상속: extends EntityModel, use trait Illuminate\Database\Eloquent\SoftDeletes
예제 #1
0
 public function save($data)
 {
     if (isset($data['client'])) {
         $client = $this->clientRepo->save($data['client']);
         $data['client_id'] = $client->id;
     }
     $invoice = $this->invoiceRepo->save($data);
     $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;
 }
 /**
  * Run the database seeds.
  *
  * @return void
  */
 public function run()
 {
     DB::table('invitations')->truncate();
     $faker = Faker\Factory::create();
     for ($i = 0; $i < 50; $i++) {
         Invitation::create(['title' => $faker->sentence(6), 'address' => $faker->slug(), 'latitude' => $faker->latitude, 'longitude' => $faker->longitude, 'phone' => $faker->phoneNumber, 'level' => $faker->randomElement(['Mới biết chơi', 'Khá - Giỏi', 'Chuyên nghiệp']), 'time' => $faker->randomElement(['5-7', '7-9', '6-8']), 'description' => $faker->paragraph(4), 'user_id' => $faker->randomElement(range(1, 30))]);
     }
 }
 public function sanitize()
 {
     $input = $this->all();
     $invitation = Invitation::with('invoice.invoice_items', 'invoice.client.currency', 'invoice.client.account.currency', 'invoice.client.account.account_gateways.gateway')->where('invitation_key', '=', $this->invitation_key)->firstOrFail();
     $input['invitation'] = $invitation;
     $input['gateway_type'] = session($invitation->id . 'gateway_type');
     $this->replace($input);
     return $this->all();
 }
예제 #4
0
 protected function getInvitation($key)
 {
     $invitation = Invitation::withTrashed()->where('invitation_key', '=', $key)->first();
     if ($invitation && !$invitation->is_deleted) {
         return $invitation;
     } else {
         return null;
     }
 }
예제 #5
0
 public function markBounced($messageId, $error)
 {
     $invitation = Invitation::with('user', 'invoice', 'contact')->whereMessageId($messageId)->first();
     if (!$invitation) {
         return false;
     }
     $invitation->email_error = $error;
     $invitation->save();
     $this->userMailer->sendEmailBounced($invitation);
     return true;
 }
예제 #6
0
 /**
  * Get the needed authorization credentials from the request.
  *
  * @param  \Illuminate\Http\Request  $request
  * @return array
  */
 protected function getCredentials(Request $request)
 {
     $credentials = $request->only('password');
     $credentials['id'] = null;
     $invitation_key = session('invitation_key');
     if ($invitation_key) {
         $invitation = Invitation::where('invitation_key', '=', $invitation_key)->first();
         if ($invitation && !$invitation->is_deleted) {
             $credentials['id'] = $invitation->contact_id;
         }
     }
     return $credentials;
 }
예제 #7
0
 /**
  * @param array $data
  * @param Invoice|null $invoice
  * @return \App\Models\Invoice|Invoice|mixed
  */
 public function save(array $data, Invoice $invoice = null)
 {
     if (isset($data['client'])) {
         $canSaveClient = false;
         $canViewClient = false;
         $clientPublicId = array_get($data, 'client.public_id') ?: array_get($data, 'client.id');
         if (empty($clientPublicId) || $clientPublicId == '-1') {
             $canSaveClient = Auth::user()->can('create', ENTITY_CLIENT);
         } else {
             $client = Client::scope($clientPublicId)->first();
             $canSaveClient = Auth::user()->can('edit', $client);
             $canViewClient = Auth::user()->can('view', $client);
         }
         if ($canSaveClient) {
             $client = $this->clientRepo->save($data['client']);
         }
         if ($canSaveClient || $canViewClient) {
             $data['client_id'] = $client->id;
         }
     }
     $invoice = $this->invoiceRepo->save($data, $invoice);
     $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;
 }
예제 #8
0
 public function create()
 {
     $this->validateRoute();
     $user = $this->getRepository()->createOrUpdate($this->request->all());
     $sandboxData = [];
     if (env('APP_ENV') == 'local') {
         $sandboxData['token_email'] = $user->getVerifyEmailToken();
     }
     $invitation = Invitation::where('email', $user->email)->get();
     foreach ($invitation as $item) {
         if (array_key_exists('_id', $item->project)) {
             $application = Application::find($item->project['_id']);
             if (!$application->getUser($user->email)) {
                 $application->setUser(['user_id' => (string) $user->_id, 'role' => $item->role, 'scope' => $item->scope])->save();
             }
         }
     }
     return $this->response->json($user->toArray(), Response::HTTP_CREATED, [], [], $sandboxData);
 }
예제 #9
0
 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;
 }
