diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/app/commands/SendRecurringInvoices.php b/app/commands/SendRecurringInvoices.php index 4829555bf22d..93e4a3837195 100755 --- a/app/commands/SendRecurringInvoices.php +++ b/app/commands/SendRecurringInvoices.php @@ -3,7 +3,7 @@ use Illuminate\Console\Command; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputArgument; -use Ninja\Mailers\ContactMailer as Mailer; +use ninja\mailers\ContactMailer as Mailer; class SendRecurringInvoices extends Command { diff --git a/app/config/mail.php b/app/config/mail.php index 82ce8f4c0b45..61c8c5454cf6 100755 --- a/app/config/mail.php +++ b/app/config/mail.php @@ -54,7 +54,7 @@ return array( | */ - 'from' => array('address' => '', 'name' => ''), + 'from' => array('address' => 'contact@invoiceninja.com', 'name' => 'Invoice Ninja'), /* |-------------------------------------------------------------------------- diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index f7cf4ca319fe..5e1c19f934f2 100755 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -389,11 +389,17 @@ class AccountController extends \BaseController { $account->date_format_id = Input::get('date_format_id') ? Input::get('date_format_id') : null; $account->datetime_format_id = Input::get('datetime_format_id') ? Input::get('datetime_format_id') : null; - Event::fire('user.refresh'); - $account->invoice_terms = Input::get('invoice_terms'); $account->save(); + $user = Auth::user(); + $user->notify_sent = Input::get('notify_sent'); + $user->notify_viewed = Input::get('notify_viewed'); + $user->notify_paid = Input::get('notify_paid'); + $user->save(); + + Event::fire('user.refresh'); + if ($gatewayId) { $accountGateway = new AccountGateway; diff --git a/app/controllers/InvoiceController.php b/app/controllers/InvoiceController.php index 07470dc42052..be8bd6d94029 100755 --- a/app/controllers/InvoiceController.php +++ b/app/controllers/InvoiceController.php @@ -1,16 +1,22 @@ mailer = $mailer; + $this->invoiceRepo = $invoiceRepo; + $this->clientRepo = $clientRepo; } public function index() @@ -32,30 +38,7 @@ class InvoiceController extends \BaseController { public function getDatatable($clientPublicId = null) { - $query = DB::table('invoices') - ->join('clients', 'clients.id', '=','invoices.client_id') - ->join('invoice_statuses', 'invoice_statuses.id', '=', 'invoices.invoice_status_id') - ->where('invoices.account_id', '=', Auth::user()->account_id) - ->where('invoices.deleted_at', '=', null) - ->where('clients.deleted_at', '=', null) - ->where('invoices.is_recurring', '=', false) - ->select('clients.public_id as client_public_id', 'invoice_number', 'clients.name as client_name', 'invoices.public_id', 'amount', 'invoices.balance', 'invoice_date', 'due_date', 'invoice_statuses.name as invoice_status_name'); - - if ($clientPublicId) { - $query->where('clients.public_id', '=', $clientPublicId); - } - - $filter = Input::get('sSearch'); - if ($filter) - { - $query->where(function($query) use ($filter) - { - $query->where('clients.name', 'like', '%'.$filter.'%') - ->orWhere('invoices.invoice_number', 'like', '%'.$filter.'%') - ->orWhere('invoice_statuses.name', 'like', '%'.$filter.'%'); - }); - } - + $query = $this->invoiceRepo->getInvoices(Auth::user()->account_id, $clientPublicId, Input::get('sSearch')); $table = Datatable::query($query); if (!$clientPublicId) { @@ -93,28 +76,7 @@ class InvoiceController extends \BaseController { public function getRecurringDatatable($clientPublicId = null) { - $query = DB::table('invoices') - ->join('clients', 'clients.id', '=','invoices.client_id') - ->join('frequencies', 'frequencies.id', '=', 'invoices.frequency_id') - ->where('invoices.account_id', '=', Auth::user()->account_id) - ->where('invoices.deleted_at', '=', null) - ->where('invoices.is_recurring', '=', true) - ->select('clients.public_id as client_public_id', 'clients.name as client_name', 'invoices.public_id', 'amount', 'frequencies.name as frequency', 'start_date', 'end_date'); - - if ($clientPublicId) { - $query->where('clients.public_id', '=', $clientPublicId); - } - - $filter = Input::get('sSearch'); - if ($filter) - { - $query->where(function($query) use ($filter) - { - $query->where('clients.name', 'like', '%'.$filter.'%') - ->orWhere('invoices.invoice_number', 'like', '%'.$filter.'%'); - }); - } - + $query = $this->invoiceRepo->getRecurringInvoices(Auth::user()->account_id, $clientPublicId, Input::get('sSearch')); $table = Datatable::query($query); if (!$clientPublicId) { @@ -421,131 +383,40 @@ class InvoiceController extends \BaseController { $inputClient = $input->client; $inputClient->name = trim($inputClient->name); - if (!$inputClient->name) { + if (!$inputClient->name) + { return Redirect::to('invoices/create') ->withInput(); - } else { - - $clientPublicId = $input->client->public_id; + } + else + { + $clientData = (array) $input->client; + $client = $this->clientRepo->save($input->client->public_id, $clientData); - if ($clientPublicId == "-1") - { - $client = Client::createNew(); - $contact = Contact::createNew(); - $contact->is_primary = true; - } - else - { - $client = Client::scope($clientPublicId)->with('contacts')->firstOrFail(); - $contact = $client->contacts()->where('is_primary', '=', true)->firstOrFail(); - } - - $inputClient = $input->client; - $client->name = trim($inputClient->name); - $client->work_phone = trim($inputClient->work_phone); - $client->address1 = trim($inputClient->address1); - $client->address2 = trim($inputClient->address2); - $client->city = trim($inputClient->city); - $client->state = trim($inputClient->state); - $client->postal_code = trim($inputClient->postal_code); - $client->country_id = $inputClient->country_id ? $inputClient->country_id : null; - $client->notes = trim($inputClient->notes); - $client->client_size_id = $inputClient->client_size_id ? $inputClient->client_size_id : null; - $client->client_industry_id = $inputClient->client_industry_id ? $inputClient->client_industry_id : null; - $client->website = trim($inputClient->website); - $client->save(); - - $isPrimary = true; - $contacts = []; - $contactIds = []; - $sendInvoiceIds = []; - - foreach ($inputClient->contacts as $contact) - { - if (isset($contact->public_id) && $contact->public_id) - { - $record = Contact::scope($contact->public_id)->firstOrFail(); - } - else - { - $record = Contact::createNew(); - } - - $record->email = trim($contact->email); - $record->first_name = trim($contact->first_name); - $record->last_name = trim($contact->last_name); - $record->phone = trim($contact->phone); - $record->is_primary = $isPrimary; - $isPrimary = false; - - $client->contacts()->save($record); - $contacts[] = $record; - $contactIds[] = $record->public_id; - - if ($contact->send_invoice) - { - $sendInvoiceIds[] = $record->id; - } - } - - foreach ($client->contacts as $contact) - { - if (!in_array($contact->public_id, $contactIds)) - { - $contact->forceDelete(); - } - } - - if ($publicId) { - $invoice = Invoice::scope($publicId)->firstOrFail(); - $invoice->invoice_items()->forceDelete(); - } else { - $invoice = Invoice::createNew(); - } - - $invoice->client_id = $client->id; - $invoice->discount = $input->discount; - $invoice->invoice_number = trim($input->invoice_number); - $invoice->invoice_date = Utils::toSqlDate($input->invoice_date); - $invoice->due_date = Utils::toSqlDate($input->due_date); - - $invoice->is_recurring = $input->is_recurring; - $invoice->frequency_id = $input->frequency_id ? $input->frequency_id : 0; - $invoice->start_date = Utils::toSqlDate($input->start_date); - $invoice->end_date = Utils::toSqlDate($input->end_date); - $invoice->terms = $input->terms; - $invoice->po_number = $input->po_number; - - - $client->invoices()->save($invoice); - - $items = $input->invoice_items; - $total = 0; - - foreach ($items as $item) - { - if (!isset($item->cost)) { - $item->cost = 0; - } - if (!isset($item->qty)) { - $item->qty = 0; - } - - $total += floatval($item->qty) * floatval($item->cost); - } + $invoiceData = (array) $input; + $invoiceData['client_id'] = $client->id; + $invoice = $this->invoiceRepo->save($publicId, $invoiceData); if ($action == 'email' && $invoice->invoice_status_id == INVOICE_STATUS_DRAFT) { $invoice->invoice_status_id = INVOICE_STATUS_SENT; - $client->balance = $invoice->client->balance + $invoice->amount; + $client->balance = $client->balance + $invoice->amount; $client->save(); } - $invoice->amount = $total; - $invoice->save(); + $client->load('contacts'); + $sendInvoiceIds = []; - foreach ($contacts as $contact) + foreach ($client->contacts as $contact) + { + if ($contact->send_invoice) + { + $sendInvoiceIds[] = $contact->id; + } + } + + foreach ($client->contacts as $contact) { $invitation = Invitation::scope()->whereContactId($contact->id)->whereInvoiceId($invoice->id)->first(); @@ -563,56 +434,25 @@ class InvoiceController extends \BaseController { } } - foreach ($items as $item) + $message = ''; + if ($input->client->public_id == '-1') { - if (!$item->cost && !$item->qty && !$item->product_key && !$item->notes) - { - continue; - } - - if ($item->product_key) - { - $product = Product::findProductByKey(trim($item->product_key)); - - if (!$product) - { - $product = Product::createNew(); - $product->product_key = trim($item->product_key); - } - - /* - $product->notes = $item->notes; - $product->cost = $item->cost; - $product->qty = $item->qty; - */ - - $product->save(); - } - - $invoiceItem = InvoiceItem::createNew(); - $invoiceItem->product_id = isset($product) ? $product->id : null; - $invoiceItem->product_key = trim($item->product_key); - $invoiceItem->notes = trim($item->notes); - $invoiceItem->cost = floatval($item->cost); - $invoiceItem->qty = floatval($item->qty); - - $invoice->invoice_items()->save($invoiceItem); + $message = ' and created client'; + $url = URL::to('clients/' . $client->public_id); + Utils::trackViewed($client->name, ENTITY_CLIENT, $url); } - - /* - */ - - $message = $clientPublicId == "-1" ? ' and created client' : ''; + if ($action == 'clone') { return InvoiceController::cloneInvoice($publicId); } else if ($action == 'email') { - $this->mailer->sendInvoice($invoice); - + $this->mailer->sendInvoice($invoice); Session::flash('message', 'Successfully emailed invoice'.$message); - } else { + } + else + { Session::flash('message', 'Successfully saved invoice'.$message); } diff --git a/app/database/migrations/2013_11_05_180133_confide_setup_users_table.php b/app/database/migrations/2013_11_05_180133_confide_setup_users_table.php index fbb4d3a8062c..1ca9ff22e518 100755 --- a/app/database/migrations/2013_11_05_180133_confide_setup_users_table.php +++ b/app/database/migrations/2013_11_05_180133_confide_setup_users_table.php @@ -68,7 +68,8 @@ class ConfideSetupUsersTable extends Migration { Schema::create('date_formats', function($t) { $t->increments('id'); - $t->string('format'); + $t->string('format'); + $t->string('picker_format'); $t->string('label'); }); @@ -149,6 +150,10 @@ class ConfideSetupUsersTable extends Migration { $t->boolean('confirmed')->default(false); $t->integer('theme_id'); + $t->boolean('notify_sent')->default(false); + $t->boolean('notify_viewed')->default(false); + $t->boolean('notify_paid')->default(true); + $t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade'); $t->unsignedInteger('public_id'); @@ -220,6 +225,7 @@ class ConfideSetupUsersTable extends Migration { $t->softDeletes(); $t->boolean('is_primary'); + $t->boolean('send_invoice'); $t->string('first_name'); $t->string('last_name'); $t->string('email'); diff --git a/app/database/seeds/ConstantsSeeder.php b/app/database/seeds/ConstantsSeeder.php index 5b3a678f3764..50ace732c282 100755 --- a/app/database/seeds/ConstantsSeeder.php +++ b/app/database/seeds/ConstantsSeeder.php @@ -72,9 +72,16 @@ class ConstantsSeeder extends Seeder DatetimeFormat::create(array('format' => 'F j, Y, g:i a', 'label' => 'March 10, 2013, 6:15 pm')); DatetimeFormat::create(array('format' => 'D M jS, Y g:ia', 'label' => 'Mon March 10th, 2013, 6:15 pm')); - DateFormat::create(array('format' => 'F j, Y', 'label' => 'March 10, 2013')); - DateFormat::create(array('format' => 'D M jS', 'label' => 'Mon March 10th, 2013')); - + DateFormat::create(array('format' => 'F j, Y', 'picker_format' => 'MM d, yyyy', 'label' => 'March 10, 2013')); + DateFormat::create(array('format' => 'D M jS, Y', 'picker_format' => 'D MM d, yyyy', 'label' => 'Mon March 10th, 2013')); + + /* + d, dd: Numeric date, no leading zero and leading zero, respectively. Eg, 5, 05. + D, DD: Abbreviated and full weekday names, respectively. Eg, Mon, Monday. + m, mm: Numeric month, no leading zero and leading zero, respectively. Eg, 7, 07. + M, MM: Abbreviated and full month names, respectively. Eg, Jan, January + yy, yyyy: 2- and 4-digit years, respectively. Eg, 12, 2012.) + */ $gateways = [ array('name'=>'Authorize.Net AIM', 'provider'=>'AuthorizeNet_AIM'), diff --git a/app/handlers/InvoiceEventHandler.php b/app/handlers/InvoiceEventHandler.php new file mode 100755 index 000000000000..bbce7793b174 --- /dev/null +++ b/app/handlers/InvoiceEventHandler.php @@ -0,0 +1,46 @@ +mailer = $mailer; + } + + public function subscribe($events) + { + $events->listen('invoice.sent', 'InvoiceEventHandler@onSent'); + $events->listen('invoice.viewed', 'InvoiceEventHandler@onViewed'); + $events->listen('invoice.paid', 'InvoiceEventHandler@onPaid'); + } + + public function onSent($invoice) + { + $this->sendNotifications($invoice, 'sent'); + } + + public function onViewed($invoice) + { + + } + + public function onPaid($invoice) + { + + } + + private function sendNotifications($invoice, $type) + { + foreach ($invoice->account->users as $user) + { + if ($user->{'notify_' . $type}) + { + $this->mailer->sendNotification($user, $invoice, $type); + } + } + } +} \ No newline at end of file diff --git a/app/handlers/UserEventHandler.php b/app/handlers/UserEventHandler.php index af8095341121..8964b3484a33 100755 --- a/app/handlers/UserEventHandler.php +++ b/app/handlers/UserEventHandler.php @@ -31,6 +31,7 @@ class UserEventHandler Session::put(SESSION_TIMEZONE, $account->timezone ? $account->timezone->name : DEFAULT_TIMEZONE); Session::put(SESSION_DATE_FORMAT, $account->date_format ? $account->date_format->format : DEFAULT_DATE_FORMAT); + Session::put(SESSION_DATE_PICKER_FORMAT, $account->date_format ? $account->date_format->picker_format : DEFAULT_DATE_PICKER_FORMAT); Session::put(SESSION_DATETIME_FORMAT, $account->datetime_format ? $account->datetime_format->format : DEFAULT_DATETIME_FORMAT); } } \ No newline at end of file diff --git a/app/libraries/entity.php b/app/libraries/entity.php old mode 100644 new mode 100755 diff --git a/app/libraries/utils.php b/app/libraries/utils.php index 55b0ae907162..6b727307c32d 100755 --- a/app/libraries/utils.php +++ b/app/libraries/utils.php @@ -92,7 +92,13 @@ class Utils return null; } - return DateTime::createFromFormat('m/d/Y', $date); + /* + $timezone = Session::get(SESSION_TIMEZONE, DEFAULT_TIMEZONE); + $format = Session::get(SESSION_DATE_FORMAT, DEFAULT_DATE_FORMAT); + return DateTime::createFromFormat($format, $date, new DateTimeZone($timezone)); + */ + + return DateTime::createFromFormat('Y-m-d', $date); } public static function fromSqlDate($date) @@ -102,12 +108,23 @@ class Utils return ''; } - return DateTime::createFromFormat('Y-m-d', $date)->format('m/d/Y'); + /* + $timezone = Session::get(SESSION_TIMEZONE, DEFAULT_TIMEZONE); + return DateTime::createFromFormat('Y-m-d', $date, new DateTimeZone($timezone))->format($format); + */ + + $format = Session::get(SESSION_DATE_FORMAT, DEFAULT_DATE_FORMAT); + + return DateTime::createFromFormat('Y-m-d', $date)->format($format); } - public static function trackViewed($name, $type) + public static function trackViewed($name, $type, $url = false) { - $url = Request::url(); + if (!$url) + { + $url = Request::url(); + } + $viewed = Session::get(RECENTLY_VIEWED); if (!$viewed) diff --git a/app/mailers/UserMailer.php b/app/mailers/UserMailer.php deleted file mode 100755 index e69de29bb2d1..000000000000 diff --git a/app/models/Invitation.php b/app/models/Invitation.php old mode 100644 new mode 100755 diff --git a/app/mailers/ContactMailer.php b/app/ninja/mailers/ContactMailer.php similarity index 88% rename from app/mailers/ContactMailer.php rename to app/ninja/mailers/ContactMailer.php index 19714d596b57..e7bfaf0866af 100755 --- a/app/mailers/ContactMailer.php +++ b/app/ninja/mailers/ContactMailer.php @@ -1,4 +1,4 @@ -invoice_status_id = INVOICE_STATUS_SENT; $invoice->save(); } + + \Event::fire('invoice.sent', $invoice); } } \ No newline at end of file diff --git a/app/mailers/Mailer.php b/app/ninja/mailers/Mailer.php similarity index 71% rename from app/mailers/Mailer.php rename to app/ninja/mailers/Mailer.php index 0ec95884710e..4452e97760e4 100755 --- a/app/mailers/Mailer.php +++ b/app/ninja/mailers/Mailer.php @@ -1,4 +1,4 @@ - 'emails.'.$view.'_text' ]; - Mail::queue($views, $data, function($message) use($email, $subject) + Mail::queue($views, $data, function($message) use ($email, $subject) { $message->to($email)->subject($subject); }); diff --git a/app/ninja/mailers/UserMailer.php b/app/ninja/mailers/UserMailer.php new file mode 100755 index 000000000000..5331d77a818c --- /dev/null +++ b/app/ninja/mailers/UserMailer.php @@ -0,0 +1,23 @@ +email) + { + return; + } + + $view = 'invoice'; + //$data = array('link' => URL::to('view') . '/' . $invoice->invoice_key); + $data = []; + $subject = 'Notification - Invoice ' . $type; + + $this->sendTo($user->email, $subject, $view, $data); + } +} \ No newline at end of file diff --git a/app/ninja/repositories/ClientRepository.php b/app/ninja/repositories/ClientRepository.php new file mode 100755 index 000000000000..8cd152ee173d --- /dev/null +++ b/app/ninja/repositories/ClientRepository.php @@ -0,0 +1,74 @@ +is_primary = true; + } + else + { + $client = Client::scope($publicId)->with('contacts')->firstOrFail(); + $contact = $client->contacts()->where('is_primary', '=', true)->firstOrFail(); + } + + $client->name = trim($data['name']); + $client->work_phone = trim($data['work_phone']); + $client->address1 = trim($data['address1']); + $client->address2 = trim($data['address2']); + $client->city = trim($data['city']); + $client->state = trim($data['state']); + $client->postal_code = trim($data['postal_code']); + $client->country_id = $data['country_id'] ? $data['country_id'] : null; + $client->notes = trim($data['notes']); + $client->client_size_id = $data['client_size_id'] ? $data['client_size_id'] : null; + $client->client_industry_id = $data['client_industry_id'] ? $data['client_industry_id'] : null; + $client->website = trim($data['website']); + $client->save(); + + $isPrimary = true; + $contactIds = []; + + foreach ($data['contacts'] as $record) + { + $record = (array) $record; + + if (isset($record['public_id']) && $record['public_id']) + { + $contact = Contact::scope($record['public_id'])->firstOrFail(); + } + else + { + $contact = Contact::createNew(); + } + + $contact->email = trim($record['email']); + $contact->first_name = trim($record['first_name']); + $contact->last_name = trim($record['last_name']); + $contact->phone = trim($record['phone']); + $contact->is_primary = $isPrimary; + $contact->send_invoice = $record['send_invoice']; + $isPrimary = false; + + $client->contacts()->save($contact); + $contactIds[] = $contact->public_id; + } + + foreach ($client->contacts as $contact) + { + if (!in_array($contact->public_id, $contactIds)) + { + $contact->forceDelete(); + } + } + + return $client; + } +} \ No newline at end of file diff --git a/app/ninja/repositories/InvoiceRepository.php b/app/ninja/repositories/InvoiceRepository.php new file mode 100755 index 000000000000..cbc43c6b5e3f --- /dev/null +++ b/app/ninja/repositories/InvoiceRepository.php @@ -0,0 +1,150 @@ +join('clients', 'clients.id', '=','invoices.client_id') + ->join('invoice_statuses', 'invoice_statuses.id', '=', 'invoices.invoice_status_id') + ->where('invoices.account_id', '=', $accountId) + ->where('invoices.deleted_at', '=', null) + ->where('clients.deleted_at', '=', null) + ->where('invoices.is_recurring', '=', false) + ->select('clients.public_id as client_public_id', 'invoice_number', 'clients.name as client_name', 'invoices.public_id', 'amount', 'invoices.balance', 'invoice_date', 'due_date', 'invoice_statuses.name as invoice_status_name'); + + if ($clientPublicId) + { + $query->where('clients.public_id', '=', $clientPublicId); + } + + if ($filter) + { + $query->where(function($query) use ($filter) + { + $query->where('clients.name', 'like', '%'.$filter.'%') + ->orWhere('invoices.invoice_number', 'like', '%'.$filter.'%') + ->orWhere('invoice_statuses.name', 'like', '%'.$filter.'%'); + }); + } + + return $query; + } + + public function getRecurringInvoices($accountId, $clientPublicId = false, $filter = false) + { + $query = \DB::table('invoices') + ->join('clients', 'clients.id', '=','invoices.client_id') + ->join('frequencies', 'frequencies.id', '=', 'invoices.frequency_id') + ->where('invoices.account_id', '=', $accountId) + ->where('invoices.deleted_at', '=', null) + ->where('invoices.is_recurring', '=', true) + ->select('clients.public_id as client_public_id', 'clients.name as client_name', 'invoices.public_id', 'amount', 'frequencies.name as frequency', 'start_date', 'end_date'); + + if ($clientPublicId) + { + $query->where('clients.public_id', '=', $clientPublicId); + } + + if ($filter) + { + $query->where(function($query) use ($filter) + { + $query->where('clients.name', 'like', '%'.$filter.'%') + ->orWhere('invoices.invoice_number', 'like', '%'.$filter.'%'); + }); + } + + return $query; + } + + public function save($publicId, $data) + { + if ($publicId) + { + $invoice = Invoice::scope($publicId)->firstOrFail(); + $invoice->invoice_items()->forceDelete(); + } + else + { + $invoice = Invoice::createNew(); + } + + $invoice->client_id = $data['client_id']; + $invoice->discount = $data['discount']; + $invoice->invoice_number = trim($data['invoice_number']); + $invoice->invoice_date = Utils::toSqlDate($data['invoice_date']); + $invoice->due_date = Utils::toSqlDate($data['due_date']); + + $invoice->is_recurring = $data['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->terms = trim($data['terms']); + $invoice->po_number = trim($data['po_number']); + + $total = 0; + + foreach ($data['invoice_items'] as $item) + { + if (!isset($item->cost)) + { + $item->cost = 0; + } + + if (!isset($item->qty)) + { + $item->qty = 0; + } + + $total += floatval($item->qty) * floatval($item->cost); + } + + $invoice->amount = $total; + $invoice->save(); + + foreach ($data['invoice_items'] as $item) + { + if (!$item->cost && !$item->qty && !$item->product_key && !$item->notes) + { + continue; + } + + if ($item->product_key) + { + $product = Product::findProductByKey(trim($item->product_key)); + + if (!$product) + { + $product = Product::createNew(); + $product->product_key = trim($item->product_key); + } + + /* + $product->notes = $item->notes; + $product->cost = $item->cost; + $product->qty = $item->qty; + */ + + $product->save(); + } + + $invoiceItem = InvoiceItem::createNew(); + $invoiceItem->product_id = isset($product) ? $product->id : null; + $invoiceItem->product_key = trim($item->product_key); + $invoiceItem->notes = trim($item->notes); + $invoiceItem->cost = floatval($item->cost); + $invoiceItem->qty = floatval($item->qty); + + $invoice->invoice_items()->save($invoiceItem); + $total += floatval($item->qty) * floatval($item->cost); + } + + return $invoice; + } +} diff --git a/app/routes.php b/app/routes.php index 767d28cc15b9..e85da0b2b53c 100755 --- a/app/routes.php +++ b/app/routes.php @@ -170,8 +170,10 @@ define('FREQUENCY_ANNUALLY', 7); define('SESSION_TIMEZONE', 'timezone'); define('SESSION_DATE_FORMAT', 'dateFormat'); +define('SESSION_DATE_PICKER_FORMAT', 'datePickerFormat'); define('SESSION_DATETIME_FORMAT', 'datetimeFormat'); define('DEFAULT_TIMEZONE', 'US/Eastern'); -define('DEFAULT_DATE_FORMAT', 'F j, Y'); +define('DEFAULT_DATE_FORMAT', 'M j, Y'); +define('DEFAULT_DATE_PICKER_FORMAT', 'yyyy-mm-dd'); define('DEFAULT_DATETIME_FORMAT', 'F j, Y, g:i a'); diff --git a/app/start/global.php b/app/start/global.php index 1f377f021b6e..1f458bbd736c 100755 --- a/app/start/global.php +++ b/app/start/global.php @@ -74,6 +74,7 @@ App::down(function() Event::subscribe('UserEventHandler'); +Event::subscribe('InvoiceEventHandler'); /* diff --git a/app/views/accounts/settings.blade.php b/app/views/accounts/settings.blade.php index fafe8f75558c..fb91eff3b6f3 100755 --- a/app/views/accounts/settings.blade.php +++ b/app/views/accounts/settings.blade.php @@ -5,6 +5,9 @@ {{ Former::open()->addClass('col-md-8 col-md-offset-2') }} {{ Former::populate($account) }} + {{ Former::populateField('notify_sent', Auth::user()->notify_sent) }} + {{ Former::populateField('notify_viewed', Auth::user()->notify_viewed) }} + {{ Former::populateField('notify_paid', Auth::user()->notify_paid) }} {{ Former::legend('Payment Gateway') }} @@ -44,6 +47,10 @@ {{ Former::select('datetime_format_id')->addOption('','')->label('Date/Time Format') ->fromQuery($datetimeFormats, 'label', 'id')->select($account->datetime_format_id) }} + {{ Former::legend('Notifications') }} + {{ Former::checkbox('notify_sent')->label(' ')->text('Email me when an invoice is sent') }} + {{ Former::checkbox('notify_viewed')->label(' ')->text('Email me when an invoice is viewed') }} + {{ Former::checkbox('notify_paid')->label(' ')->text('Email me when an invoice is paid') }} {{ Former::legend('Invoices') }} {{ Former::textarea('invoice_terms') }} diff --git a/app/views/credits/edit.blade.php b/app/views/credits/edit.blade.php index 54364fe02791..632ece24ebdd 100755 --- a/app/views/credits/edit.blade.php +++ b/app/views/credits/edit.blade.php @@ -29,7 +29,7 @@ {{ Former::select('client')->fromQuery($clients, 'name', 'public_id')->select($client ? $client->public_id : '')->addOption('', '')->addGroupClass('client-select') }} {{ Former::text('amount') }} - {{ Former::text('credit_date') }} + {{ Former::text('credit_date')->data_date_format(DEFAULT_DATE_PICKER_FORMAT) }}