clientRepo = $clientRepo; $this->invoiceRepo = $invoiceRepo; $this->datatableService = $datatableService; } protected function getRepo() { return $this->invoiceRepo; } public function save($data, $checkSubPermissions = false) { if (isset($data['client'])) { $can_save_client = !$checkSubPermissions; if(!$can_save_client){ if(empty($data['client']['public_id']) || $data['client']['public_id']=='-1'){ $can_save_client = Client::canCreate(); } else{ $can_save_client = Client::wherePublicId($data['client']['public_id'])->first()->canEdit(); } } if($can_save_client){ $client = $this->clientRepo->save($data['client']); $data['client_id'] = $client->id; } } $invoice = $this->invoiceRepo->save($data, $checkSubPermissions); $client = $invoice->client; $client->load('contacts'); $sendInvoiceIds = []; foreach ($client->contacts as $contact) { if ($contact->send_invoice || count($client->contacts) == 1) { $sendInvoiceIds[] = $contact->id; } } foreach ($client->contacts as $contact) { $invitation = Invitation::scope()->whereContactId($contact->id)->whereInvoiceId($invoice->id)->first(); if (in_array($contact->id, $sendInvoiceIds) && !$invitation) { $invitation = Invitation::createNew(); $invitation->invoice_id = $invoice->id; $invitation->contact_id = $contact->id; $invitation->invitation_key = str_random(RANDOM_KEY_LENGTH); $invitation->save(); } elseif (!in_array($contact->id, $sendInvoiceIds) && $invitation) { $invitation->delete(); } } return $invoice; } public function convertQuote($quote, $invitation = null) { $invoice = $this->invoiceRepo->cloneInvoice($quote, $quote->id); if (!$invitation) { return $invoice; } foreach ($invoice->invitations as $invoiceInvitation) { if ($invitation->contact_id == $invoiceInvitation->contact_id) { return $invoiceInvitation->invitation_key; } } } public function approveQuote($quote, $invitation = null) { $account = $quote->account; if (!$quote->is_quote || $quote->quote_invoice_id) { return null; } if ($account->auto_convert_quote || ! $account->isPro()) { $invoice = $this->convertQuote($quote, $invitation); event(new QuoteInvitationWasApproved($quote, $invoice, $invitation)); return $invoice; } else { $quote->markApproved(); event(new QuoteInvitationWasApproved($quote, null, $invitation)); foreach ($quote->invitations as $invoiceInvitation) { if ($invitation->contact_id == $invoiceInvitation->contact_id) { return $invoiceInvitation->invitation_key; } } } } public function getDatatable($accountId, $clientPublicId = null, $entityType, $search) { $query = $this->invoiceRepo->getInvoices($accountId, $clientPublicId, $entityType, $search) ->where('invoices.is_quote', '=', $entityType == ENTITY_QUOTE ? true : false); if(!Utils::hasPermission('view_all')){ $query->where('invoices.user_id', '=', Auth::user()->id); } return $this->createDatatable($entityType, $query, !$clientPublicId); } protected function getDatatableColumns($entityType, $hideClient) { return [ [ 'invoice_number', function ($model) use ($entityType) { if(!Invoice::canEditItem($model)){ return $model->invoice_number; } return link_to("{$entityType}s/{$model->public_id}/edit", $model->invoice_number, ['class' => Utils::getEntityRowClass($model)])->toHtml(); } ], [ 'client_name', function ($model) { if(!Client::canViewItemByOwner($model->client_user_id)){ return Utils::getClientDisplayName($model); } return link_to("clients/{$model->client_public_id}", Utils::getClientDisplayName($model))->toHtml(); }, ! $hideClient ], [ 'invoice_date', function ($model) { return Utils::fromSqlDate($model->invoice_date); } ], [ 'amount', function ($model) { return Utils::formatMoney($model->amount, $model->currency_id, $model->country_id); } ], [ 'balance', function ($model) { return $model->partial > 0 ? trans('texts.partial_remaining', [ 'partial' => Utils::formatMoney($model->partial, $model->currency_id, $model->country_id), 'balance' => Utils::formatMoney($model->balance, $model->currency_id, $model->country_id)] ) : Utils::formatMoney($model->balance, $model->currency_id, $model->country_id); }, $entityType == ENTITY_INVOICE ], [ 'due_date', function ($model) { return Utils::fromSqlDate($model->due_date); }, ], [ 'invoice_status_name', function ($model) use ($entityType) { return $model->quote_invoice_id ? link_to("invoices/{$model->quote_invoice_id}/edit", trans('texts.converted'))->toHtml() : self::getStatusLabel($entityType, $model); } ] ]; } protected function getDatatableActions($entityType) { return [ [ trans("texts.edit_{$entityType}"), function ($model) use ($entityType) { return URL::to("{$entityType}s/{$model->public_id}/edit"); }, function ($model) { return Invoice::canEditItem($model); } ], [ trans("texts.clone_{$entityType}"), function ($model) use ($entityType) { return URL::to("{$entityType}s/{$model->public_id}/clone"); }, function ($model) { return Invoice::canCreate(); } ], [ trans("texts.view_history"), function ($model) use ($entityType) { return URL::to("{$entityType}s/{$entityType}_history/{$model->public_id}"); } ], [ '--divider--', function(){return false;}, function ($model) { return Invoice::canEditItem($model) || Payment::canCreate(); } ], [ trans("texts.mark_sent"), function ($model) { return "javascript:markEntity({$model->public_id})"; }, function ($model) { return $model->invoice_status_id < INVOICE_STATUS_SENT && Invoice::canEditItem($model); } ], [ trans('texts.enter_payment'), function ($model) { return URL::to("payments/create/{$model->client_public_id}/{$model->public_id}"); }, function ($model) use ($entityType) { return $entityType == ENTITY_INVOICE && $model->balance > 0 && Payment::canCreate(); } ], [ trans("texts.view_quote"), function ($model) { return URL::to("quotes/{$model->quote_id}/edit"); }, function ($model) use ($entityType) { return $entityType == ENTITY_INVOICE && $model->quote_id && Invoice::canEditItem($model); } ], [ trans("texts.view_invoice"), function ($model) { return URL::to("invoices/{$model->quote_invoice_id}/edit"); }, function ($model) use ($entityType) { return $entityType == ENTITY_QUOTE && $model->quote_invoice_id && Invoice::canEditItem($model); } ], [ trans("texts.convert_to_invoice"), function ($model) { return "javascript:convertEntity({$model->public_id})"; }, function ($model) use ($entityType) { return $entityType == ENTITY_QUOTE && ! $model->quote_invoice_id && Invoice::canEditItem($model); } ] ]; } private function getStatusLabel($entityType, $model) { // check if invoice is overdue if (Utils::parseFloat($model->balance) && $model->due_date && $model->due_date != '0000-00-00') { if (\DateTime::createFromFormat('Y-m-d', $model->due_date) < new \DateTime("now")) { $label = $entityType == ENTITY_INVOICE ? trans('texts.overdue') : trans('texts.expired'); return "

" . $label . "

"; } } $label = trans("texts.status_" . strtolower($model->invoice_status_name)); $class = 'default'; switch ($model->invoice_status_id) { case INVOICE_STATUS_SENT: $class = 'info'; break; case INVOICE_STATUS_VIEWED: $class = 'warning'; break; case INVOICE_STATUS_APPROVED: $class = 'success'; break; case INVOICE_STATUS_PARTIAL: $class = 'primary'; break; case INVOICE_STATUS_PAID: $class = 'success'; break; } return "

$label

"; } }