예제 #10
0
 /**
  * @SWG\Post(
  *   path="/invoices",
  *   tags={"invoice"},
  *   summary="Create an invoice",
  *   @SWG\Parameter(
  *     in="body",
  *     name="body",
  *     @SWG\Schema(ref="#/definitions/Invoice")
  *   ),
  *   @SWG\Response(
  *     response=200,
  *     description="New invoice",
  *      @SWG\Schema(type="object", @SWG\Items(ref="#/definitions/Invoice"))
  *   ),
  *   @SWG\Response(
  *     response="default",
  *     description="an ""unexpected"" error"
  *   )
  * )
  */
 public function store(CreateInvoiceRequest $request)
 {
     $data = Input::all();
     $error = null;
     if (isset($data['email'])) {
         $email = $data['email'];
         $client = Client::scope()->whereHas('contacts', function ($query) use($email) {
             $query->where('email', '=', $email);
         })->first();
         if (!$client) {
             $validator = Validator::make(['email' => $email], ['email' => 'email']);
             if ($validator->fails()) {
                 $messages = $validator->messages();
                 return $messages->first();
             }
             $clientData = ['contact' => ['email' => $email]];
             foreach (['name', 'private_notes'] as $field) {
                 if (isset($data[$field])) {
                     $clientData[$field] = $data[$field];
                 }
             }
             foreach (['first_name', 'last_name'] as $field) {
                 if (isset($data[$field])) {
                     $clientData[$field] = $data[$field];
                 }
             }
             $client = $this->clientRepo->save($clientData);
         }
     } else {
         if (isset($data['client_id'])) {
             $client = Client::scope($data['client_id'])->firstOrFail();
         }
     }
     $data = self::prepareData($data, $client);
     $data['client_id'] = $client->id;
     $invoice = $this->invoiceRepo->save($data);
     if (!isset($data['id'])) {
         $invitation = Invitation::createNew();
         $invitation->invoice_id = $invoice->id;
         $invitation->contact_id = $client->contacts[0]->id;
         $invitation->invitation_key = str_random(RANDOM_KEY_LENGTH);
         $invitation->save();
     }
     if (isset($data['email_invoice']) && $data['email_invoice']) {
         $this->mailer->sendInvoice($invoice);
     }
     $invoice = Invoice::scope($invoice->public_id)->with('client', 'invoice_items', 'invitations')->first();
     $transformer = new InvoiceTransformer(\Auth::user()->account, Input::get('serializer'));
     $data = $this->createItem($invoice, $transformer, 'invoice');
     return $this->response($data);
 }
예제 #11
0
 private function saveInvoice($publicId, $input, $entityType)
 {
     $invoice = $input->invoice;
     $this->taxRateRepo->save($input->tax_rates);
     $clientData = (array) $invoice->client;
     $client = $this->clientRepo->save($invoice->client->public_id, $clientData);
     $invoiceData = (array) $invoice;
     $invoiceData['client_id'] = $client->id;
     $invoice = $this->invoiceRepo->save($publicId, $invoiceData, $entityType);
     $account = Auth::user()->account;
     if ($account->invoice_taxes != $input->invoice_taxes || $account->invoice_item_taxes != $input->invoice_item_taxes || $account->invoice_design_id != $input->invoice->invoice_design_id || $account->show_item_taxes != $input->show_item_taxes) {
         $account->invoice_taxes = $input->invoice_taxes;
         $account->invoice_item_taxes = $input->invoice_item_taxes;
         $account->invoice_design_id = $input->invoice->invoice_design_id;
         $account->show_item_taxes = $input->show_item_taxes;
         $account->save();
     }
     $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;
 }
예제 #12
0
 public function cloneInvoice($invoice, $quotePublicId = null)
 {
     $invoice->load('invitations', 'invoice_items');
     $account = $invoice->account;
     $clone = Invoice::createNew($invoice);
     $clone->balance = $invoice->amount;
     // if the invoice prefix is diff than quote prefix, use the same number for the invoice
     if (($account->invoice_number_prefix || $account->quote_number_prefix) && $account->invoice_number_prefix != $account->quote_number_prefix && $account->share_counter) {
         $invoiceNumber = $invoice->invoice_number;
         if ($account->quote_number_prefix && strpos($invoiceNumber, $account->quote_number_prefix) === 0) {
             $invoiceNumber = substr($invoiceNumber, strlen($account->quote_number_prefix));
         }
         $clone->invoice_number = $account->invoice_number_prefix . $invoiceNumber;
     } else {
         $clone->invoice_number = $account->getNextInvoiceNumber();
     }
     foreach (['client_id', 'discount', 'is_amount_discount', 'invoice_date', 'po_number', 'due_date', 'is_recurring', 'frequency_id', 'start_date', 'end_date', 'terms', 'invoice_footer', 'public_notes', 'invoice_design_id', 'tax_name', 'tax_rate', 'amount', 'is_quote', 'custom_value1', 'custom_value2', 'custom_taxes1', 'custom_taxes2', 'partial'] as $field) {
         $clone->{$field} = $invoice->{$field};
     }
     if ($quotePublicId) {
         $clone->is_quote = false;
         $clone->quote_id = $quotePublicId;
     }
     $clone->save();
     if ($quotePublicId) {
         $invoice->quote_invoice_id = $clone->public_id;
         $invoice->save();
     }
     foreach ($invoice->invoice_items as $item) {
         $cloneItem = InvoiceItem::createNew($invoice);
         foreach (['product_id', 'product_key', 'notes', 'cost', 'qty', 'tax_name', 'tax_rate'] as $field) {
             $cloneItem->{$field} = $item->{$field};
         }
         $clone->invoice_items()->save($cloneItem);
     }
     foreach ($invoice->invitations as $invitation) {
         $cloneInvitation = Invitation::createNew($invoice);
         $cloneInvitation->contact_id = $invitation->contact_id;
         $cloneInvitation->invitation_key = str_random(RANDOM_KEY_LENGTH);
         $clone->invitations()->save($cloneInvitation);
     }
     return $clone;
 }
 private function getInvitation()
 {
     $invitationKey = session('invitation_key');
     if (!$invitationKey) {
         return false;
     }
     $invitation = Invitation::where('invitation_key', '=', $invitationKey)->first();
     if (!$invitation || $invitation->is_deleted) {
         return false;
     }
     $invoice = $invitation->invoice;
     if (!$invoice || $invoice->is_deleted) {
         return false;
     }
     return $invitation;
 }
