コード例 #1
0
 public function edit($publicId)
 {
     $payment = Payment::scope($publicId)->firstOrFail();
     $payment->payment_date = Utils::fromSqlDate($payment->payment_date);
     $data = array('client' => null, 'invoice' => null, 'invoices' => Invoice::scope()->where('is_recurring', '=', false)->where('is_quote', '=', false)->with('client', 'invoice_status')->orderBy('invoice_number')->get(), 'payment' => $payment, 'method' => 'PUT', 'url' => 'payments/' . $publicId, 'title' => trans('texts.edit_payment'), 'paymentTypes' => Cache::get('paymentTypes'), 'clients' => Client::scope()->with('contacts')->orderBy('name')->get());
     return View::make('payments.edit', $data);
 }
コード例 #2
0
 public function store()
 {
     $data = Input::all();
     $error = false;
     if (isset($data['invoice_id'])) {
         $invoice = Invoice::scope($data['invoice_id'])->with('client')->first();
         if ($invoice) {
             $data['invoice'] = $invoice->public_id;
             $data['client'] = $invoice->client->public_id;
         } else {
             $error = trans('validation.not_in', ['attribute' => 'invoice_id']);
         }
     } else {
         $error = trans('validation.not_in', ['attribute' => 'invoice_id']);
     }
     if (!isset($data['transaction_reference'])) {
         $data['transaction_reference'] = '';
     }
     if (!$error) {
         $payment = $this->paymentRepo->save($data);
         $payment = Payment::scope($payment->public_id)->with('client', 'contact', 'user', 'invoice')->first();
         $payment = Utils::remapPublicIds([$payment]);
     }
     $response = json_encode($error ?: $payment, JSON_PRETTY_PRINT);
     $headers = Utils::getApiHeaders();
     return Response::make($response, 200, $headers);
 }
コード例 #3
0
 /**
  * @SWG\Post(
  *   path="/payments",
  *   summary="Create a payment",
  *   tags={"payment"},
  *   @SWG\Parameter(
  *     in="body",
  *     name="body",
  *     @SWG\Schema(ref="#/definitions/Payment")
  *   ),
  *   @SWG\Response(
  *     response=200,
  *     description="New payment",
  *      @SWG\Schema(type="object", @SWG\Items(ref="#/definitions/Payment"))
  *   ),
  *   @SWG\Response(
  *     response="default",
  *     description="an ""unexpected"" error"
  *   )
  * )
  */
 public function store()
 {
     $data = Input::all();
     $error = false;
     if (isset($data['invoice_id'])) {
         $invoice = Invoice::scope($data['invoice_id'])->with('client')->first();
         if ($invoice) {
             $data['invoice'] = $invoice->public_id;
             $data['client'] = $invoice->client->public_id;
         } else {
             $error = trans('validation.not_in', ['attribute' => 'invoice_id']);
         }
     } else {
         $error = trans('validation.not_in', ['attribute' => 'invoice_id']);
     }
     if (!isset($data['transaction_reference'])) {
         $data['transaction_reference'] = '';
     }
     if ($error) {
         return $error;
     }
     $payment = $this->paymentRepo->save($data);
     $payment = Payment::scope($payment->public_id)->with('client', 'contact', 'user', 'invoice')->first();
     $transformer = new PaymentTransformer(Auth::user()->account, Input::get('serializer'));
     $data = $this->createItem($payment, $transformer, 'payment');
     return $this->response($data);
 }
コード例 #4
0
 public function index()
 {
     $invoices = Invoice::scope()->with('client', 'user')->where('invoices.is_quote', '=', true)->orderBy('created_at', 'desc')->get();
     $invoices = Utils::remapPublicIds($invoices);
     $response = json_encode($invoices, JSON_PRETTY_PRINT);
     $headers = Utils::getApiHeaders(count($invoices));
     return Response::make($response, 200, $headers);
 }
コード例 #5
0
 /**
  * Get the validation rules that apply to the request.
  *
  * @return array
  */
 public function rules()
 {
     $input = $this->input();
     $invoice = Invoice::scope($input['invoice'])->invoices()->firstOrFail();
     $rules = ['client' => 'required', 'invoice' => 'required', 'amount' => "required|numeric|between:0.01,{$invoice->balance}", 'payment_date' => 'required'];
     if (!empty($input['payment_type_id']) && $input['payment_type_id'] == PAYMENT_TYPE_CREDIT) {
         $rules['payment_type_id'] = 'has_credit:' . $input['client'] . ',' . $input['amount'];
     }
     return $rules;
 }
