public function actionCredit() { $model = new Credit(); $credit_date = ''; $post_date = array('term' => '', 'rate' => '', 'rate' => '', 'tstartmonth' => '', 'startyear' => ''); if (Yii::$app->request->isPost) { $credit_date = $model->credit_calculate(Yii::$app->request->post('Credit')['term'], Yii::$app->request->post('Credit')['rate'], Yii::$app->request->post('Credit')['amount'], Yii::$app->request->post('startmonth'), Yii::$app->request->post('startyear')); $post_date = ['term' => Yii::$app->request->post('Credit')['term'], 'rate' => Yii::$app->request->post('Credit')['rate'], 'amount' => Yii::$app->request->post('Credit')['amount'], 'startmonth' => Yii::$app->request->post('startmonth'), 'startyear' => Yii::$app->request->post('startyear')]; } return $this->render('credit', ['model' => $model, 'credit_date' => $credit_date, 'post_date' => $post_date]); }
private function getData($request) { $account = Auth::user()->account; $data = ['account' => $account, 'title' => 'Invoice Ninja v' . NINJA_VERSION . ' - ' . $account->formatDateTime($account->getDateTime()), 'multiUser' => $account->users->count() > 1]; if ($request->input(ENTITY_CLIENT)) { $data['clients'] = Client::scope()->with('user', 'contacts', 'country')->withTrashed()->where('is_deleted', '=', false)->get(); $data['contacts'] = Contact::scope()->with('user', 'client.contacts')->withTrashed()->get(); $data['credits'] = Credit::scope()->with('user', 'client.contacts')->get(); } if ($request->input(ENTITY_TASK)) { $data['tasks'] = Task::scope()->with('user', 'client.contacts')->withTrashed()->where('is_deleted', '=', false)->get(); } if ($request->input(ENTITY_INVOICE)) { $data['invoices'] = Invoice::scope()->with('user', 'client.contacts', 'invoice_status')->withTrashed()->where('is_deleted', '=', false)->where('is_quote', '=', false)->where('is_recurring', '=', false)->get(); $data['quotes'] = Invoice::scope()->with('user', 'client.contacts', 'invoice_status')->withTrashed()->where('is_deleted', '=', false)->where('is_quote', '=', true)->where('is_recurring', '=', false)->get(); } if ($request->input(ENTITY_PAYMENT)) { $data['payments'] = Payment::scope()->withTrashed()->where('is_deleted', '=', false)->with('user', 'client.contacts', 'payment_type', 'invoice', 'account_gateway.gateway')->get(); } if ($request->input(ENTITY_VENDOR)) { $data['clients'] = Vendor::scope()->with('user', 'vendorcontacts', 'country')->withTrashed()->where('is_deleted', '=', false)->get(); $data['vendor_contacts'] = VendorContact::scope()->with('user', 'vendor.contacts')->withTrashed()->get(); /* $data['expenses'] = Credit::scope() ->with('user', 'client.contacts') ->get(); */ } return $data; }
public function save($publicId = null, $input) { if ($publicId) { $payment = Payment::scope($publicId)->firstOrFail(); } else { $payment = Payment::createNew(); } $paymentTypeId = $input['payment_type_id'] ? $input['payment_type_id'] : null; $payment->payment_type_id = $paymentTypeId; $payment->payment_date = Utils::toSqlDate($input['payment_date']); $payment->transaction_reference = trim($input['transaction_reference']); if (!$publicId) { $clientId = Client::getPrivateId($input['client']); $amount = Utils::parseFloat($input['amount']); if ($paymentTypeId == PAYMENT_TYPE_CREDIT) { $credits = Credit::scope()->where('client_id', '=', $clientId)->where('balance', '>', 0)->orderBy('created_at')->get(); $applied = 0; foreach ($credits as $credit) { $applied += $credit->apply($amount); if ($applied >= $amount) { break; } } } $payment->client_id = $clientId; $payment->invoice_id = isset($input['invoice']) && $input['invoice'] != "-1" ? Invoice::getPrivateId($input['invoice']) : null; $payment->amount = $amount; } $payment->save(); return $payment; }
public function save($input, $payment = null) { $publicId = isset($input['public_id']) ? $input['public_id'] : false; if ($payment) { // do nothing } elseif ($publicId) { $payment = Payment::scope($publicId)->firstOrFail(); if (Utils::isNinjaDev()) { \Log::warning('Entity not set in payment repo save'); } } else { $payment = Payment::createNew(); } if ($payment->is_deleted) { return $payment; } $paymentTypeId = false; if (isset($input['payment_type_id'])) { $paymentTypeId = $input['payment_type_id'] ? $input['payment_type_id'] : null; $payment->payment_type_id = $paymentTypeId; } if (isset($input['payment_date_sql'])) { $payment->payment_date = $input['payment_date_sql']; } elseif (isset($input['payment_date'])) { $payment->payment_date = Utils::toSqlDate($input['payment_date']); } else { $payment->payment_date = date('Y-m-d'); } if (isset($input['transaction_reference'])) { $payment->transaction_reference = trim($input['transaction_reference']); } if (!$publicId) { $clientId = $input['client_id']; $amount = Utils::parseFloat($input['amount']); if ($paymentTypeId == PAYMENT_TYPE_CREDIT) { $credits = Credit::scope()->where('client_id', '=', $clientId)->where('balance', '>', 0)->orderBy('created_at')->get(); $remaining = $amount; foreach ($credits as $credit) { $remaining -= $credit->apply($remaining); if (!$remaining) { break; } } } $payment->invoice_id = $input['invoice_id']; $payment->client_id = $clientId; $payment->amount = $amount; } $payment->save(); return $payment; }
public function deletedPayment(PaymentWasDeleted $event) { $payment = $event->payment; // if the payment was from a credit we need to refund the credit if ($payment->payment_type_id != PAYMENT_TYPE_CREDIT) { return; } $credit = Credit::createNew(); $credit->client_id = $payment->client_id; $credit->credit_date = Carbon::now()->toDateTimeString(); $credit->balance = $credit->amount = $payment->amount; $credit->private_notes = $payment->transaction_reference; $credit->save(); }
public function save($input) { $publicId = isset($data['public_id']) ? $data['public_id'] : false; if ($publicId) { $credit = Credit::scope($publicId)->firstOrFail(); } else { $credit = Credit::createNew(); } $credit->client_id = Client::getPrivateId($input['client']); $credit->credit_date = Utils::toSqlDate($input['credit_date']); $credit->amount = Utils::parseFloat($input['amount']); $credit->balance = Utils::parseFloat($input['amount']); $credit->private_notes = trim($input['private_notes']); $credit->save(); return $credit; }
public function bulk($ids, $action) { if (!$ids) { return 0; } $credits = Credit::withTrashed()->scope($ids)->get(); foreach ($credits as $credit) { if ($action == 'restore') { $credit->restore(); } else { if ($action == 'delete') { $credit->is_deleted = true; $credit->save(); } $credit->delete(); } } return count($credits); }
public function save($input, $credit = null) { $publicId = isset($data['public_id']) ? $data['public_id'] : false; if ($credit) { // do nothing } elseif ($publicId) { $credit = Credit::scope($publicId)->firstOrFail(); \Log::warning('Entity not set in credit repo save'); } else { $credit = Credit::createNew(); } $credit->client_id = Client::getPrivateId($input['client']); $credit->credit_date = Utils::toSqlDate($input['credit_date']); $credit->amount = Utils::parseFloat($input['amount']); $credit->balance = Utils::parseFloat($input['amount']); $credit->private_notes = trim($input['private_notes']); $credit->save(); return $credit; }
private function export() { $output = fopen('php://output', 'w') or Utils::fatalError(); header('Content-Type:application/csv'); header('Content-Disposition:attachment;filename=export.csv'); $clients = Client::scope()->get(); Utils::exportData($output, $clients->toArray()); $contacts = Contact::scope()->get(); Utils::exportData($output, $contacts->toArray()); $invoices = Invoice::scope()->get(); Utils::exportData($output, $invoices->toArray()); $invoiceItems = InvoiceItem::scope()->get(); Utils::exportData($output, $invoiceItems->toArray()); $payments = Payment::scope()->get(); Utils::exportData($output, $payments->toArray()); $credits = Credit::scope()->get(); Utils::exportData($output, $credits->toArray()); fclose($output); exit; }
} public function client() { return $this->belongsTo('App\\Models\\Client')->withTrashed(); } public function getName() { return ''; } public function getEntityType() { return ENTITY_CREDIT; } public function apply($amount) { if ($amount > $this->balance) { $applied = $this->balance; $this->balance = 0; } else { $applied = $amount; $this->balance = $this->balance - $amount; } $this->save(); return $applied; } } Credit::creating(function ($credit) { }); Credit::created(function ($credit) { event(new CreditWasCreated($credit)); });
/** * @param $request * * @return array */ private function getData($request) { $account = Auth::user()->account; $data = ['account' => $account, 'title' => 'Invoice Ninja v' . NINJA_VERSION . ' - ' . $account->formatDateTime($account->getDateTime()), 'multiUser' => $account->users->count() > 1]; if ($request->input('include') === 'all' || $request->input('clients')) { $data['clients'] = Client::scope()->with('user', 'contacts', 'country')->withArchived()->get(); } if ($request->input('include') === 'all' || $request->input('contacts')) { $data['contacts'] = Contact::scope()->with('user', 'client.contacts')->withTrashed()->get(); } if ($request->input('include') === 'all' || $request->input('credits')) { $data['credits'] = Credit::scope()->with('user', 'client.contacts')->get(); } if ($request->input('include') === 'all' || $request->input('tasks')) { $data['tasks'] = Task::scope()->with('user', 'client.contacts')->withArchived()->get(); } if ($request->input('include') === 'all' || $request->input('invoices')) { $data['invoices'] = Invoice::scope()->invoiceType(INVOICE_TYPE_STANDARD)->with('user', 'client.contacts', 'invoice_status')->withArchived()->where('is_recurring', '=', false)->get(); } if ($request->input('include') === 'all' || $request->input('quotes')) { $data['quotes'] = Invoice::scope()->invoiceType(INVOICE_TYPE_QUOTE)->with('user', 'client.contacts', 'invoice_status')->withArchived()->where('is_recurring', '=', false)->get(); } if ($request->input('include') === 'all' || $request->input('recurring')) { $data['recurringInvoices'] = Invoice::scope()->invoiceType(INVOICE_TYPE_STANDARD)->with('user', 'client.contacts', 'invoice_status', 'frequency')->withArchived()->where('is_recurring', '=', true)->get(); } if ($request->input('include') === 'all' || $request->input('payments')) { $data['payments'] = Payment::scope()->withArchived()->with('user', 'client.contacts', 'payment_type', 'invoice', 'account_gateway.gateway')->get(); } if ($request->input('include') === 'all' || $request->input('vendors')) { $data['vendors'] = Vendor::scope()->with('user', 'vendor_contacts', 'country')->withArchived()->get(); } if ($request->input('include') === 'all' || $request->input('vendor_contacts')) { $data['vendor_contacts'] = VendorContact::scope()->with('user', 'vendor.vendor_contacts')->withTrashed()->get(); } return $data; }
/** * Display the specified resource. * * @param int $id * @return Response */ public function show($publicId) { $client = Client::withTrashed()->scope($publicId)->with('contacts', 'size', 'industry')->firstOrFail(); if (!$this->checkViewPermission($client, $response)) { return $response; } Utils::trackViewed($client->getDisplayName(), ENTITY_CLIENT); $actionLinks = []; if (Task::canCreate()) { $actionLinks[] = ['label' => trans('texts.new_task'), 'url' => '/tasks/create/' . $client->public_id]; } if (Utils::isPro() && Invoice::canCreate()) { $actionLinks[] = ['label' => trans('texts.new_quote'), 'url' => '/quotes/create/' . $client->public_id]; } if (!empty($actionLinks)) { $actionLinks[] = \DropdownButton::DIVIDER; } if (Payment::canCreate()) { $actionLinks[] = ['label' => trans('texts.enter_payment'), 'url' => '/payments/create/' . $client->public_id]; } if (Credit::canCreate()) { $actionLinks[] = ['label' => trans('texts.enter_credit'), 'url' => '/credits/create/' . $client->public_id]; } if (Expense::canCreate()) { $actionLinks[] = ['label' => trans('texts.enter_expense'), 'url' => '/expenses/create/0/' . $client->public_id]; } $data = array('actionLinks' => $actionLinks, 'showBreadcrumbs' => false, 'client' => $client, 'credit' => $client->getTotalCredit(), 'title' => trans('texts.view_client'), 'hasRecurringInvoices' => Invoice::scope()->where('is_recurring', '=', true)->whereClientId($client->id)->count() > 0, 'hasQuotes' => Invoice::scope()->where('is_quote', '=', true)->whereClientId($client->id)->count() > 0, 'hasTasks' => Task::scope()->whereClientId($client->id)->count() > 0, 'gatewayLink' => $client->getGatewayLink()); return View::make('clients.show', $data); }
return ''; } public function getEntityType() { return ENTITY_CREDIT; } public function apply($amount) { if ($amount > $this->balance) { $applied = $this->balance; $this->balance = 0; } else { $applied = $amount; $this->balance = $this->balance - $amount; } $this->save(); return $applied; } } Credit::created(function ($credit) { Activity::createCredit($credit); }); Credit::updating(function ($credit) { Activity::updateCredit($credit); }); Credit::deleting(function ($credit) { Activity::archiveCredit($credit); }); Credit::restoring(function ($credit) { Activity::restoreCredit($credit); });
/** * Record Credits * * @return bool * @throws \Exception */ private function recordCredits() { $user = User::find($this->requestor_id); $credit = $user->credit; if ($credit) { $credit->amount += $this->amount; } else { $credit = new Credit(); $credit->user_id = $user->id; $credit->amount = $this->amount; } if ($credit->save()) { $creditLog = new CreditLog(); $creditLog->user_id = $user->id; $creditLog->credit_id = $credit->id; $creditLog->amount = $this->amount; $creditLog->type = CreditLog::TYPE_EARNED; if (!$creditLog->save()) { throw new \Exception('Error saving credit log!'); } } else { throw new \Exception('Error saving credit!'); } return true; }
/** * Bootstrap any application services. * * @return void */ public function boot() { Form::macro('image_data', function ($imagePath) { return 'data:image/jpeg;base64,' . base64_encode(file_get_contents($imagePath)); }); Form::macro('nav_link', function ($url, $text, $url2 = '', $extra = '') { $capitalize = config('former.capitalize_translations'); $class = Request::is($url) || Request::is($url . '/*') || Request::is($url2 . '/*') ? ' class="active"' : ''; if ($capitalize) { $title = ucwords(trans("texts.{$text}")) . Utils::getProLabel($text); } else { $title = trans("texts.{$text}") . Utils::getProLabel($text); } return '<li' . $class . '><a href="' . URL::to($url) . '" ' . $extra . '>' . $title . '</a></li>'; }); Form::macro('tab_link', function ($url, $text, $active = false) { $class = $active ? ' class="active"' : ''; return '<li' . $class . '><a href="' . URL::to($url) . '" data-toggle="tab">' . $text . '</a></li>'; }); Form::macro('menu_link', function ($type) { $types = $type . 's'; $Type = ucfirst($type); $Types = ucfirst($types); $class = (Request::is($types) || Request::is('*' . $type . '*')) && !Request::is('*settings*') ? ' active' : ''; $str = '<li class="dropdown ' . $class . '"> <a href="' . URL::to($types) . '" class="dropdown-toggle">' . trans("texts.{$types}") . '</a>'; $items = []; if (Auth::user()->hasPermission('create_all')) { $items[] = '<li><a href="' . URL::to($types . '/create') . '">' . trans("texts.new_{$type}") . '</a></li>'; } if ($type == ENTITY_INVOICE) { if (!empty($items)) { $items[] = '<li class="divider"></li>'; } $items[] = '<li><a href="' . URL::to('recurring_invoices') . '">' . trans("texts.recurring_invoices") . '</a></li>'; if (Invoice::canCreate()) { $items[] = '<li><a href="' . URL::to('recurring_invoices/create') . '">' . trans("texts.new_recurring_invoice") . '</a></li>'; } if (Auth::user()->isPro()) { $items[] = '<li class="divider"></li>'; $items[] = '<li><a href="' . URL::to('quotes') . '">' . trans("texts.quotes") . '</a></li>'; if (Invoice::canCreate()) { $items[] = '<li><a href="' . URL::to('quotes/create') . '">' . trans("texts.new_quote") . '</a></li>'; } } } else { if ($type == ENTITY_CLIENT) { if (!empty($items)) { $items[] = '<li class="divider"></li>'; } $items[] = '<li><a href="' . URL::to('credits') . '">' . trans("texts.credits") . '</a></li>'; if (Credit::canCreate()) { $items[] = '<li><a href="' . URL::to('credits/create') . '">' . trans("texts.new_credit") . '</a></li>'; } } else { if ($type == ENTITY_EXPENSE) { if (!empty($items)) { $items[] = '<li class="divider"></li>'; } $items[] = '<li><a href="' . URL::to('vendors') . '">' . trans("texts.vendors") . '</a></li>'; if (Vendor::canCreate()) { $items[] = '<li><a href="' . URL::to('vendors/create') . '">' . trans("texts.new_vendor") . '</a></li>'; } } } } if (!empty($items)) { $str .= '<ul class="dropdown-menu" id="menu1">' . implode($items) . '</ul>'; } $str .= '</li>'; return $str; }); Form::macro('flatButton', function ($label, $color) { return '<input type="button" value="' . trans("texts.{$label}") . '" style="background-color:' . $color . ';border:0 none;border-radius:5px;padding:12px 40px;margin:0 6px;cursor:hand;display:inline-block;font-size:14px;color:#fff;text-transform:none;font-weight:bold;"/>'; }); Form::macro('emailViewButton', function ($link = '#', $entityType = ENTITY_INVOICE) { return view('partials.email_button')->with(['link' => $link, 'field' => "view_{$entityType}", 'color' => '#0b4d78'])->render(); }); Form::macro('emailPaymentButton', function ($link = '#') { return view('partials.email_button')->with(['link' => $link, 'field' => 'pay_now', 'color' => '#36c157'])->render(); }); Form::macro('breadcrumbs', function ($status = false) { $str = '<ol class="breadcrumb">'; // Get the breadcrumbs by exploding the current path. $basePath = Utils::basePath(); $parts = explode('?', isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : ''); $path = $parts[0]; if ($basePath != '/') { $path = str_replace($basePath, '', $path); } $crumbs = explode('/', $path); foreach ($crumbs as $key => $val) { if (is_numeric($val)) { unset($crumbs[$key]); } } $crumbs = array_values($crumbs); for ($i = 0; $i < count($crumbs); $i++) { $crumb = trim($crumbs[$i]); if (!$crumb) { continue; } if ($crumb == 'company') { return ''; } $name = trans("texts.{$crumb}"); if ($i == count($crumbs) - 1) { $str .= "<li class='active'>{$name}</li>"; } else { $str .= '<li>' . link_to($crumb, $name) . '</li>'; } } if ($status) { $str .= ' ' . $status; } return $str . '</ol>'; }); Validator::extend('positive', function ($attribute, $value, $parameters) { return Utils::parseFloat($value) >= 0; }); Validator::extend('has_credit', function ($attribute, $value, $parameters) { $publicClientId = $parameters[0]; $amount = $parameters[1]; $client = \App\Models\Client::scope($publicClientId)->firstOrFail(); $credit = $client->getTotalCredit(); return $credit >= $amount; }); // check that the time log elements don't overlap Validator::extend('time_log', function ($attribute, $value, $parameters) { $lastTime = 0; $value = json_decode($value); array_multisort($value); foreach ($value as $timeLog) { list($startTime, $endTime) = $timeLog; if (!$endTime) { continue; } if ($startTime < $lastTime || $startTime > $endTime) { return false; } if ($endTime < min($startTime, $lastTime)) { return false; } $lastTime = max($lastTime, $endTime); } return true; }); Validator::extend('less_than', function ($attribute, $value, $parameters) { return floatval($value) <= floatval($parameters[0]); }); Validator::replacer('less_than', function ($message, $attribute, $rule, $parameters) { return str_replace(':value', $parameters[0], $message); }); Validator::extend('has_counter', function ($attribute, $value, $parameters) { return !$value || strstr($value, '{$counter}'); }); Validator::extend('valid_contacts', function ($attribute, $value, $parameters) { foreach ($value as $contact) { $validator = Validator::make($contact, ['email' => 'email|required_without:first_name', 'first_name' => 'required_without:email']); if ($validator->fails()) { return false; } } return true; }); Validator::extend('valid_invoice_items', function ($attribute, $value, $parameters) { $total = 0; foreach ($value as $item) { $qty = isset($item['qty']) ? $item['qty'] : 1; $cost = isset($item['cost']) ? $item['cost'] : 1; $total += $qty * $cost; } return $total <= MAX_INVOICE_AMOUNT; }); }
public static function updatePayment($payment) { if ($payment->is_deleted && !$payment->getOriginal('is_deleted')) { $client = $payment->client; $client->balance = $client->balance + $payment->amount; $client->paid_to_date = $client->paid_to_date - $payment->amount; $client->save(); $invoice = $payment->invoice; $invoice->balance = $invoice->balance + $payment->amount; if ($invoice->isPaid() && $invoice->balance > 0) { $invoice->invoice_status_id = $invoice->balance == $invoice->amount ? INVOICE_STATUS_DRAFT : INVOICE_STATUS_PARTIAL; } $invoice->save(); // deleting a payment from credit creates a new credit if ($payment->payment_type_id == PAYMENT_TYPE_CREDIT) { $credit = Credit::createNew(); $credit->client_id = $client->id; $credit->credit_date = Carbon::now()->toDateTimeString(); $credit->balance = $credit->amount = $payment->amount; $credit->private_notes = $payment->transaction_reference; $credit->save(); } $activity = Activity::getBlank(); $activity->payment_id = $payment->id; $activity->client_id = $invoice->client_id; $activity->invoice_id = $invoice->id; $activity->activity_type_id = ACTIVITY_TYPE_DELETE_PAYMENT; $activity->message = Utils::encodeActivity(Auth::user(), 'deleted ' . $payment->getName()); $activity->balance = $client->balance; $activity->adjustment = $payment->amount; $activity->save(); } else { /* $diff = floatval($invoice->amount) - floatval($invoice->getOriginal('amount')); if ($diff == 0) { return; } $client = $invoice->client; $client->balance = $client->balance + $diff; $client->save(); $activity = Activity::getBlank($invoice); $activity->client_id = $invoice->client_id; $activity->invoice_id = $invoice->id; $activity->activity_type_id = ACTIVITY_TYPE_UPDATE_INVOICE; $activity->message = Utils::encodeActivity(Auth::user(), 'updated', $invoice); $activity->balance = $client->balance; $activity->adjustment = $diff; $activity->json_backup = $backupInvoice->hidePrivateFields()->toJSON(); $activity->save(); */ } }
public function createNinjaCredit($client, $amount) { $account = $this->getNinjaAccount(); $lastCredit = Credit::withTrashed()->whereAccountId($account->id)->orderBy('public_id', 'DESC')->first(); $publicId = $lastCredit ? $lastCredit->public_id + 1 : 1; $credit = new Credit(); $credit->public_id = $publicId; $credit->account_id = $account->id; $credit->user_id = $account->users()->first()->id; $credit->client_id = $client->id; $credit->amount = $amount; $credit->save(); return $credit; }
protected function getDatatableActions($entityType) { return [[trans('texts.edit_client'), function ($model) { return URL::to("clients/{$model->public_id}/edit"); }, function ($model) { return Client::canEditItem($model); }], ['--divider--', function () { return false; }, function ($model) { return Client::canEditItem($model) && (Task::canCreate() || Invoice::canCreate()); }], [trans('texts.new_task'), function ($model) { return URL::to("tasks/create/{$model->public_id}"); }, function ($model) { return Task::canCreate(); }], [trans('texts.new_invoice'), function ($model) { return URL::to("invoices/create/{$model->public_id}"); }, function ($model) { return Invoice::canCreate(); }], [trans('texts.new_quote'), function ($model) { return URL::to("quotes/create/{$model->public_id}"); }, function ($model) { return Auth::user()->isPro() && Invoice::canCreate(); }], ['--divider--', function () { return false; }, function ($model) { return (Task::canCreate() || Invoice::canCreate()) && (Payment::canCreate() || Credit::canCreate() || Expense::canCreate()); }], [trans('texts.enter_payment'), function ($model) { return URL::to("payments/create/{$model->public_id}"); }, function ($model) { return Payment::canCreate(); }], [trans('texts.enter_credit'), function ($model) { return URL::to("credits/create/{$model->public_id}"); }, function ($model) { return Credit::canCreate(); }], [trans('texts.enter_expense'), function ($model) { return URL::to("expenses/create/0/{$model->public_id}"); }, function ($model) { return Expense::canCreate(); }]]; }