예제 #14
0
 /**
  * Bootstrap any necessary services.
  *
  * @return void
  */
 public function boot()
 {
     Table::observe(new TableObserver());
     User::observe(new UserObserver());
     Invitation::observe(new InvitationsObserver());
 }
 /**
  * Display the password reset view for the given token.
  *
  * If no token is present, display the link request form.
  *
  * @param  \Illuminate\Http\Request $request
  * @param  string|null $key
  * @param  string|null $token
  * @return \Illuminate\Http\Response
  */
 public function showResetForm(Request $request, $key = null, $token = null)
 {
     if (is_null($token)) {
         return $this->getEmail();
     }
     $data = compact('token');
     if ($key) {
         $contact = Contact::where('contact_key', '=', $key)->first();
         if ($contact && !$contact->is_deleted) {
             $account = $contact->account;
             $data['contact_key'] = $contact->contact_key;
         } else {
             // Maybe it's an invitation key
             $invitation = Invitation::where('invitation_key', '=', $key)->first();
             if ($invitation && !$invitation->is_deleted) {
                 $account = $invitation->account;
                 $data['contact_key'] = $invitation->contact->contact_key;
             }
         }
         if (!empty($account)) {
             $data['account'] = $account;
             $data['clientFontUrl'] = $account->getFontsUrl();
         } else {
             return \Redirect::to('/client/sessionexpired');
         }
     }
     return view('clientauth.reset')->with($data);
 }
 public function createNinjaInvoice($client, $clientAccount, $plan = PLAN_PRO, $term = PLAN_TERM_MONTHLY, $credit = 0, $pending_monthly = false)
 {
     if ($credit < 0) {
         $credit = 0;
     }
     $plan_cost = Account::$plan_prices[$plan][$term];
     $account = $this->getNinjaAccount();
     $lastInvoice = Invoice::withTrashed()->whereAccountId($account->id)->orderBy('public_id', 'DESC')->first();
     $publicId = $lastInvoice ? $lastInvoice->public_id + 1 : 1;
     $invoice = new Invoice();
     $invoice->account_id = $account->id;
     $invoice->user_id = $account->users()->first()->id;
     $invoice->public_id = $publicId;
     $invoice->client_id = $client->id;
     $invoice->invoice_number = $account->getNextInvoiceNumber($invoice);
     $invoice->invoice_date = $clientAccount->getRenewalDate();
     $invoice->amount = $invoice->balance = $plan_cost - $credit;
     $invoice->save();
     if ($credit) {
         $credit_item = InvoiceItem::createNew($invoice);
         $credit_item->qty = 1;
         $credit_item->cost = -$credit;
         $credit_item->notes = trans('texts.plan_credit_description');
         $credit_item->product_key = trans('texts.plan_credit_product');
         $invoice->invoice_items()->save($credit_item);
     }
     $item = InvoiceItem::createNew($invoice);
     $item->qty = 1;
     $item->cost = $plan_cost;
     $item->notes = trans("texts.{$plan}_plan_{$term}_description");
     // Don't change this without updating the regex in PaymentService->createPayment()
     $item->product_key = 'Plan - ' . ucfirst($plan) . ' (' . ucfirst($term) . ')';
     $invoice->invoice_items()->save($item);
     if ($pending_monthly) {
         $term_end = $term == PLAN_MONTHLY ? date_create('+1 month') : date_create('+1 year');
         $pending_monthly_item = InvoiceItem::createNew($invoice);
         $item->qty = 1;
         $pending_monthly_item->cost = 0;
         $pending_monthly_item->notes = trans("texts.plan_pending_monthly", array('date', Utils::dateToString($term_end)));
         // Don't change this without updating the text in PaymentService->createPayment()
         $pending_monthly_item->product_key = 'Pending Monthly';
         $invoice->invoice_items()->save($pending_monthly_item);
     }
     $invitation = new Invitation();
     $invitation->account_id = $account->id;
     $invitation->user_id = $account->users()->first()->id;
     $invitation->public_id = $publicId;
     $invitation->invoice_id = $invoice->id;
     $invitation->contact_id = $client->contacts()->first()->id;
     $invitation->invitation_key = str_random(RANDOM_KEY_LENGTH);
     $invitation->save();
     return $invitation;
 }