コード例 #6
0
 /**
  * Get the validation rules that apply to the request.
  *
  * @return array
  */
 public function rules()
 {
     $input = $this->input();
     $invoice = Invoice::scope($input['invoice'])->firstOrFail();
     $rules = array('client' => 'required', 'invoice' => 'required', 'amount' => "required|less_than:{$invoice->balance}|positive");
     if ($input['payment_type_id'] == PAYMENT_TYPE_CREDIT) {
         $rules['payment_type_id'] = 'has_credit:' . $input['client'] . ',' . $input['amount'];
     }
     return $rules;
 }
コード例 #7
0
 /**
  * Display the specified resource.
  *
  * @param  int      $id
  * @return Response
  */
 public function show($publicId)
 {
     $client = Client::withTrashed()->scope($publicId)->with('contacts', 'size', 'industry')->firstOrFail();
     Utils::trackViewed($client->getDisplayName(), ENTITY_CLIENT);
     $actionLinks = [['label' => trans('texts.new_task'), 'url' => '/tasks/create/' . $client->public_id]];
     if (Utils::isPro()) {
         array_push($actionLinks, ['label' => trans('texts.new_quote'), 'url' => '/quotes/create/' . $client->public_id]);
     }
     array_push($actionLinks, ['label' => trans('texts.enter_payment'), 'url' => '/payments/create/' . $client->public_id], ['label' => trans('texts.enter_credit'), 'url' => '/credits/create/' . $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);
 }
コード例 #8
0
 public function entity()
 {
     $invoice = parent::entity();
     // support loading an invoice by its invoice number
     if ($this->invoice_number && !$invoice) {
         $invoice = Invoice::scope()->whereInvoiceNumber($this->invoice_number)->withTrashed()->firstOrFail();
     }
     // eager load the invoice items
     if ($invoice && !$invoice->relationLoaded('invoice_items')) {
         $invoice->load('invoice_items');
     }
     return $invoice;
 }
コード例 #9
0
 /**
  * Get the validation rules that apply to the request.
  *
  * @return array
  */
 public function rules()
 {
     if (!$this->invoice_id || !$this->amount) {
         return ['invoice_id' => 'required', 'amount' => 'required'];
     }
     $invoice = Invoice::scope($this->invoice_id)->firstOrFail();
     $this->merge(['invoice_id' => $invoice->id, 'client_id' => $invoice->client->id]);
     $rules = array('amount' => "required|less_than:{$invoice->balance}|positive");
     if ($this->payment_type_id == PAYMENT_TYPE_CREDIT) {
         $rules['payment_type_id'] = 'has_credit:' . $invoice->client->public_id . ',' . $this->amount;
     }
     return $rules;
 }
コード例 #10
0
 /**
  * Get the validation rules that apply to the request.
  *
  * @return array
  */
 public function rules()
 {
     if (!$this->invoice_id || !$this->amount) {
         return ['invoice_id' => 'required', 'amount' => 'required'];
     }
     $invoice = Invoice::scope($this->invoice_id)->invoices()->firstOrFail();
     $this->merge(['invoice_id' => $invoice->id, 'client_id' => $invoice->client->id]);
     $rules = ['amount' => "required|numeric|between:0.01,{$invoice->balance}"];
     if ($this->payment_type_id == PAYMENT_TYPE_CREDIT) {
         $rules['payment_type_id'] = 'has_credit:' . $invoice->client->public_id . ',' . $this->amount;
     }
     return $rules;
 }
コード例 #11
0
 public function index($clientPublicId = false)
 {
     $invoices = Invoice::scope()->with('client', 'user')->where('invoices.is_quote', '=', true);
     if ($clientPublicId) {
         $invoices->whereHas('client', function ($query) use($clientPublicId) {
             $query->where('public_id', '=', $clientPublicId);
         });
     }
     $invoices = $invoices->orderBy('created_at', 'desc')->get();
     $invoices = Utils::remapPublicIds($invoices);
     $response = json_encode($invoices, JSON_PRETTY_PRINT);
     $headers = Utils::getApiHeaders(count($invoices));
     return Response::make($response, 200, $headers);
 }
コード例 #12
0
 protected function stateInvoice()
 {
     $invoiceId = $this->stateEntity(ENTITY_INVOICE);
     if (!$invoiceId) {
         throw new Exception(trans('texts.intent_not_supported'));
     }
     $invoice = Invoice::scope($invoiceId)->first();
     if (!$invoice) {
         throw new Exception(trans('texts.intent_not_supported'));
     }
     if (!Auth::user()->can('view', $invoice)) {
         throw new Exception(trans('texts.not_allowed'));
     }
     return $invoice;
 }
コード例 #13
0
 public function getErrors($input)
 {
     $rules = array('client' => 'required', 'invoice' => 'required', 'amount' => 'required');
     if ($input['payment_type_id'] == PAYMENT_TYPE_CREDIT) {
         $rules['payment_type_id'] = 'has_credit:' . $input['client'] . ',' . $input['amount'];
     }
     if (isset($input['invoice']) && $input['invoice']) {
         $invoice = Invoice::scope($input['invoice'])->firstOrFail();
         $rules['amount'] .= "|less_than:{$invoice->balance}";
     }
     $validator = \Validator::make($input, $rules);
     if ($validator->fails()) {
         return $validator;
     }
     return false;
 }
コード例 #14
0
 /**
  * @SWG\Get(
  *   path="/quotes",
  *   tags={"quote"},
  *   summary="List of quotes",
  *   @SWG\Response(
  *     response=200,
  *     description="A list with quotes",
  *      @SWG\Schema(type="array", @SWG\Items(ref="#/definitions/Invoice"))
  *   ),
  *   @SWG\Response(
  *     response="default",
  *     description="an ""unexpected"" error"
  *   )
  * )
  */
 public function index()
 {
     $paginator = Invoice::scope();
     $invoices = Invoice::scope()->with('client', 'invitations', 'user', 'invoice_items')->where('invoices.is_quote', '=', true);
     if ($clientPublicId = Input::get('client_id')) {
         $filter = function ($query) use($clientPublicId) {
             $query->where('public_id', '=', $clientPublicId);
         };
         $invoices->whereHas('client', $filter);
         $paginator->whereHas('client', $filter);
     }
     $invoices = $invoices->orderBy('created_at', 'desc')->paginate();
     $transformer = new QuoteTransformer(\Auth::user()->account, Input::get('serializer'));
     $paginator = $paginator->paginate();
     $data = $this->createCollection($invoices, $transformer, 'quotes', $paginator);
     return $this->response($data);
 }
コード例 #15
0
 public function index()
 {
     // total_income, billed_clients, invoice_sent and active_clients
     $select = DB::raw('COUNT(DISTINCT CASE WHEN invoices.id IS NOT NULL THEN clients.id ELSE null END) billed_clients,
                     SUM(CASE WHEN invoices.invoice_status_id >= ' . INVOICE_STATUS_SENT . ' THEN 1 ELSE 0 END) invoices_sent,
                     COUNT(DISTINCT clients.id) active_clients');
     $metrics = DB::table('accounts')->select($select)->leftJoin('clients', 'accounts.id', '=', 'clients.account_id')->leftJoin('invoices', 'clients.id', '=', 'invoices.client_id')->where('accounts.id', '=', Auth::user()->account_id)->where('clients.is_deleted', '=', false)->where('invoices.is_deleted', '=', false)->where('invoices.is_recurring', '=', false)->where('invoices.is_quote', '=', false)->groupBy('accounts.id')->first();
     $select = DB::raw('SUM(clients.paid_to_date) as value, clients.currency_id as currency_id');
     $paidToDate = DB::table('accounts')->select($select)->leftJoin('clients', 'accounts.id', '=', 'clients.account_id')->where('accounts.id', '=', Auth::user()->account_id)->where('clients.is_deleted', '=', false)->groupBy('accounts.id')->groupBy(DB::raw('CASE WHEN clients.currency_id IS NULL THEN CASE WHEN accounts.currency_id IS NULL THEN 1 ELSE accounts.currency_id END ELSE clients.currency_id END'))->get();
     $select = DB::raw('AVG(invoices.amount) as invoice_avg, clients.currency_id as currency_id');
     $averageInvoice = DB::table('accounts')->select($select)->leftJoin('clients', 'accounts.id', '=', 'clients.account_id')->leftJoin('invoices', 'clients.id', '=', 'invoices.client_id')->where('accounts.id', '=', Auth::user()->account_id)->where('clients.is_deleted', '=', false)->where('invoices.is_deleted', '=', false)->groupBy('accounts.id')->groupBy(DB::raw('CASE WHEN clients.currency_id IS NULL THEN CASE WHEN accounts.currency_id IS NULL THEN 1 ELSE accounts.currency_id END ELSE clients.currency_id END'))->get();
     $activities = Activity::where('activities.account_id', '=', Auth::user()->account_id)->where('activity_type_id', '>', 0)->orderBy('created_at', 'desc')->take(14)->get();
     $pastDue = Invoice::scope()->where('due_date', '<', date('Y-m-d'))->where('balance', '>', 0)->where('is_recurring', '=', false)->where('is_quote', '=', false)->where('is_deleted', '=', false)->orderBy('due_date', 'asc')->take(6)->get();
     $upcoming = Invoice::scope()->where('due_date', '>=', date('Y-m-d'))->where('balance', '>', 0)->where('is_recurring', '=', false)->where('is_quote', '=', false)->where('is_deleted', '=', false)->orderBy('due_date', 'asc')->take(6)->get();
     $data = ['paidToDate' => $paidToDate, 'averageInvoice' => $averageInvoice, 'invoicesSent' => $metrics ? $metrics->invoices_sent : 0, 'activeClients' => $metrics ? $metrics->active_clients : 0, 'activities' => $activities, 'pastDue' => $pastDue, 'upcoming' => $upcoming];
     return View::make('dashboard', $data);
 }
コード例 #16
0
 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')->withArchived()->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')->withArchived()->get();
     }
     if ($request->input(ENTITY_INVOICE)) {
         $data['invoices'] = Invoice::scope()->with('user', 'client.contacts', 'invoice_status')->withArchived()->where('is_quote', '=', false)->where('is_recurring', '=', false)->get();
         $data['quotes'] = Invoice::scope()->with('user', 'client.contacts', 'invoice_status')->withArchived()->where('is_quote', '=', true)->where('is_recurring', '=', false)->get();
         $data['recurringInvoices'] = Invoice::scope()->with('user', 'client.contacts', 'invoice_status', 'frequency')->withArchived()->where('is_quote', '=', false)->where('is_recurring', '=', true)->get();
     }
     if ($request->input(ENTITY_PAYMENT)) {
         $data['payments'] = Payment::scope()->withArchived()->with('user', 'client.contacts', 'payment_type', 'invoice', 'account_gateway.gateway')->get();
     }
     if ($request->input(ENTITY_VENDOR)) {
         $data['clients'] = Vendor::scope()->with('user', 'vendorcontacts', 'country')->withArchived()->get();
         $data['vendor_contacts'] = VendorContact::scope()->with('user', 'vendor.contacts')->withTrashed()->get();
         /*
         $data['expenses'] = Credit::scope()
             ->with('user', 'client.contacts')
             ->get();
         */
     }
     return $data;
 }
