1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-18 00:53:10 +01:00

Added timezone support

This commit is contained in:
Hillel Coren 2013-12-02 14:22:29 +02:00
parent 49800b394c
commit dd088d8668
15 changed files with 218 additions and 24 deletions

View File

@ -37,6 +37,8 @@ class AccountController extends \BaseController {
} }
Auth::login($user); Auth::login($user);
Session::put('tz', 'US/Eastern');
return Redirect::to('invoices/create'); return Redirect::to('invoices/create');
} }
@ -46,8 +48,9 @@ class AccountController extends \BaseController {
{ {
$account = Account::with('users')->find(Auth::user()->account_id); $account = Account::with('users')->find(Auth::user()->account_id);
$countries = Country::orderBy('name')->get(); $countries = Country::orderBy('name')->get();
$timezones = Timezone::orderBy('location')->get();
return View::make('accounts.details', array('account'=>$account, 'countries'=>$countries)); return View::make('accounts.details', array('account'=>$account, 'countries'=>$countries, 'timezones'=>$timezones));
} }
else if ($section == ACCOUNT_SETTINGS) else if ($section == ACCOUNT_SETTINGS)
{ {
@ -421,7 +424,8 @@ class AccountController extends \BaseController {
$account->city = Input::get('city'); $account->city = Input::get('city');
$account->state = Input::get('state'); $account->state = Input::get('state');
$account->postal_code = Input::get('postal_code'); $account->postal_code = Input::get('postal_code');
$account->country_id = Input::get('country_id'); $account->country_id = Input::get('country_id') ? Input::get('country_id') : null;
$account->timezone_id = Input::get('timezone_id') ? Input::get('timezone_id') : null;
$account->save(); $account->save();
$user = $account->users()->first(); $user = $account->users()->first();
@ -431,6 +435,11 @@ class AccountController extends \BaseController {
$user->phone = Input::get('phone'); $user->phone = Input::get('phone');
$user->save(); $user->save();
if (Input::get('timezone_id')) {
$timezone = Timezone::find(Input::get('timezone_id'));
Session::put('tz', $timezone->name);
}
/* Logo image file */ /* Logo image file */
if ($file = Input::file('logo')) if ($file = Input::file('logo'))
{ {

View File

@ -28,7 +28,7 @@ class ClientController extends \BaseController {
->addColumn('contact', function($model) { return $model->contacts[0]->getFullName(); }) ->addColumn('contact', function($model) { return $model->contacts[0]->getFullName(); })
->addColumn('balance', function($model) { return '$' . $model->balance; }) ->addColumn('balance', function($model) { return '$' . $model->balance; })
->addColumn('last_login', function($model) { return $model->contacts[0]->getLastLogin(); }) ->addColumn('last_login', function($model) { return $model->contacts[0]->getLastLogin(); })
->addColumn('date_created', function($model) { return $model->getDateCreated(); }) ->addColumn('date_created', function($model) { return $model->created_at->toFormattedDateString(); })
->addColumn('email', function($model) { return HTML::mailto($model->contacts[0]->email, $model->contacts[0]->email); }) ->addColumn('email', function($model) { return HTML::mailto($model->contacts[0]->email, $model->contacts[0]->email); })
->addColumn('phone', function($model) { return $model->contacts[0]->phone; }) ->addColumn('phone', function($model) { return $model->contacts[0]->phone; })
->addColumn('dropdown', function($model) ->addColumn('dropdown', function($model)

View File

@ -37,8 +37,8 @@ class InvoiceController extends \BaseController {
return $table->addColumn('total', function($model){ return '$' . money_format('%i', $model->getTotal()); }) return $table->addColumn('total', function($model){ return '$' . money_format('%i', $model->getTotal()); })
->addColumn('amount_due', function($model) { return '$' . money_format('%i', $model->getTotal()); }) ->addColumn('amount_due', function($model) { return '$' . money_format('%i', $model->getTotal()); })
->addColumn('invoice_date', function($model) { return (new Carbon($model->invoice_date))->toFormattedDateString(); }) ->addColumn('invoice_date', function($model) { return fromSqlDate($model->invoice_date); })
->addColumn('due_date', function($model) { return $model->due_date == '0000-00-00' ? '' : (new Carbon($model->due_date))->toFormattedDateString(); }) ->addColumn('due_date', function($model) { return fromSqlDate($model->due_date); })
->addColumn('status', function($model) { return $model->invoice_status->name; }) ->addColumn('status', function($model) { return $model->invoice_status->name; })
->addColumn('dropdown', function($model) ->addColumn('dropdown', function($model)
{ {
@ -61,13 +61,14 @@ class InvoiceController extends \BaseController {
public function view($key) public function view($key)
{ {
$invitation = Invitation::with('invoice.invoice_items', 'invoice.client.account.account_gateways')->where('key', '=', $key)->firstOrFail(); $invitation = Invitation::with('user', 'invoice.account', 'invoice.invoice_items', 'invoice.client.account.account_gateways')->where('key', '=', $key)->firstOrFail();
$contact = null;
$user = $invitation->user;
$invitation->viewed_date = new date('Y-m-d H:i:s'); $invitation->viewed_date = Carbon::now()->toDateTimeString();
$invitation->save(); $invitation->save();
Activity::log($invitation->invoice->client, ACTIVITY_TYPE_VIEW_INVOICE, $contact, $invitation); Activity::viewInvoice($invitation);
return View::make('invoices.view')->with('invoice', $invitation->invoice); return View::make('invoices.view')->with('invoice', $invitation->invoice);
} }
@ -320,9 +321,12 @@ class InvoiceController extends \BaseController {
$product->key = $item->product_key; $product->key = $item->product_key;
} }
/*
$product->notes = $item->notes; $product->notes = $item->notes;
$product->cost = $item->cost; $product->cost = $item->cost;
$product->qty = $item->qty; $product->qty = $item->qty;
*/
$product->save(); $product->save();
} }

View File

@ -26,6 +26,7 @@ class ConfideSetupUsersTable extends Migration {
Schema::dropIfExists('accounts'); Schema::dropIfExists('accounts');
Schema::dropIfExists('invoice_statuses'); Schema::dropIfExists('invoice_statuses');
Schema::dropIfExists('countries'); Schema::dropIfExists('countries');
Schema::dropIfExists('timezones');
Schema::create('countries', function($table) Schema::create('countries', function($table)
@ -46,10 +47,18 @@ class ConfideSetupUsersTable extends Migration {
$table->boolean('eea')->default(0); $table->boolean('eea')->default(0);
}); });
Schema::create('timezones', function($t)
{
$t->increments('id');
$t->string('name');
$t->string('location');
});
Schema::create('accounts', function($t) Schema::create('accounts', function($t)
{ {
$t->increments('id'); $t->increments('id');
$t->unsignedInteger('timezone_id')->nullable();
$t->timestamps(); $t->timestamps();
$t->softDeletes(); $t->softDeletes();
@ -65,6 +74,7 @@ class ConfideSetupUsersTable extends Migration {
$t->string('postal_code'); $t->string('postal_code');
$t->unsignedInteger('country_id')->nullable(); $t->unsignedInteger('country_id')->nullable();
$t->foreign('timezone_id')->references('id')->on('timezones');
$t->foreign('country_id')->references('id')->on('countries'); $t->foreign('country_id')->references('id')->on('countries');
}); });
@ -290,6 +300,7 @@ class ConfideSetupUsersTable extends Migration {
$t->unsignedInteger('payment_id'); $t->unsignedInteger('payment_id');
$t->unsignedInteger('invoice_id'); $t->unsignedInteger('invoice_id');
$t->unsignedInteger('credit_id'); $t->unsignedInteger('credit_id');
$t->unsignedInteger('invitation_id');
$t->text('message'); $t->text('message');
$t->integer('activity_type_id'); $t->integer('activity_type_id');
@ -324,6 +335,6 @@ class ConfideSetupUsersTable extends Migration {
Schema::dropIfExists('accounts'); Schema::dropIfExists('accounts');
Schema::dropIfExists('invoice_statuses'); Schema::dropIfExists('invoice_statuses');
Schema::dropIfExists('countries'); Schema::dropIfExists('countries');
Schema::dropIfExists('timezones');
} }
} }

View File

@ -75,5 +75,124 @@ class ConstantsSeeder extends Seeder
{ {
Gateway::create($gateway); Gateway::create($gateway);
} }
$timezones = array(
'Pacific/Midway' => "(GMT-11:00) Midway Island",
'US/Samoa' => "(GMT-11:00) Samoa",
'US/Hawaii' => "(GMT-10:00) Hawaii",
'US/Alaska' => "(GMT-09:00) Alaska",
'US/Pacific' => "(GMT-08:00) Pacific Time (US & Canada)",
'America/Tijuana' => "(GMT-08:00) Tijuana",
'US/Arizona' => "(GMT-07:00) Arizona",
'US/Mountain' => "(GMT-07:00) Mountain Time (US & Canada)",
'America/Chihuahua' => "(GMT-07:00) Chihuahua",
'America/Mazatlan' => "(GMT-07:00) Mazatlan",
'America/Mexico_City' => "(GMT-06:00) Mexico City",
'America/Monterrey' => "(GMT-06:00) Monterrey",
'Canada/Saskatchewan' => "(GMT-06:00) Saskatchewan",
'US/Central' => "(GMT-06:00) Central Time (US & Canada)",
'US/Eastern' => "(GMT-05:00) Eastern Time (US & Canada)",
'US/East-Indiana' => "(GMT-05:00) Indiana (East)",
'America/Bogota' => "(GMT-05:00) Bogota",
'America/Lima' => "(GMT-05:00) Lima",
'America/Caracas' => "(GMT-04:30) Caracas",
'Canada/Atlantic' => "(GMT-04:00) Atlantic Time (Canada)",
'America/La_Paz' => "(GMT-04:00) La Paz",
'America/Santiago' => "(GMT-04:00) Santiago",
'Canada/Newfoundland' => "(GMT-03:30) Newfoundland",
'America/Buenos_Aires' => "(GMT-03:00) Buenos Aires",
'Greenland' => "(GMT-03:00) Greenland",
'Atlantic/Stanley' => "(GMT-02:00) Stanley",
'Atlantic/Azores' => "(GMT-01:00) Azores",
'Atlantic/Cape_Verde' => "(GMT-01:00) Cape Verde Is.",
'Africa/Casablanca' => "(GMT) Casablanca",
'Europe/Dublin' => "(GMT) Dublin",
'Europe/Lisbon' => "(GMT) Lisbon",
'Europe/London' => "(GMT) London",
'Africa/Monrovia' => "(GMT) Monrovia",
'Europe/Amsterdam' => "(GMT+01:00) Amsterdam",
'Europe/Belgrade' => "(GMT+01:00) Belgrade",
'Europe/Berlin' => "(GMT+01:00) Berlin",
'Europe/Bratislava' => "(GMT+01:00) Bratislava",
'Europe/Brussels' => "(GMT+01:00) Brussels",
'Europe/Budapest' => "(GMT+01:00) Budapest",
'Europe/Copenhagen' => "(GMT+01:00) Copenhagen",
'Europe/Ljubljana' => "(GMT+01:00) Ljubljana",
'Europe/Madrid' => "(GMT+01:00) Madrid",
'Europe/Paris' => "(GMT+01:00) Paris",
'Europe/Prague' => "(GMT+01:00) Prague",
'Europe/Rome' => "(GMT+01:00) Rome",
'Europe/Sarajevo' => "(GMT+01:00) Sarajevo",
'Europe/Skopje' => "(GMT+01:00) Skopje",
'Europe/Stockholm' => "(GMT+01:00) Stockholm",
'Europe/Vienna' => "(GMT+01:00) Vienna",
'Europe/Warsaw' => "(GMT+01:00) Warsaw",
'Europe/Zagreb' => "(GMT+01:00) Zagreb",
'Europe/Athens' => "(GMT+02:00) Athens",
'Europe/Bucharest' => "(GMT+02:00) Bucharest",
'Africa/Cairo' => "(GMT+02:00) Cairo",
'Africa/Harare' => "(GMT+02:00) Harare",
'Europe/Helsinki' => "(GMT+02:00) Helsinki",
'Europe/Istanbul' => "(GMT+02:00) Istanbul",
'Asia/Jerusalem' => "(GMT+02:00) Jerusalem",
'Europe/Kiev' => "(GMT+02:00) Kyiv",
'Europe/Minsk' => "(GMT+02:00) Minsk",
'Europe/Riga' => "(GMT+02:00) Riga",
'Europe/Sofia' => "(GMT+02:00) Sofia",
'Europe/Tallinn' => "(GMT+02:00) Tallinn",
'Europe/Vilnius' => "(GMT+02:00) Vilnius",
'Asia/Baghdad' => "(GMT+03:00) Baghdad",
'Asia/Kuwait' => "(GMT+03:00) Kuwait",
'Africa/Nairobi' => "(GMT+03:00) Nairobi",
'Asia/Riyadh' => "(GMT+03:00) Riyadh",
'Asia/Tehran' => "(GMT+03:30) Tehran",
'Europe/Moscow' => "(GMT+04:00) Moscow",
'Asia/Baku' => "(GMT+04:00) Baku",
'Europe/Volgograd' => "(GMT+04:00) Volgograd",
'Asia/Muscat' => "(GMT+04:00) Muscat",
'Asia/Tbilisi' => "(GMT+04:00) Tbilisi",
'Asia/Yerevan' => "(GMT+04:00) Yerevan",
'Asia/Kabul' => "(GMT+04:30) Kabul",
'Asia/Karachi' => "(GMT+05:00) Karachi",
'Asia/Tashkent' => "(GMT+05:00) Tashkent",
'Asia/Kolkata' => "(GMT+05:30) Kolkata",
'Asia/Kathmandu' => "(GMT+05:45) Kathmandu",
'Asia/Yekaterinburg' => "(GMT+06:00) Ekaterinburg",
'Asia/Almaty' => "(GMT+06:00) Almaty",
'Asia/Dhaka' => "(GMT+06:00) Dhaka",
'Asia/Novosibirsk' => "(GMT+07:00) Novosibirsk",
'Asia/Bangkok' => "(GMT+07:00) Bangkok",
'Asia/Jakarta' => "(GMT+07:00) Jakarta",
'Asia/Krasnoyarsk' => "(GMT+08:00) Krasnoyarsk",
'Asia/Chongqing' => "(GMT+08:00) Chongqing",
'Asia/Hong_Kong' => "(GMT+08:00) Hong Kong",
'Asia/Kuala_Lumpur' => "(GMT+08:00) Kuala Lumpur",
'Australia/Perth' => "(GMT+08:00) Perth",
'Asia/Singapore' => "(GMT+08:00) Singapore",
'Asia/Taipei' => "(GMT+08:00) Taipei",
'Asia/Ulaanbaatar' => "(GMT+08:00) Ulaan Bataar",
'Asia/Urumqi' => "(GMT+08:00) Urumqi",
'Asia/Irkutsk' => "(GMT+09:00) Irkutsk",
'Asia/Seoul' => "(GMT+09:00) Seoul",
'Asia/Tokyo' => "(GMT+09:00) Tokyo",
'Australia/Adelaide' => "(GMT+09:30) Adelaide",
'Australia/Darwin' => "(GMT+09:30) Darwin",
'Asia/Yakutsk' => "(GMT+10:00) Yakutsk",
'Australia/Brisbane' => "(GMT+10:00) Brisbane",
'Australia/Canberra' => "(GMT+10:00) Canberra",
'Pacific/Guam' => "(GMT+10:00) Guam",
'Australia/Hobart' => "(GMT+10:00) Hobart",
'Australia/Melbourne' => "(GMT+10:00) Melbourne",
'Pacific/Port_Moresby' => "(GMT+10:00) Port Moresby",
'Australia/Sydney' => "(GMT+10:00) Sydney",
'Asia/Vladivostok' => "(GMT+11:00) Vladivostok",
'Asia/Magadan' => "(GMT+12:00) Magadan",
'Pacific/Auckland' => "(GMT+12:00) Auckland",
'Pacific/Fiji' => "(GMT+12:00) Fiji",
);
foreach ($timezones as $name => $location) {
Timezone::create(array('name'=>$name, 'location'=>$location));
}
} }
} }

View File

@ -29,6 +29,11 @@ class Account extends Eloquent
return $this->belongsTo('Country'); return $this->belongsTo('Country');
} }
public function timezone()
{
return $this->belongsTo('Timezone');
}
public function isGatewayConfigured($gatewayId = 0) public function isGatewayConfigured($gatewayId = 0)
{ {
if ($gatewayId) if ($gatewayId)

View File

@ -70,6 +70,7 @@ class Activity extends Eloquent
public static function emailInvoice($invitation) public static function emailInvoice($invitation)
{ {
$activity = Activity::getBlank(); $activity = Activity::getBlank();
$activity->client_id = $invitation->invoice->client_id;
$activity->invoice_id = $invitation->invoice_id; $activity->invoice_id = $invitation->invoice_id;
$activity->contact_id = $invitation->contact_id; $activity->contact_id = $invitation->contact_id;
$activity->activity_type_id = ACTIVITY_TYPE_EMAIL_INVOICE; $activity->activity_type_id = ACTIVITY_TYPE_EMAIL_INVOICE;
@ -111,7 +112,10 @@ class Activity extends Eloquent
public static function viewInvoice($invitation) public static function viewInvoice($invitation)
{ {
$activity = new Activity; $activity = new Activity;
$activity->invitation_id = $invitation->invitation_id; $activity->user_id = $invitation->user_id;
$activity->account_id = $invitation->user->account_id;
$activity->client_id = $invitation->invoice->client_id;
$activity->invitation_id = $invitation->id;
$activity->contact_id = $invitation->contact_id; $activity->contact_id = $invitation->contact_id;
$activity->invoice_id = $invitation->invoice_id; $activity->invoice_id = $invitation->invoice_id;
$activity->activity_type_id = ACTIVITY_TYPE_VIEW_INVOICE; $activity->activity_type_id = ACTIVITY_TYPE_VIEW_INVOICE;

View File

@ -100,7 +100,7 @@ class Client extends Eloquent implements iEntity
} }
public function getDateCreated() public function getDateCreated()
{ {
if ($this->created_at == '0000-00-00 00:00:00') if ($this->created_at == '0000-00-00 00:00:00')
{ {
return '---'; return '---';

View File

@ -8,6 +8,16 @@ class Invitation extends Eloquent
{ {
return $this->belongsTo('Invoice'); return $this->belongsTo('Invoice');
} }
public function contact()
{
return $this->belongsTo('Contact');
}
public function user()
{
return $this->belongsTo('User');
}
} }
Invitation::created(function($invitation) Invitation::created(function($invitation)

6
app/models/Timezone.php Executable file
View File

@ -0,0 +1,6 @@
<?php
class Timezone extends Eloquent
{
public $timestamps = false;
}

View File

@ -126,6 +126,26 @@ function toSpaceCase($camelStr)
return preg_replace('/([a-z])([A-Z])/s','$1 $2', $camelStr); return preg_replace('/([a-z])([A-Z])/s','$1 $2', $camelStr);
} }
/*
function toDateString($date)
{
if ($date->year < 1900) {
return '';
}
$tz = Session::get('tz');
if (!$tz) {
$tz = 'US/Eastern';
}
$date->tz = $tz;
return $date->toFormattedDateString();
}
*/
function toDateTimeString($date)
{
}
function toSqlDate($date) function toSqlDate($date)
{ {
if (!$date) if (!$date)
@ -142,14 +162,14 @@ function fromSqlDate($date)
{ {
return ''; return '';
} }
return DateTime::createFromFormat('Y-m-d', $date)->format('m/d/Y'); return DateTime::createFromFormat('Y-m-d', $date)->format('m/d/Y');
} }
function processedRequest($url) function processedRequest($url)
{ {
Session::put(Input::get('_token'), $url); //Session::put(Input::get('_token'), $url);
Session::put('_token', md5(microtime())); //Session::put('_token', md5(microtime()));
} }

View File

@ -29,7 +29,8 @@
{{ Former::legend('Account') }} {{ Former::legend('Account') }}
{{ Former::text('name') }} {{ Former::text('name') }}
{{ Former::select('timezone_id')->addOption('','')->label('Timezone')
->fromQuery($timezones, 'location', 'id')->select($account->timezone_id) }}
{{ Former::file('logo')->max(2, 'MB')->accept('image')->wrap('test') }} {{ Former::file('logo')->max(2, 'MB')->accept('image')->wrap('test') }}
@if (file_exists($account->getLogoPath())) @if (file_exists($account->getLogoPath()))

View File

@ -102,7 +102,7 @@
} }
div.dataTables_paginate.paging_bootstrap { div.dataTables_paginate.paging_bootstrap {
margin-top: -20px; margin-top: -30px;
} }
table.table tbody tr.odd { table.table tbody tr.odd {

View File

@ -28,6 +28,7 @@
</div> </div>
<div class="col-md-5"> <div class="col-md-5">
{{ Former::text('invoice_number')->label('Invoice #') }} {{ Former::text('invoice_number')->label('Invoice #') }}
{{-- Former::text('invoice_date')->label('Invoice Date')->data_date_format('yyyy-mm-dd') --}}
{{ Former::text('invoice_date')->label('Invoice Date') }} {{ Former::text('invoice_date')->label('Invoice Date') }}
{{ Former::text('due_date')->label('Due Date') }} {{ Former::text('due_date')->label('Due Date') }}
{{-- Former::text('discount')->data_bind("value: discount, valueUpdate: 'afterkeydown'") --}} {{-- Former::text('discount')->data_bind("value: discount, valueUpdate: 'afterkeydown'") --}}
@ -255,7 +256,7 @@
state: "{{ $account->state }}", state: "{{ $account->state }}",
postal_code: "{{ $account->postal_code }}", postal_code: "{{ $account->postal_code }}",
country: { country: {
name: "{{ $account->country->name }}" name: "{{ $account->country ? $account->country->name : '' }}"
} }
}, },
client: { client: {

View File

@ -122,7 +122,7 @@ function generatePDF(invoice) {
y += 16; y += 16;
doc.text(tableLeft, y, invoice.account.city + ', ' + invoice.account.state + ' ' + invoice.account.postal_code); doc.text(tableLeft, y, invoice.account.city + ', ' + invoice.account.state + ' ' + invoice.account.postal_code);
y += 16; y += 16;
doc.text(tableLeft, y, invoice.account.country.name); doc.text(tableLeft, y, invoice.account.country ? invoice.account.country.name : '');
var clientX = headerRight - (doc.getStringUnitWidth(invoice.client.name) * doc.internal.getFontSize()); var clientX = headerRight - (doc.getStringUnitWidth(invoice.client.name) * doc.internal.getFontSize());
@ -186,13 +186,17 @@ function formatMoney(num) {
/* Set the defaults for DataTables initialisation */ /* Set the defaults for DataTables initialisation */
$.extend( true, $.fn.dataTable.defaults, { $.extend( true, $.fn.dataTable.defaults, {
"sDom": "t<'row-fluid'<'span6'l><'span6'p>>", "sDom": "t<'row-fluid'<'span6'i><'span6'p>>",
//"sDom": "<'row'<'span6'l><'span6'f>r>t<'row'<'span6'i><'span6'p>>",
"sPaginationType": "bootstrap", "sPaginationType": "bootstrap",
"bProcessing": false, "bProcessing": false,
"bInfo": false, //"iDisplayLength": 50,
"bInfo": true,
"oLanguage": { "oLanguage": {
"sLengthMenu": "_MENU_ records per page" //"sLengthMenu": "_MENU_ records per page"
} "sLengthMenu": "_MENU_"
},
//"sScrollY": "500px",
} ); } );