예제 #17
0
 public function createRecurringInvoice($recurInvoice)
 {
     $recurInvoice->load('account.timezone', 'invoice_items', 'client', 'user');
     if ($recurInvoice->client->deleted_at) {
         return false;
     }
     if (!$recurInvoice->user->confirmed) {
         return false;
     }
     if (!$recurInvoice->shouldSendToday()) {
         return false;
     }
     $invoice = Invoice::createNew($recurInvoice);
     $invoice->client_id = $recurInvoice->client_id;
     $invoice->recurring_invoice_id = $recurInvoice->id;
     $invoice->invoice_number = 'R' . $recurInvoice->account->getNextInvoiceNumber($recurInvoice);
     $invoice->amount = $recurInvoice->amount;
     $invoice->balance = $recurInvoice->amount;
     $invoice->invoice_date = date_create()->format('Y-m-d');
     $invoice->discount = $recurInvoice->discount;
     $invoice->po_number = $recurInvoice->po_number;
     $invoice->public_notes = Utils::processVariables($recurInvoice->public_notes);
     $invoice->terms = Utils::processVariables($recurInvoice->terms);
     $invoice->invoice_footer = Utils::processVariables($recurInvoice->invoice_footer);
     $invoice->tax_name = $recurInvoice->tax_name;
     $invoice->tax_rate = $recurInvoice->tax_rate;
     $invoice->invoice_design_id = $recurInvoice->invoice_design_id;
     $invoice->custom_value1 = $recurInvoice->custom_value1 ?: 0;
     $invoice->custom_value2 = $recurInvoice->custom_value2 ?: 0;
     $invoice->custom_taxes1 = $recurInvoice->custom_taxes1 ?: 0;
     $invoice->custom_taxes2 = $recurInvoice->custom_taxes2 ?: 0;
     $invoice->custom_text_value1 = $recurInvoice->custom_text_value1;
     $invoice->custom_text_value2 = $recurInvoice->custom_text_value2;
     $invoice->is_amount_discount = $recurInvoice->is_amount_discount;
     if ($invoice->client->payment_terms != 0) {
         $days = $invoice->client->payment_terms;
         if ($days == -1) {
             $days = 0;
         }
         $invoice->due_date = date_create()->modify($days . ' day')->format('Y-m-d');
     }
     $invoice->save();
     foreach ($recurInvoice->invoice_items as $recurItem) {
         $item = InvoiceItem::createNew($recurItem);
         $item->product_id = $recurItem->product_id;
         $item->qty = $recurItem->qty;
         $item->cost = $recurItem->cost;
         $item->notes = Utils::processVariables($recurItem->notes);
         $item->product_key = Utils::processVariables($recurItem->product_key);
         $item->tax_name = $recurItem->tax_name;
         $item->tax_rate = $recurItem->tax_rate;
         $invoice->invoice_items()->save($item);
     }
     foreach ($recurInvoice->invitations as $recurInvitation) {
         $invitation = Invitation::createNew($recurInvitation);
         $invitation->contact_id = $recurInvitation->contact_id;
         $invitation->invitation_key = str_random(RANDOM_KEY_LENGTH);
         $invoice->invitations()->save($invitation);
     }
     $recurInvoice->last_sent_date = date('Y-m-d');
     $recurInvoice->save();
     if ($recurInvoice->auto_bill) {
         if ($this->paymentService->autoBillInvoice($invoice)) {
             // update the invoice reference to match its actual state
             // this is to ensure a 'payment received' email is sent
             $invoice->invoice_status_id = INVOICE_STATUS_PAID;
         }
     }
     return $invoice;
 }
예제 #18
0
 public function createNinjaInvoice($client)
 {
     $account = $this->getNinjaAccount();
     $lastInvoice = Invoice::withTrashed()->whereAccountId($account->id)->orderBy('public_id', 'DESC')->first();
     $publicId = $lastInvoice ? $lastInvoice->public_id + 1 : 1;
     $invoice = new Invoice();
     $invoice->account_id = $account->id;
     $invoice->user_id = $account->users()->first()->id;
     $invoice->public_id = $publicId;
     $invoice->client_id = $client->id;
     $invoice->invoice_number = $account->getNextInvoiceNumber();
     $invoice->invoice_date = date_create()->format('Y-m-d');
     $invoice->amount = PRO_PLAN_PRICE;
     $invoice->balance = PRO_PLAN_PRICE;
     $invoice->save();
     $item = new InvoiceItem();
     $item->account_id = $account->id;
     $item->user_id = $account->users()->first()->id;
     $item->public_id = $publicId;
     $item->qty = 1;
     $item->cost = PRO_PLAN_PRICE;
     $item->notes = trans('texts.pro_plan_description');
     $item->product_key = trans('texts.pro_plan_product');
     $invoice->invoice_items()->save($item);
     $invitation = new Invitation();
     $invitation->account_id = $account->id;
     $invitation->user_id = $account->users()->first()->id;
     $invitation->public_id = $publicId;
     $invitation->invoice_id = $invoice->id;
     $invitation->contact_id = $client->contacts()->first()->id;
     $invitation->invitation_key = str_random(RANDOM_KEY_LENGTH);
     $invitation->save();
     return $invitation;
 }
 public function transform(Invitation $invitation)
 {
     $invitation->setRelation('account', $this->account);
     return ['id' => (int) $invitation->public_id, 'key' => $invitation->getName(), 'status' => $invitation->getStatus(), 'link' => $invitation->getLink(), 'sent_date' => $invitation->sent_date, 'viewed_date' => $invitation->sent_date];
 }
예제 #20
0
 public function approve($invitationKey)
 {
     $invitation = Invitation::with('invoice.invoice_items', 'invoice.invitations')->where('invitation_key', '=', $invitationKey)->firstOrFail();
     $invoice = $invitation->invoice;
     if ($invoice->is_quote && !$invoice->quote_invoice_id) {
         Event::fire(new QuoteApproved($invoice));
         Activity::approveQuote($invitation);
         $invoice = $this->invoiceRepo->cloneInvoice($invoice, $invoice->id);
         Session::flash('message', trans('texts.converted_to_invoice'));
         foreach ($invoice->invitations as $invitationClone) {
             if ($invitation->contact_id == $invitationClone->contact_id) {
                 $invitationKey = $invitationClone->invitation_key;
             }
         }
     }
     return Redirect::to("view/{$invitationKey}");
 }