コード例 #17
0
 /**
  * @param $clientId
  * @return mixed
  */
 public function findOpenInvoices($clientId, $entityType = false)
 {
     $query = Invoice::scope()->invoiceType(INVOICE_TYPE_STANDARD)->whereClientId($clientId)->whereIsRecurring(false)->whereDeletedAt(null);
     if ($entityType == ENTITY_TASK) {
         $query->whereHasTasks(true);
     } elseif ($entityType == ENTITY_EXPENSE) {
         $query->whereHasExpenses(true);
     }
     return $query->where('invoice_status_id', '<', 5)->select(['public_id', 'invoice_number'])->get();
 }
コード例 #18
0
 public function emailInvoice()
 {
     $data = Input::all();
     $error = null;
     if (!isset($data['id'])) {
         $error = trans('validation.required', ['attribute' => 'id']);
     } else {
         $invoice = Invoice::scope($data['id'])->first();
         if (!$invoice) {
             $error = trans('validation.not_in', ['attribute' => 'id']);
         } else {
             $this->mailer->sendInvoice($invoice);
         }
     }
     if ($error) {
         $response = json_encode($error, JSON_PRETTY_PRINT);
     } else {
         $response = json_encode(RESULT_SUCCESS, JSON_PRETTY_PRINT);
     }
     $headers = Utils::getApiHeaders();
     return Response::make($response, $error ? 400 : 200, $headers);
 }
コード例 #19
0
 /**
  * @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;
 }
コード例 #20
0
 /**
  * @param TemplateService $templateService
  * @return \Illuminate\Http\Response
  */
 public function previewEmail(TemplateService $templateService)
 {
     $template = Input::get('template');
     $invoice = Invoice::scope()->invoices()->withTrashed()->first();
     if (!$invoice) {
         return trans('texts.create_invoice_for_sample');
     }
     /** @var \App\Models\Account $account */
     $account = Auth::user()->account;
     $invitation = $invoice->invitations->first();
     // replace the variables with sample data
     $data = ['account' => $account, 'invoice' => $invoice, 'invitation' => $invitation, 'link' => $invitation->getLink(), 'client' => $invoice->client, 'amount' => $invoice->amount];
     // create the email view
     $view = 'emails.' . $account->getTemplateView(ENTITY_INVOICE) . '_html';
     $data = array_merge($data, ['body' => $templateService->processVariables($template, $data), 'entityType' => ENTITY_INVOICE]);
     return Response::view($view, $data);
 }
コード例 #21
0
 public function getNextInvoiceNumber($invoice)
 {
     if ($this->hasNumberPattern($invoice->is_quote)) {
         return $this->getNumberPattern($invoice);
     }
     $counter = $this->getCounter($invoice->is_quote);
     $prefix = $invoice->is_quote ? $this->quote_number_prefix : $this->invoice_number_prefix;
     $counterOffset = 0;
     // confirm the invoice number isn't already taken
     do {
         $number = $prefix . str_pad($counter, 4, '0', STR_PAD_LEFT);
         $check = Invoice::scope(false, $this->id)->whereInvoiceNumber($number)->withTrashed()->first();
         $counter++;
         $counterOffset++;
     } while ($check);
     // update the invoice counter to be caught up
     if ($counterOffset > 1) {
         if ($invoice->is_quote && !$this->share_counter) {
             $this->quote_number_counter += $counterOffset - 1;
         } else {
             $this->invoice_number_counter += $counterOffset - 1;
         }
         $this->save();
     }
     return $number;
 }