예제 #21
0
 /**
  * @SWG\Post(
  *   path="/invoices",
  *   tags={"invoice"},
  *   summary="Create an invoice",
  *   @SWG\Parameter(
  *     in="body",
  *     name="body",
  *     @SWG\Schema(ref="#/definitions/Invoice")
  *   ),
  *   @SWG\Response(
  *     response=200,
  *     description="New invoice",
  *      @SWG\Schema(type="object", @SWG\Items(ref="#/definitions/Invoice"))
  *   ),
  *   @SWG\Response(
  *     response="default",
  *     description="an ""unexpected"" error"
  *   )
  * )
  */
 public function store()
 {
     $data = Input::all();
     $error = null;
     if (isset($data['id']) || isset($data['public_id'])) {
         die("We don't yet support updating invoices");
     }
     if (isset($data['email'])) {
         $email = $data['email'];
         $client = Client::scope()->whereHas('contacts', function ($query) use($email) {
             $query->where('email', '=', $email);
         })->first();
         if (!$client) {
             $validator = Validator::make(['email' => $email], ['email' => 'email']);
             if ($validator->fails()) {
                 $messages = $validator->messages();
                 return $messages->first();
             }
             $clientData = ['contact' => ['email' => $email]];
             foreach (['name', 'private_notes'] as $field) {
                 if (isset($data[$field])) {
                     $clientData[$field] = $data[$field];
                 }
             }
             foreach (['first_name', 'last_name'] as $field) {
                 if (isset($data[$field])) {
                     $clientData[$field] = $data[$field];
                 }
             }
             $client = $this->clientRepo->save($clientData);
         }
     } else {
         if (isset($data['client_id'])) {
             $client = Client::scope($data['client_id'])->first();
         }
     }
     // check if the invoice number is set and unique
     if (!isset($data['invoice_number']) && !isset($data['id'])) {
         // do nothing... invoice number will be set automatically
     } else {
         if (isset($data['invoice_number'])) {
             $invoice = Invoice::scope()->where('invoice_number', '=', $data['invoice_number'])->first();
             if ($invoice) {
                 $error = trans('validation.unique', ['attribute' => 'texts.invoice_number']);
             }
         }
     }
     if (!$error) {
         if (!isset($data['client_id']) && !isset($data['email'])) {
             $error = trans('validation.required_without', ['attribute' => 'client_id', 'values' => 'email']);
         } else {
             if (!$client) {
                 $error = trans('validation.not_in', ['attribute' => 'client_id']);
             }
         }
     }
     if ($error) {
         return $error;
     } else {
         $data = self::prepareData($data, $client);
         $data['client_id'] = $client->id;
         $invoice = $this->invoiceRepo->save($data);
         if (!isset($data['id'])) {
             $invitation = Invitation::createNew();
             $invitation->invoice_id = $invoice->id;
             $invitation->contact_id = $client->contacts[0]->id;
             $invitation->invitation_key = str_random(RANDOM_KEY_LENGTH);
             $invitation->save();
         }
         if (isset($data['email_invoice']) && $data['email_invoice']) {
             $this->mailer->sendInvoice($invoice);
         }
         $invoice = Invoice::scope($invoice->public_id)->with('client', 'invoice_items', 'invitations')->first();
         $transformer = new InvoiceTransformer(\Auth::user()->account, Input::get('serializer'));
         $data = $this->createItem($invoice, $transformer, 'invoice');
         return $this->response($data);
     }
 }
 public function createNinjaInvoice($client, $clientAccount, $plan, $credit = 0)
 {
     $term = $plan['term'];
     $plan_cost = $plan['price'];
     $num_users = $plan['num_users'];
     $plan = $plan['plan'];
     if ($credit < 0) {
         $credit = 0;
     }
     $account = $this->getNinjaAccount();
     $lastInvoice = Invoice::withTrashed()->whereAccountId($account->id)->orderBy('public_id', 'DESC')->first();
     $publicId = $lastInvoice ? $lastInvoice->public_id + 1 : 1;
     $invoice = new Invoice();
     $invoice->account_id = $account->id;
     $invoice->user_id = $account->users()->first()->id;
     $invoice->public_id = $publicId;
     $invoice->client_id = $client->id;
     $invoice->invoice_number = $account->getNextInvoiceNumber($invoice);
     $invoice->invoice_date = $clientAccount->getRenewalDate();
     $invoice->amount = $invoice->balance = $plan_cost - $credit;
     $invoice->invoice_type_id = INVOICE_TYPE_STANDARD;
     $invoice->save();
     if ($credit) {
         $credit_item = InvoiceItem::createNew($invoice);
         $credit_item->qty = 1;
         $credit_item->cost = -$credit;
         $credit_item->notes = trans('texts.plan_credit_description');
         $credit_item->product_key = trans('texts.plan_credit_product');
         $invoice->invoice_items()->save($credit_item);
     }
     $item = InvoiceItem::createNew($invoice);
     $item->qty = 1;
     $item->cost = $plan_cost;
     $item->notes = trans("texts.{$plan}_plan_{$term}_description");
     if ($plan == PLAN_ENTERPRISE) {
         $min = Utils::getMinNumUsers($num_users);
         $item->notes .= "\n\n###" . trans('texts.min_to_max_users', ['min' => $min, 'max' => $num_users]);
     }
     // Don't change this without updating the regex in PaymentService->createPayment()
     $item->product_key = 'Plan - ' . ucfirst($plan) . ' (' . ucfirst($term) . ')';
     $invoice->invoice_items()->save($item);
     $invitation = new Invitation();
     $invitation->account_id = $account->id;
     $invitation->user_id = $account->users()->first()->id;
     $invitation->public_id = $publicId;
     $invitation->invoice_id = $invoice->id;
     $invitation->contact_id = $client->contacts()->first()->id;
     $invitation->invitation_key = str_random(RANDOM_KEY_LENGTH);
     $invitation->save();
     return $invitation;
 }
 public function offsite_payment()
 {
     $payerId = Request::query('PayerID');
     $token = Request::query('token');
     if (!$token) {
         $token = Session::pull('transaction_reference');
     }
     if (!$token) {
         return redirect(NINJA_WEB_URL);
     }
     $invitation = Invitation::with('invoice.client.currency', 'invoice.client.account.account_gateways.gateway')->where('transaction_reference', '=', $token)->firstOrFail();
     $invoice = $invitation->invoice;
     $accountGateway = $invoice->client->account->getGatewayByType(Session::get('payment_type'));
     $gateway = $this->paymentService->createGateway($accountGateway);
     // Check for Dwolla payment error
     if ($accountGateway->isGateway(GATEWAY_DWOLLA) && Input::get('error')) {
         $this->error('Dwolla', Input::get('error_description'), $accountGateway);
         return Redirect::to('view/' . $invitation->invitation_key);
     }
     try {
         if (method_exists($gateway, 'completePurchase')) {
             $details = $this->paymentService->getPaymentDetails($invitation);
             $response = $gateway->completePurchase($details)->send();
             $ref = $response->getTransactionReference();
             if ($response->isSuccessful()) {
                 $payment = $this->paymentService->createPayment($invitation, $ref, $payerId);
                 Session::flash('message', trans('texts.applied_payment'));
                 return Redirect::to('view/' . $invitation->invitation_key);
             } else {
                 $this->error('offsite', $response->getMessage(), $accountGateway);
                 return Redirect::to('view/' . $invitation->invitation_key);
             }
         } else {
             $payment = $this->paymentService->createPayment($invitation, $token, $payerId);
             Session::flash('message', trans('texts.applied_payment'));
             return Redirect::to('view/' . $invitation->invitation_key);
         }
     } catch (\Exception $e) {
         $this->error('Offsite-uncaught', false, $accountGateway, $e);
         return Redirect::to('view/' . $invitation->invitation_key);
     }
 }
 /**
  * @param bool $invitationKey
  * @param mixed $gatewayTypeAlias
  * @return \Illuminate\Http\RedirectResponse
  */
 public function offsitePayment($invitationKey = false, $gatewayTypeAlias = false)
 {
     $invitationKey = $invitationKey ?: Session::get('invitation_key');
     $invitation = Invitation::with('invoice.invoice_items', 'invoice.client.currency', 'invoice.client.account.account_gateways.gateway')->where('invitation_key', '=', $invitationKey)->firstOrFail();
     if (!$gatewayTypeAlias) {
         $gatewayTypeId = Session::get($invitation->id . 'gateway_type');
     } elseif ($gatewayTypeAlias != GATEWAY_TYPE_TOKEN) {
         $gatewayTypeId = GatewayType::getIdFromAlias($gatewayTypeAlias);
     } else {
         $gatewayTypeId = $gatewayTypeAlias;
     }
     $paymentDriver = $invitation->account->paymentDriver($invitation, $gatewayTypeId);
     if ($error = Input::get('error_description') ?: Input::get('error')) {
         return $this->error($paymentDriver, $error);
     }
     try {
         if ($paymentDriver->completeOffsitePurchase(Input::all())) {
             Session::flash('message', trans('texts.applied_payment'));
         }
         return redirect()->to($invitation->getLink());
     } catch (Exception $exception) {
         return $this->error($paymentDriver, $exception);
     }
 }