コード例 #22
0
 public function findOpenInvoices($clientId)
 {
     return Invoice::scope()->whereClientId($clientId)->whereIsQuote(false)->whereIsRecurring(false)->whereDeletedAt(null)->whereHasTasks(true)->where('invoice_status_id', '<', 5)->select(['public_id', 'invoice_number'])->get();
 }
コード例 #23
0
 public function edit($publicId, $clone = false)
 {
     $account = Auth::user()->account;
     $invoice = Invoice::scope($publicId)->with('invitations', 'account.country', 'client.contacts', 'client.country', 'invoice_items')->withTrashed()->firstOrFail();
     $entityType = $invoice->getEntityType();
     $contactIds = DB::table('invitations')->join('contacts', 'contacts.id', '=', 'invitations.contact_id')->where('invitations.invoice_id', '=', $invoice->id)->where('invitations.account_id', '=', Auth::user()->account_id)->where('invitations.deleted_at', '=', null)->select('contacts.public_id')->lists('public_id');
     if ($clone) {
         $invoice->id = $invoice->public_id = null;
         $invoice->invoice_number = $account->getNextInvoiceNumber($invoice);
         $invoice->balance = $invoice->amount;
         $invoice->invoice_status_id = 0;
         $invoice->invoice_date = date_create()->format('Y-m-d');
         $method = 'POST';
         $url = "{$entityType}s";
     } else {
         Utils::trackViewed($invoice->getDisplayName() . ' - ' . $invoice->client->getDisplayName(), $invoice->getEntityType());
         $method = 'PUT';
         $url = "{$entityType}s/{$publicId}";
     }
     $invoice->invoice_date = Utils::fromSqlDate($invoice->invoice_date);
     $invoice->due_date = Utils::fromSqlDate($invoice->due_date);
     $invoice->start_date = Utils::fromSqlDate($invoice->start_date);
     $invoice->end_date = Utils::fromSqlDate($invoice->end_date);
     $invoice->last_sent_date = Utils::fromSqlDate($invoice->last_sent_date);
     $invoice->is_pro = Auth::user()->isPro();
     $actions = [['url' => 'javascript:onCloneClick()', 'label' => trans("texts.clone_{$entityType}")], ['url' => URL::to("{$entityType}s/{$entityType}_history/{$invoice->public_id}"), 'label' => trans("texts.view_history")], DropdownButton::DIVIDER];
     if ($invoice->invoice_status_id < INVOICE_STATUS_SENT && !$invoice->is_recurring) {
         $actions[] = ['url' => 'javascript:onMarkClick()', 'label' => trans("texts.mark_sent")];
     }
     if ($entityType == ENTITY_QUOTE) {
         if ($invoice->quote_invoice_id) {
             $actions[] = ['url' => URL::to("invoices/{$invoice->quote_invoice_id}/edit"), 'label' => trans("texts.view_invoice")];
         } else {
             $actions[] = ['url' => 'javascript:onConvertClick()', 'label' => trans("texts.convert_to_invoice")];
         }
     } elseif ($entityType == ENTITY_INVOICE) {
         if ($invoice->quote_id) {
             $actions[] = ['url' => URL::to("quotes/{$invoice->quote_id}/edit"), 'label' => trans("texts.view_quote")];
         }
         if (!$invoice->is_recurring && $invoice->balance > 0) {
             $actions[] = ['url' => 'javascript:onPaymentClick()', 'label' => trans('texts.enter_payment')];
         }
     }
     if (count($actions) > 3) {
         $actions[] = DropdownButton::DIVIDER;
     }
     $actions[] = ['url' => 'javascript:onArchiveClick()', 'label' => trans("texts.archive_{$entityType}")];
     $actions[] = ['url' => 'javascript:onDeleteClick()', 'label' => trans("texts.delete_{$entityType}")];
     $lastSent = $invoice->is_recurring && $invoice->last_sent_date ? $invoice->recurring_invoices->last() : null;
     $data = array('clients' => Client::scope()->withTrashed()->with('contacts', 'country')->whereId($invoice->client_id)->get(), 'entityType' => $entityType, 'showBreadcrumbs' => $clone, 'invoice' => $invoice, 'method' => $method, 'invitationContactIds' => $contactIds, 'url' => $url, 'title' => trans("texts.edit_{$entityType}"), 'client' => $invoice->client, 'isRecurring' => $invoice->is_recurring, 'actions' => $actions, 'lastSent' => $lastSent);
     $data = array_merge($data, self::getViewModel());
     if ($clone) {
         $data['formIsChanged'] = true;
     }
     // Set the invitation data on the client's contacts
     if (!$clone) {
         $clients = $data['clients'];
         foreach ($clients as $client) {
             if ($client->id != $invoice->client->id) {
                 continue;
             }
             foreach ($invoice->invitations as $invitation) {
                 foreach ($client->contacts as $contact) {
                     if ($invitation->contact_id == $contact->id) {
                         $contact->email_error = $invitation->email_error;
                         $contact->invitation_link = $invitation->getLink();
                         $contact->invitation_viewed = $invitation->viewed_date && $invitation->viewed_date != '0000-00-00 00:00:00' ? $invitation->viewed_date : false;
                         $contact->invitation_status = $contact->email_error ? false : $invitation->getStatus();
                     }
                 }
             }
             break;
         }
     }
     return View::make('invoices.edit', $data);
 }
コード例 #24
0
 public function findOpenInvoices($clientId)
 {
     return Invoice::scope()->whereClientId($clientId)->whereIsQuote(false)->whereIsRecurring(false)->whereHasTasks(true)->where('balance', '>', 0)->select(['public_id', 'invoice_number'])->get();
 }
コード例 #25
0
 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;
 }
コード例 #26
0
 /**
  * @SWG\Delete(
  *   path="/invoices",
  *   tags={"invoice"},
  *   summary="Delete an invoice",
  *   @SWG\Parameter(
  *     in="body",
  *     name="body",
  *     @SWG\Schema(ref="#/definitions/Invoice")
  *   ),
  *   @SWG\Response(
  *     response=200,
  *     description="Delete invoice",
  *      @SWG\Schema(type="object", @SWG\Items(ref="#/definitions/Invoice"))
  *   ),
  *   @SWG\Response(
  *     response="default",
  *     description="an ""unexpected"" error"
  *   )
  * )
  */
 public function destroy($publicId)
 {
     $data['public_id'] = $publicId;
     $invoice = Invoice::scope($publicId)->firstOrFail();
     $this->invoiceRepo->delete($invoice);
     $transformer = new InvoiceTransformer(\Auth::user()->account, Input::get('serializer'));
     $data = $this->createItem($invoice, $transformer, 'invoice');
     return $this->response($data);
 }