예제 #25
0
 public function offsite_payment()
 {
     $payerId = Request::query('PayerID');
     $token = Request::query('token');
     if (!$token) {
         $token = Session::pull('transaction_reference');
     }
     if (!$token) {
         return redirect(NINJA_WEB_URL);
     }
     $invitation = Invitation::with('invoice.client.currency', 'invoice.client.account.account_gateways.gateway')->where('transaction_reference', '=', $token)->firstOrFail();
     $invoice = $invitation->invoice;
     $accountGateway = $invoice->client->account->getGatewayByType(Session::get('payment_type'));
     $gateway = self::createGateway($accountGateway);
     try {
         if (method_exists($gateway, 'completePurchase')) {
             $details = self::getPaymentDetails($invitation);
             $response = $gateway->completePurchase($details)->send();
             $ref = $response->getTransactionReference();
             if ($response->isSuccessful()) {
                 $payment = self::createPayment($invitation, $ref, $payerId);
                 Session::flash('message', trans('texts.applied_payment'));
                 return Redirect::to('view/' . $invitation->invitation_key);
             } else {
                 $errorMessage = trans('texts.payment_error') . "\n\n" . $response->getMessage();
                 Session::flash('error', $errorMessage);
                 Utils::logError($errorMessage);
                 return Redirect::to('view/' . $invitation->invitation_key);
             }
         } else {
             $payment = self::createPayment($invitation, $token, $payerId);
             Session::flash('message', trans('texts.applied_payment'));
             return Redirect::to('view/' . $invitation->invitation_key);
         }
     } catch (\Exception $e) {
         $errorMessage = trans('texts.payment_error');
         Session::flash('error', $errorMessage);
         Utils::logError($errorMessage . "\n\n" . $e->getMessage());
         return Redirect::to('view/' . $invitation->invitation_key);
     }
 }