コード例 #27
0
 public function save($publicId, $data, $entityType)
 {
     if ($publicId) {
         $invoice = Invoice::scope($publicId)->firstOrFail();
     } else {
         $invoice = Invoice::createNew();
         if ($entityType == ENTITY_QUOTE) {
             $invoice->is_quote = true;
         }
     }
     $account = \Auth::user()->account;
     if (isset($data['set_default_terms']) && $data['set_default_terms'] || isset($data['set_default_footer']) && $data['set_default_footer']) {
         if (isset($data['set_default_terms']) && $data['set_default_terms']) {
             $account->invoice_terms = trim($data['terms']);
         }
         if (isset($data['set_default_footer']) && $data['set_default_footer']) {
             $account->invoice_footer = trim($data['invoice_footer']);
         }
         $account->save();
     }
     $invoice->client_id = $data['client_id'];
     $invoice->discount = round(Utils::parseFloat($data['discount']), 2);
     $invoice->is_amount_discount = $data['is_amount_discount'] ? true : false;
     $invoice->invoice_number = trim($data['invoice_number']);
     $invoice->partial = round(Utils::parseFloat($data['partial']), 2);
     $invoice->invoice_date = isset($data['invoice_date_sql']) ? $data['invoice_date_sql'] : Utils::toSqlDate($data['invoice_date']);
     $invoice->has_tasks = isset($data['has_tasks']) ? $data['has_tasks'] : false;
     if (!$publicId) {
         $invoice->is_recurring = $data['is_recurring'] && !Utils::isDemo() ? true : false;
     }
     if ($invoice->is_recurring) {
         $invoice->frequency_id = $data['frequency_id'] ? $data['frequency_id'] : 0;
         $invoice->start_date = Utils::toSqlDate($data['start_date']);
         $invoice->end_date = Utils::toSqlDate($data['end_date']);
         $invoice->due_date = null;
     } else {
         $invoice->due_date = isset($data['due_date_sql']) ? $data['due_date_sql'] : Utils::toSqlDate($data['due_date']);
         $invoice->frequency_id = 0;
         $invoice->start_date = null;
         $invoice->end_date = null;
     }
     $invoice->terms = trim($data['terms']) ? trim($data['terms']) : (!$publicId && $account->invoice_terms ? $account->invoice_terms : '');
     $invoice->invoice_footer = trim($data['invoice_footer']) ? trim($data['invoice_footer']) : (!$publicId && $account->invoice_footer ? $account->invoice_footer : '');
     $invoice->public_notes = trim($data['public_notes']);
     // process date variables
     $invoice->terms = Utils::processVariables($invoice->terms);
     $invoice->invoice_footer = Utils::processVariables($invoice->invoice_footer);
     $invoice->public_notes = Utils::processVariables($invoice->public_notes);
     $invoice->po_number = trim($data['po_number']);
     $invoice->invoice_design_id = $data['invoice_design_id'];
     if (isset($data['tax_name']) && isset($data['tax_rate']) && $data['tax_name']) {
         $invoice->tax_rate = Utils::parseFloat($data['tax_rate']);
         $invoice->tax_name = trim($data['tax_name']);
     } else {
         $invoice->tax_rate = 0;
         $invoice->tax_name = '';
     }
     $total = 0;
     foreach ($data['invoice_items'] as $item) {
         $item = (array) $item;
         if (!$item['cost'] && !$item['product_key'] && !$item['notes']) {
             continue;
         }
         $invoiceItemCost = round(Utils::parseFloat($item['cost']), 2);
         $invoiceItemQty = round(Utils::parseFloat($item['qty']), 2);
         $invoiceItemTaxRate = 0;
         if (isset($item['tax_rate']) && Utils::parseFloat($item['tax_rate']) > 0) {
             $invoiceItemTaxRate = Utils::parseFloat($item['tax_rate']);
         }
         $lineTotal = $invoiceItemCost * $invoiceItemQty;
         $total += round($lineTotal + $lineTotal * $invoiceItemTaxRate / 100, 2);
     }
     if ($invoice->discount > 0) {
         if ($invoice->is_amount_discount) {
             $total -= $invoice->discount;
         } else {
             $total *= (100 - $invoice->discount) / 100;
         }
     }
     $invoice->custom_value1 = round($data['custom_value1'], 2);
     $invoice->custom_value2 = round($data['custom_value2'], 2);
     $invoice->custom_taxes1 = $data['custom_taxes1'] ? true : false;
     $invoice->custom_taxes2 = $data['custom_taxes2'] ? true : false;
     // custom fields charged taxes
     if ($invoice->custom_value1 && $invoice->custom_taxes1) {
         $total += $invoice->custom_value1;
     }
     if ($invoice->custom_value2 && $invoice->custom_taxes2) {
         $total += $invoice->custom_value2;
     }
     $total += $total * $invoice->tax_rate / 100;
     $total = round($total, 2);
     // custom fields not charged taxes
     if ($invoice->custom_value1 && !$invoice->custom_taxes1) {
         $total += $invoice->custom_value1;
     }
     if ($invoice->custom_value2 && !$invoice->custom_taxes2) {
         $total += $invoice->custom_value2;
     }
     if ($publicId) {
         $invoice->balance = $total - ($invoice->amount - $invoice->balance);
     } else {
         $invoice->balance = $total;
     }
     $invoice->amount = $total;
     $invoice->save();
     if ($publicId) {
         $invoice->invoice_items()->forceDelete();
     }
     foreach ($data['invoice_items'] as $item) {
         $item = (array) $item;
         if (!$item['cost'] && !$item['product_key'] && !$item['notes']) {
             continue;
         }
         if (isset($item['task_public_id']) && $item['task_public_id']) {
             $task = Task::scope($item['task_public_id'])->where('invoice_id', '=', null)->firstOrFail();
             $task->invoice_id = $invoice->id;
             $task->client_id = $invoice->client_id;
             $task->save();
         } else {
             if ($item['product_key']) {
                 $product = Product::findProductByKey(trim($item['product_key']));
                 if (!$product) {
                     $product = Product::createNew();
                     $product->product_key = trim($item['product_key']);
                 }
                 if (\Auth::user()->account->update_products) {
                     $product->notes = $item['notes'];
                     $product->cost = $item['cost'];
                 }
                 $product->save();
             }
         }
         $invoiceItem = InvoiceItem::createNew();
         $invoiceItem->product_id = isset($product) ? $product->id : null;
         $invoiceItem->product_key = trim($invoice->is_recurring ? $item['product_key'] : Utils::processVariables($item['product_key']));
         $invoiceItem->notes = trim($invoice->is_recurring ? $item['notes'] : Utils::processVariables($item['notes']));
         $invoiceItem->cost = Utils::parseFloat($item['cost']);
         $invoiceItem->qty = Utils::parseFloat($item['qty']);
         $invoiceItem->tax_rate = 0;
         if (isset($item['tax_rate']) && isset($item['tax_name']) && $item['tax_name']) {
             $invoiceItem['tax_rate'] = Utils::parseFloat($item['tax_rate']);
             $invoiceItem['tax_name'] = trim($item['tax_name']);
         }
         $invoice->invoice_items()->save($invoiceItem);
     }
     return $invoice;
 }