예제 #26
0
 private function save($publicId = null)
 {
     $action = Input::get('action');
     $entityType = Input::get('entityType');
     if (in_array($action, ['archive', 'delete', 'mark', 'restore'])) {
         return InvoiceController::bulk($entityType);
     }
     $input = json_decode(Input::get('data'));
     $invoice = $input->invoice;
     if ($errors = $this->invoiceRepo->getErrors($invoice)) {
         Session::flash('error', trans('texts.invoice_error'));
         return Redirect::to("{$entityType}s/create")->withInput()->withErrors($errors);
     } else {
         $this->taxRateRepo->save($input->tax_rates);
         $clientData = (array) $invoice->client;
         $client = $this->clientRepo->save($invoice->client->public_id, $clientData);
         $invoiceData = (array) $invoice;
         $invoiceData['client_id'] = $client->id;
         $invoice = $this->invoiceRepo->save($publicId, $invoiceData, $entityType);
         $account = Auth::user()->account;
         if ($account->invoice_taxes != $input->invoice_taxes || $account->invoice_item_taxes != $input->invoice_item_taxes || $account->invoice_design_id != $input->invoice->invoice_design_id) {
             $account->invoice_taxes = $input->invoice_taxes;
             $account->invoice_item_taxes = $input->invoice_item_taxes;
             $account->invoice_design_id = $input->invoice->invoice_design_id;
             $account->save();
         }
         $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();
             }
         }
         $message = trans($publicId ? "texts.updated_{$entityType}" : "texts.created_{$entityType}");
         if ($input->invoice->client->public_id == '-1') {
             $message = $message . ' ' . trans('texts.and_created_client');
             $url = URL::to('clients/' . $client->public_id);
             Utils::trackViewed($client->getDisplayName(), ENTITY_CLIENT, $url);
         }
         $pdfUpload = Input::get('pdfupload');
         if (!empty($pdfUpload) && strpos($pdfUpload, 'data:application/pdf;base64,') === 0) {
             $this->storePDF(Input::get('pdfupload'), $invoice);
         }
         if ($action == 'clone') {
             return $this->cloneInvoice($publicId);
         } elseif ($action == 'convert') {
             return $this->convertQuote($publicId);
         } elseif ($action == 'email') {
             if (Auth::user()->confirmed && !Auth::user()->isDemo()) {
                 if ($invoice->is_recurring) {
                     if ($invoice->shouldSendToday()) {
                         $invoice = $this->invoiceRepo->createRecurringInvoice($invoice);
                         $response = $this->mailer->sendInvoice($invoice);
                     } else {
                         $response = trans('texts.recurring_too_soon');
                     }
                 } else {
                     $response = $this->mailer->sendInvoice($invoice);
                 }
                 if ($response === true) {
                     $message = trans("texts.emailed_{$entityType}");
                     Session::flash('message', $message);
                 } else {
                     Session::flash('error', $response);
                 }
             } else {
                 $errorMessage = trans(Auth::user()->registered ? 'texts.confirmation_required' : 'texts.registration_required');
                 Session::flash('error', $errorMessage);
                 Session::flash('message', $message);
             }
         } else {
             Session::flash('message', $message);
         }
         $url = "{$entityType}s/" . $invoice->public_id . '/edit';
         return Redirect::to($url);
     }
 }
 public function createRecurringInvoice($recurInvoice)
 {
     $recurInvoice->load('account.timezone', 'invoice_items', 'client', 'user');
     if ($recurInvoice->client->deleted_at) {
         return false;
     }
     if (!$recurInvoice->user->confirmed) {
         return false;
     }
     if (!$recurInvoice->shouldSendToday()) {
         return false;
     }
     $invoice = Invoice::createNew($recurInvoice);
     $invoice->client_id = $recurInvoice->client_id;
     $invoice->recurring_invoice_id = $recurInvoice->id;
     $invoice->invoice_number = $recurInvoice->account->getNextInvoiceNumber(false, 'R');
     $invoice->amount = $recurInvoice->amount;
     $invoice->balance = $recurInvoice->amount;
     $invoice->invoice_date = date_create()->format('Y-m-d');
     $invoice->discount = $recurInvoice->discount;
     $invoice->po_number = $recurInvoice->po_number;
     $invoice->public_notes = Utils::processVariables($recurInvoice->public_notes);
     $invoice->terms = Utils::processVariables($recurInvoice->terms);
     $invoice->invoice_footer = Utils::processVariables($recurInvoice->invoice_footer);
     $invoice->tax_name = $recurInvoice->tax_name;
     $invoice->tax_rate = $recurInvoice->tax_rate;
     $invoice->invoice_design_id = $recurInvoice->invoice_design_id;
     $invoice->custom_value1 = $recurInvoice->custom_value1;
     $invoice->custom_value2 = $recurInvoice->custom_value2;
     $invoice->custom_taxes1 = $recurInvoice->custom_taxes1;
     $invoice->custom_taxes2 = $recurInvoice->custom_taxes2;
     $invoice->is_amount_discount = $recurInvoice->is_amount_discount;
     if ($invoice->client->payment_terms != 0) {
         $days = $invoice->client->payment_terms;
         if ($days == -1) {
             $days = 0;
         }
         $invoice->due_date = date_create()->modify($days . ' day')->format('Y-m-d');
     }
     $invoice->save();
     foreach ($recurInvoice->invoice_items as $recurItem) {
         $item = InvoiceItem::createNew($recurItem);
         $item->product_id = $recurItem->product_id;
         $item->qty = $recurItem->qty;
         $item->cost = $recurItem->cost;
         $item->notes = Utils::processVariables($recurItem->notes);
         $item->product_key = Utils::processVariables($recurItem->product_key);
         $item->tax_name = $recurItem->tax_name;
         $item->tax_rate = $recurItem->tax_rate;
         $invoice->invoice_items()->save($item);
     }
     foreach ($recurInvoice->invitations as $recurInvitation) {
         $invitation = Invitation::createNew($recurInvitation);
         $invitation->contact_id = $recurInvitation->contact_id;
         $invitation->invitation_key = str_random(RANDOM_KEY_LENGTH);
         $invoice->invitations()->save($invitation);
     }
     $recurInvoice->last_sent_date = Carbon::now()->toDateTimeString();
     $recurInvoice->save();
     return $invoice;
 }
예제 #28
0
 public function offsite_payment()
 {
     $payerId = Request::query('PayerID');
     $token = Request::query('token');
     if (!$token) {
         $token = Session::pull('transaction_reference');
     }
     if (!$token) {
         return redirect(NINJA_WEB_URL);
     }
     $invitation = Invitation::with('invoice.client.currency', 'invoice.client.account.account_gateways.gateway')->where('transaction_reference', '=', $token)->firstOrFail();
     $invoice = $invitation->invoice;
     $client = $invoice->client;
     $account = $client->account;
     if ($payerId) {
         $paymentType = PAYMENT_TYPE_PAYPAL;
     } else {
         $paymentType = Session::get($invitation->id . 'payment_type');
     }
     if (!$paymentType) {
         $this->error('No-Payment-Type', false, false);
         return Redirect::to($invitation->getLink());
     }
     $accountGateway = $account->getGatewayByType($paymentType);
     $gateway = $this->paymentService->createGateway($accountGateway);
     // Check for Dwolla payment error
     if ($accountGateway->isGateway(GATEWAY_DWOLLA) && Input::get('error')) {
         $this->error('Dwolla', Input::get('error_description'), $accountGateway);
         return Redirect::to($invitation->getLink());
     }
     // PayFast transaction referencce
     if ($accountGateway->isGateway(GATEWAY_PAYFAST) && Request::has('pt')) {
         $token = Request::query('pt');
     }
     try {
         if (method_exists($gateway, 'completePurchase') && !$accountGateway->isGateway(GATEWAY_TWO_CHECKOUT) && !$accountGateway->isGateway(GATEWAY_CHECKOUT_COM)) {
             $details = $this->paymentService->getPaymentDetails($invitation, $accountGateway);
             $response = $this->paymentService->completePurchase($gateway, $accountGateway, $details, $token);
             $ref = $response->getTransactionReference() ?: $token;
             if ($response->isCancelled()) {
                 // do nothing
             } elseif ($response->isSuccessful()) {
                 $payment = $this->paymentService->createPayment($invitation, $accountGateway, $ref, $payerId);
                 Session::flash('message', trans('texts.applied_payment'));
             } else {
                 $this->error('offsite', $response->getMessage(), $accountGateway);
             }
             return Redirect::to($invitation->getLink());
         } else {
             $payment = $this->paymentService->createPayment($invitation, $accountGateway, $token, $payerId);
             Session::flash('message', trans('texts.applied_payment'));
             return Redirect::to($invitation->getLink());
         }
     } catch (\Exception $e) {
         $this->error('Offsite-uncaught', false, $accountGateway, $e);
         return Redirect::to($invitation->getLink());
     }
 }
예제 #29
0
 public function store()
 {
     $data = Input::all();
     $error = null;
     if (isset($data['id']) || isset($data['public_id'])) {
         die("We don't yet support updating invoices");
     }
     if (isset($data['email'])) {
         $client = Client::scope()->whereHas('contacts', function ($query) use($data) {
             $query->where('email', '=', $data['email']);
         })->first();
         if (!$client) {
             $clientData = ['contact' => ['email' => $data['email']]];
             foreach (['name', 'private_notes'] as $field) {
                 if (isset($data[$field])) {
                     $clientData[$field] = $data[$field];
                 }
             }
             foreach (['first_name', 'last_name'] as $field) {
                 if (isset($data[$field])) {
                     $clientData[$field] = $data[$field];
                 }
             }
             $error = $this->clientRepo->getErrors($clientData);
             if (!$error) {
                 $client = $this->clientRepo->save($clientData);
             }
         }
     } else {
         if (isset($data['client_id'])) {
             $client = Client::scope($data['client_id'])->first();
         }
     }
     // check if the invoice number is set and unique
     if (!isset($data['invoice_number']) && !isset($data['id'])) {
         // do nothing... invoice number will be set automatically
     } else {
         if (isset($data['invoice_number'])) {
             $invoice = Invoice::scope()->where('invoice_number', '=', $data['invoice_number'])->first();
             if ($invoice) {
                 $error = trans('validation.unique', ['attribute' => 'texts.invoice_number']);
             }
         }
     }
     if (!$error) {
         if (!isset($data['client_id']) && !isset($data['email'])) {
             $error = trans('validation.', ['attribute' => 'client_id or email']);
         } else {
             if (!$client) {
                 $error = trans('validation.not_in', ['attribute' => 'client_id']);
             }
         }
     }
     if ($error) {
         $response = json_encode($error, JSON_PRETTY_PRINT);
     } else {
         $data = self::prepareData($data, $client);
         $data['client_id'] = $client->id;
         $invoice = $this->invoiceRepo->save($data);
         if (!isset($data['id'])) {
             $invitation = Invitation::createNew();
             $invitation->invoice_id = $invoice->id;
             $invitation->contact_id = $client->contacts[0]->id;
             $invitation->invitation_key = str_random(RANDOM_KEY_LENGTH);
             $invitation->save();
         }
         if (isset($data['email_invoice']) && $data['email_invoice']) {
             $this->mailer->sendInvoice($invoice);
         }
         // prepare the return data
         $invoice = Invoice::scope($invoice->public_id)->with('client', 'invoice_items', 'invitations')->first();
         $invoice = Utils::remapPublicIds([$invoice]);
         $response = json_encode($invoice, JSON_PRETTY_PRINT);
     }
     $headers = Utils::getApiHeaders();
     return Response::make($response, $error ? 400 : 200, $headers);
 }
예제 #30
0
 public function approve($invitationKey)
 {
     $invitation = Invitation::with('invoice.invoice_items', 'invoice.invitations')->where('invitation_key', '=', $invitationKey)->firstOrFail();
     $invoice = $invitation->invoice;
     $invitationKey = $this->invoiceService->approveQuote($invoice, $invitation);
     Session::flash('message', trans('texts.quote_is_approved'));
     return Redirect::to("view/{$invitationKey}");
 }