コード例 #28
0
 /**
  * @SWG\Put(
  *   path="/invoices",
  *   tags={"invoice"},
  *   summary="Update an invoice",
  *   @SWG\Parameter(
  *     in="body",
  *     name="body",
  *     @SWG\Schema(ref="#/definitions/Invoice")
  *   ),
  *   @SWG\Response(
  *     response=200,
  *     description="Update invoice",
  *      @SWG\Schema(type="object", @SWG\Items(ref="#/definitions/Invoice"))
  *   ),
  *   @SWG\Response(
  *     response="default",
  *     description="an ""unexpected"" error"
  *   )
  * )
  */
 public function update(UpdateInvoiceAPIRequest $request, $publicId)
 {
     if ($request->action == ACTION_CONVERT) {
         $quote = $request->entity();
         $invoice = $this->invoiceRepo->cloneInvoice($quote, $quote->id);
         return $this->itemResponse($invoice);
     } elseif ($request->action) {
         return $this->handleAction($request);
     }
     $data = $request->input();
     $data['public_id'] = $publicId;
     $this->invoiceService->save($data, $request->entity());
     $invoice = Invoice::scope($publicId)->with('client', 'invoice_items', 'invitations')->firstOrFail();
     return $this->itemResponse($invoice);
 }
コード例 #29
0
ファイル: Account.php プロジェクト: ricoa/invoice-ninja
 public function getNextInvoiceNumber($isQuote = false, $prefix = '')
 {
     $counter = $isQuote && !$this->share_counter ? $this->quote_number_counter : $this->invoice_number_counter;
     $prefix .= $isQuote ? $this->quote_number_prefix : $this->invoice_number_prefix;
     // confirm the invoice number isn't already taken
     do {
         $number = $prefix . str_pad($counter, 4, "0", STR_PAD_LEFT);
         $check = Invoice::scope(false, $this->id)->whereInvoiceNumber($number)->withTrashed()->first();
         $counter++;
     } while ($check);
     return $number;
 }
コード例 #30
0
 public function checkInvoiceNumber($invoicePublicId = false)
 {
     $invoiceNumber = request()->invoice_number;
     $query = Invoice::scope()->whereInvoiceNumber($invoiceNumber)->withTrashed();
     if ($invoicePublicId) {
         $query->where('public_id', '!=', $invoicePublicId);
     }
     $count = $query->count();
     return $count ? RESULT_FAILURE : RESULT_SUCCESS;
 }