diff --git a/app/Http/Controllers/ClientController.php b/app/Http/Controllers/ClientController.php index d48c015afd4a..454ff63f06b1 100644 --- a/app/Http/Controllers/ClientController.php +++ b/app/Http/Controllers/ClientController.php @@ -2,7 +2,12 @@ namespace App\Http\Controllers; +use App\Models\Client; use Illuminate\Http\Request; +use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Log; +use Yajra\DataTables\Facades\DataTables; +use Yajra\DataTables\Html\Builder; class ClientController extends Controller { @@ -11,9 +16,45 @@ class ClientController extends Controller * * @return \Illuminate\Http\Response */ - public function index() + public function index(Builder $builder) { + Log::error('here i Am'); + if (request()->ajax()) { + $clients = Client::select('clients.*', DB::raw("CONCAT(client_contacts.first_name,' ',client_contacts.last_name) as full_name"), 'client_contacts.email') + ->leftJoin('client_contacts', function($leftJoin) + { + $leftJoin->on('clients.id', '=', 'client_contacts.client_id') + ->where('client_contacts.is_primary', '=', true); + }); + + return DataTables::of($clients->get()) + ->addColumn('action', function ($client) { + return ' Edit'; + }) + ->addColumn('checkbox', function ($client){ + return ''; + }) + ->rawColumns(['checkbox', 'action']) + ->make(true); + } + + $builder->addAction(); + $builder->addCheckbox(); + + $html = $builder->columns([ + ['data' => 'checkbox', 'name' => 'checkbox', 'title' => '', 'searchable' => false, 'orderable' => false], + ['data' => 'name', 'name' => 'name', 'title' => trans('texts.name'), 'visible'=> true], + ['data' => 'full_name', 'name' => 'full_name', 'title' => trans('texts.contact'), 'visible'=> true], + ['data' => 'email', 'name' => 'email', 'title' => trans('texts.email'), 'visible'=> true], + ['data' => 'created_at', 'name' => 'created_at', 'title' => trans('texts.date_created'), 'visible'=> true], + ['data' => 'last_login', 'name' => 'last_login', 'title' => trans('texts.last_login'), 'visible'=> true], + ['data' => 'balance', 'name' => 'balance', 'title' => trans('texts.balance'), 'visible'=> true], + ['data' => 'action', 'name' => 'action', 'title' => '', 'searchable' => false, 'orderable' => false], + ]); + + + return view('client.list', compact('html')); } /** @@ -81,4 +122,5 @@ class ClientController extends Controller { // } + } diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/DashboardController.php similarity index 77% rename from app/Http/Controllers/HomeController.php rename to app/Http/Controllers/DashboardController.php index 7afb0c4a033d..f452e916dd23 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/DashboardController.php @@ -2,7 +2,7 @@ namespace App\Http\Controllers; -class HomeController extends Controller +class DashboardController extends Controller { /** * Create a new controller instance. @@ -11,7 +11,8 @@ class HomeController extends Controller */ public function __construct() { - + $this->middleware('auth:user'); + } /** @@ -21,13 +22,6 @@ class HomeController extends Controller */ public function index() { - return view('home'); - } - - public function user() - { - $this->middleware('auth:user'); - return view('dashboard.index'); } diff --git a/app/Http/Controllers/Traits/VerifiesUserEmail.php b/app/Http/Controllers/Traits/VerifiesUserEmail.php index 67192c3ccbb1..84bca012f488 100644 --- a/app/Http/Controllers/Traits/VerifiesUserEmail.php +++ b/app/Http/Controllers/Traits/VerifiesUserEmail.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers\Traits; use App\Models\User; +use Illuminate\Support\Facades\Auth; trait VerifiesUserEmail { @@ -17,11 +18,13 @@ trait VerifiesUserEmail $user->confirmation_code = null; $user->save(); - redirect()->route('user.dashboard')->with('message', trans('texts.security_confirmation')); + Auth::loginUsingId($user->id, true); + + return redirect()->route('user.dashboard')->with('message', trans('texts.security_confirmation')); } - redirect()->route('login')->with('message', trans('texts.wrong_confirmation')); + return redirect()->route('login')->with('message', trans('texts.wrong_confirmation')); } } \ No newline at end of file diff --git a/app/Http/Middleware/UrlSetDb.php b/app/Http/Middleware/UrlSetDb.php index 324535c53ac5..2f6e3acc4d6f 100644 --- a/app/Http/Middleware/UrlSetDb.php +++ b/app/Http/Middleware/UrlSetDb.php @@ -16,7 +16,7 @@ class UrlSetDb * @return mixed */ - public function handle($request, Closure $next, $hash) + public function handle($request, Closure $next) { if (config('ninja.db.multi_db_enabled')) @@ -24,11 +24,11 @@ class UrlSetDb $hashids = new Hashids(); //decoded output is _always_ an array. //parse URL hash and set DB - $segments = explode("-", $hash); + $segments = explode("-", $request->route('confirmation_code')); $hashed_db = $hashids->decode($segments[0]); - MultiDB::setDB(MultiDB::DB_PREFIX . $hashed_db[0]); + MultiDB::setDB(MultiDB::DB_PREFIX . str_pad($hashed_db[0], 2 , "0", STR_PAD_LEFT)); } return $next($request); diff --git a/app/Jobs/User/CreateUser.php b/app/Jobs/User/CreateUser.php index 130ee65e48dd..b261bb9439c7 100644 --- a/app/Jobs/User/CreateUser.php +++ b/app/Jobs/User/CreateUser.php @@ -2,6 +2,7 @@ namespace App\Jobs\User; +use App\Events\User\UserCreated; use App\Models\User; use App\Models\UserCompany; use App\Utils\Traits\MakesHash; @@ -62,6 +63,9 @@ class CreateUser ]); + + event(new UserCreated($user)); + return $user; } } diff --git a/app/Listeners/SendVerificationNotification.php b/app/Listeners/SendVerificationNotification.php index e3f0cfbfefa8..c181142b6924 100644 --- a/app/Listeners/SendVerificationNotification.php +++ b/app/Listeners/SendVerificationNotification.php @@ -3,8 +3,10 @@ namespace App\Listeners; use App\Libraries\MultiDB; +use App\Mail\VerifyUser; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Support\Facades\Mail; class SendVerificationNotification { @@ -29,5 +31,9 @@ class SendVerificationNotification //send confirmation email using $event->user MultiDB::setDB($event->user->db); + Mail::to($event->user->email) + //->cc('') + //->bcc('') + ->queue(new VerifyUser($event->user)); } } diff --git a/app/Mail/VerifyUser.php b/app/Mail/VerifyUser.php new file mode 100644 index 000000000000..367afe88cc26 --- /dev/null +++ b/app/Mail/VerifyUser.php @@ -0,0 +1,39 @@ +user = $user; + } + + /** + * Build the message. + * + * @return $this + */ + public function build() + { + + return $this->from('turbo124@gmail.com') //todo + ->subject(__trans('texts.confirmation_subject')) + ->markdown('email.auth.verify', ['user' => $this->user]) + ->text('email.auth.verify_text'); + } +} diff --git a/app/Models/Account.php b/app/Models/Account.php index 6a6c6dd2c158..dfe0acbee570 100644 --- a/app/Models/Account.php +++ b/app/Models/Account.php @@ -50,6 +50,10 @@ class Account extends Model return $this->hasMany(Company::class); } + public function default_company() + { + return $this->hasOne(Company::class, 'default_company_id', 'id'); + } /** * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ diff --git a/app/Models/Client.php b/app/Models/Client.php index 36bf29e1fc3f..fd171ea071f1 100644 --- a/app/Models/Client.php +++ b/app/Models/Client.php @@ -6,5 +6,25 @@ use Illuminate\Database\Eloquent\Model; class Client extends Model { - // + + public function contacts() + { + return $this->hasMany(ClientContact::class); + } + + public function locations() + { + return $this->hasMany(ClientLocation::class); + } + + public function primary_location() + { + return $this->hasMany(ClientLocation::class)->whereIsPrimary(true); + } + + public function primary_contact() + { + return $this->hasMany(ClientContact::class)->whereIsPrimary(true); + } + } diff --git a/app/Models/ClientContact.php b/app/Models/ClientContact.php index 5a2274f4c9c8..7f2a41d1b190 100644 --- a/app/Models/ClientContact.php +++ b/app/Models/ClientContact.php @@ -31,4 +31,10 @@ class ClientContact extends Authenticatable 'password', 'remember_token', ]; + + public function client() + { + $this->hasOne(Client::class); + } + } diff --git a/app/Models/ClientLocation.php b/app/Models/ClientLocation.php index 38596d98559b..eb7601d6c647 100644 --- a/app/Models/ClientLocation.php +++ b/app/Models/ClientLocation.php @@ -6,5 +6,5 @@ use Illuminate\Database\Eloquent\Model; class ClientLocation extends Model { - // + public $timestamps = false; } diff --git a/app/Models/User.php b/app/Models/User.php index 384a873f230d..20eff18447da 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -44,7 +44,6 @@ class User extends Authenticatable implements MustVerifyEmail */ protected $hidden = [ 'remember_token', - 'confirmation_code', 'oauth_user_id', 'oauth_provider_id', 'google_2fa_secret', @@ -53,9 +52,14 @@ class User extends Authenticatable implements MustVerifyEmail 'slack_webhook_url', ]; - public function user_accounts() + public function account() { - return $this->hasMany(UserAccount::class); + return $this->hasOne(Account::class); + } + + public function user_companies() + { + return $this->hasMany(UserCompany::class); } public function contacts() @@ -64,8 +68,6 @@ class User extends Authenticatable implements MustVerifyEmail } - - public function owns($entity) { return ! empty($entity->user_id) && $entity->user_id == $this->id; diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 77fc926514eb..9b49439acaa0 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -4,8 +4,6 @@ namespace App\Providers; use App\Events\User\UserCreated; use App\Listeners\SendVerificationNotification; -use Illuminate\Auth\Events\Registered; -use Illuminate\Auth\Listeners\SendEmailVerificationNotification; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; class EventServiceProvider extends ServiceProvider @@ -16,9 +14,6 @@ class EventServiceProvider extends ServiceProvider * @var array */ protected $listen = [ - Registered::class => [ - SendVerificationNotification::class, - ], UserCreated::class => [ SendVerificationNotification::class, ] diff --git a/app/Utils/Traits/MakesHash.php b/app/Utils/Traits/MakesHash.php index 5e4f1365fdce..fb379c19c520 100644 --- a/app/Utils/Traits/MakesHash.php +++ b/app/Utils/Traits/MakesHash.php @@ -27,7 +27,7 @@ trait MakesHash */ public function createDbHash($db) : string { - return getDbCode($db) . '-' . strtolower(str_random(RANDOM_KEY_LENGTH)); + return $this->getDbCode($db) . '-' . strtolower(str_random(RANDOM_KEY_LENGTH)); } /** diff --git a/composer.json b/composer.json index 18a45f065561..b7fd4ddb79e4 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,9 @@ "predis/predis": "^1.1", "spatie/laravel-html": "^2.19", "webpatser/laravel-countries": "dev-master#75992ad", - "wildbit/postmark-php": "^2.6" + "wildbit/postmark-php": "^2.6", + "yajra/laravel-datatables": "^1.0", + "yajra/laravel-datatables-html": "^3.0" }, "require-dev": { "beyondcode/laravel-dump-server": "^1.0", diff --git a/composer.lock b/composer.lock index 3e16ef0628d8..c17246e59725 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "f070f7f4ccfe346840e4dfd0e39650a5", + "content-hash": "753b0ff8fa34e1e5a54d950d3d780d30", "packages": [ { "name": "asgrim/ofxparser", @@ -1129,6 +1129,74 @@ ], "time": "2018-10-12T19:39:35+00:00" }, + { + "name": "laravelcollective/html", + "version": "v5.7.1", + "source": { + "type": "git", + "url": "https://github.com/LaravelCollective/html.git", + "reference": "777b6d390811ba249255ed5750bf17a019cd88a5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/LaravelCollective/html/zipball/777b6d390811ba249255ed5750bf17a019cd88a5", + "reference": "777b6d390811ba249255ed5750bf17a019cd88a5", + "shasum": "" + }, + "require": { + "illuminate/http": "5.7.*", + "illuminate/routing": "5.7.*", + "illuminate/session": "5.7.*", + "illuminate/support": "5.7.*", + "illuminate/view": "5.7.*", + "php": ">=7.1.3" + }, + "require-dev": { + "illuminate/database": "5.7.*", + "mockery/mockery": "~1.0", + "phpunit/phpunit": "~7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.7-dev" + }, + "laravel": { + "providers": [ + "Collective\\Html\\HtmlServiceProvider" + ], + "aliases": { + "Form": "Collective\\Html\\FormFacade", + "Html": "Collective\\Html\\HtmlFacade" + } + } + }, + "autoload": { + "psr-4": { + "Collective\\Html\\": "src/" + }, + "files": [ + "src/helpers.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + }, + { + "name": "Adam Engebretson", + "email": "adam@laravelcollective.com" + } + ], + "description": "HTML and Form Builders for the Laravel Framework", + "homepage": "https://laravelcollective.com", + "time": "2018-09-05T18:32:53+00:00" + }, { "name": "league/flysystem", "version": "1.0.48", @@ -1213,6 +1281,70 @@ ], "time": "2018-10-15T13:53:10+00:00" }, + { + "name": "league/fractal", + "version": "0.17.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/fractal.git", + "reference": "a0b350824f22fc2fdde2500ce9d6851a3f275b0e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/fractal/zipball/a0b350824f22fc2fdde2500ce9d6851a3f275b0e", + "reference": "a0b350824f22fc2fdde2500ce9d6851a3f275b0e", + "shasum": "" + }, + "require": { + "php": ">=5.4" + }, + "require-dev": { + "doctrine/orm": "^2.5", + "illuminate/contracts": "~5.0", + "mockery/mockery": "~0.9", + "pagerfanta/pagerfanta": "~1.0.0", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~1.5", + "zendframework/zend-paginator": "~2.3" + }, + "suggest": { + "illuminate/pagination": "The Illuminate Pagination component.", + "pagerfanta/pagerfanta": "Pagerfanta Paginator", + "zendframework/zend-paginator": "Zend Framework Paginator" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.13-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Fractal\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Phil Sturgeon", + "email": "me@philsturgeon.uk", + "homepage": "http://philsturgeon.uk/", + "role": "Developer" + } + ], + "description": "Handle the output of complex data structures ready for API output.", + "homepage": "http://fractal.thephpleague.com/", + "keywords": [ + "api", + "json", + "league", + "rest" + ], + "time": "2017-06-12T11:04:56+00:00" + }, { "name": "league/oauth1-client", "version": "1.7.0", @@ -1276,6 +1408,167 @@ ], "time": "2016-08-17T00:36:58+00:00" }, + { + "name": "maatwebsite/excel", + "version": "3.1.2", + "source": { + "type": "git", + "url": "https://github.com/Maatwebsite/Laravel-Excel.git", + "reference": "a80179c3f33d06fc0d7f22891d6aae4bb083f8c3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Maatwebsite/Laravel-Excel/zipball/a80179c3f33d06fc0d7f22891d6aae4bb083f8c3", + "reference": "a80179c3f33d06fc0d7f22891d6aae4bb083f8c3", + "shasum": "" + }, + "require": { + "illuminate/support": "5.5.* || 5.6.* || 5.7.*", + "php": "^7.0", + "phpoffice/phpspreadsheet": "^1.4" + }, + "require-dev": { + "mockery/mockery": "^1.1", + "orchestra/database": "^3.6", + "orchestra/testbench": "^3.6", + "phpunit/phpunit": "^7.0", + "predis/predis": "^1.1" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Maatwebsite\\Excel\\ExcelServiceProvider" + ], + "aliases": { + "Excel": "Maatwebsite\\Excel\\Facades\\Excel" + } + } + }, + "autoload": { + "psr-4": { + "Maatwebsite\\Excel\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Patrick Brouwers", + "email": "patrick@maatwebsite.nl" + } + ], + "description": "Supercharged Excel exports and imports in Laravel", + "keywords": [ + "PHPExcel", + "batch", + "csv", + "excel", + "export", + "import", + "laravel", + "php", + "phpspreadsheet" + ], + "time": "2018-10-11T09:21:58+00:00" + }, + { + "name": "markbaker/complex", + "version": "1.4.7", + "source": { + "type": "git", + "url": "https://github.com/MarkBaker/PHPComplex.git", + "reference": "1ea674a8308baf547cbcbd30c5fcd6d301b7c000" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/1ea674a8308baf547cbcbd30c5fcd6d301b7c000", + "reference": "1ea674a8308baf547cbcbd30c5fcd6d301b7c000", + "shasum": "" + }, + "require": { + "php": "^5.6.0|^7.0.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3", + "phpcompatibility/php-compatibility": "^8.0", + "phpdocumentor/phpdocumentor": "2.*", + "phploc/phploc": "2.*", + "phpmd/phpmd": "2.*", + "phpunit/phpunit": "^4.8.35|^5.4.0", + "sebastian/phpcpd": "2.*", + "squizlabs/php_codesniffer": "^3.3.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Complex\\": "classes/src/" + }, + "files": [ + "classes/src/functions/abs.php", + "classes/src/functions/acos.php", + "classes/src/functions/acosh.php", + "classes/src/functions/acot.php", + "classes/src/functions/acoth.php", + "classes/src/functions/acsc.php", + "classes/src/functions/acsch.php", + "classes/src/functions/argument.php", + "classes/src/functions/asec.php", + "classes/src/functions/asech.php", + "classes/src/functions/asin.php", + "classes/src/functions/asinh.php", + "classes/src/functions/atan.php", + "classes/src/functions/atanh.php", + "classes/src/functions/conjugate.php", + "classes/src/functions/cos.php", + "classes/src/functions/cosh.php", + "classes/src/functions/cot.php", + "classes/src/functions/coth.php", + "classes/src/functions/csc.php", + "classes/src/functions/csch.php", + "classes/src/functions/exp.php", + "classes/src/functions/inverse.php", + "classes/src/functions/ln.php", + "classes/src/functions/log2.php", + "classes/src/functions/log10.php", + "classes/src/functions/negative.php", + "classes/src/functions/pow.php", + "classes/src/functions/rho.php", + "classes/src/functions/sec.php", + "classes/src/functions/sech.php", + "classes/src/functions/sin.php", + "classes/src/functions/sinh.php", + "classes/src/functions/sqrt.php", + "classes/src/functions/tan.php", + "classes/src/functions/tanh.php", + "classes/src/functions/theta.php", + "classes/src/operations/add.php", + "classes/src/operations/subtract.php", + "classes/src/operations/multiply.php", + "classes/src/operations/divideby.php", + "classes/src/operations/divideinto.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mark Baker", + "email": "mark@lange.demon.co.uk" + } + ], + "description": "PHP Class for working with complex numbers", + "homepage": "https://github.com/MarkBaker/PHPComplex", + "keywords": [ + "complex", + "mathematics" + ], + "time": "2018-10-13T23:28:42+00:00" + }, { "name": "monolog/monolog", "version": "1.23.0", @@ -1636,6 +1929,93 @@ ], "time": "2018-07-02T15:55:56+00:00" }, + { + "name": "phpoffice/phpspreadsheet", + "version": "1.5.0", + "source": { + "type": "git", + "url": "https://github.com/PHPOffice/PhpSpreadsheet.git", + "reference": "2dfd06c59825914a1a325f2a2ed13634b9d8c411" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/2dfd06c59825914a1a325f2a2ed13634b9d8c411", + "reference": "2dfd06c59825914a1a325f2a2ed13634b9d8c411", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-dom": "*", + "ext-gd": "*", + "ext-iconv": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-simplexml": "*", + "ext-xml": "*", + "ext-xmlreader": "*", + "ext-xmlwriter": "*", + "ext-zip": "*", + "ext-zlib": "*", + "markbaker/complex": "^1.4.1", + "php": "^5.6|^7.0", + "psr/simple-cache": "^1.0" + }, + "require-dev": { + "dompdf/dompdf": "^0.8.0", + "friendsofphp/php-cs-fixer": "@stable", + "jpgraph/jpgraph": "^4.0", + "mpdf/mpdf": "^7.0.0", + "phpunit/phpunit": "^5.7", + "squizlabs/php_codesniffer": "^3.3", + "tecnickcom/tcpdf": "^6.2" + }, + "suggest": { + "dompdf/dompdf": "Option for rendering PDF with PDF Writer", + "jpgraph/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers", + "mpdf/mpdf": "Option for rendering PDF with PDF Writer", + "tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer" + }, + "type": "library", + "autoload": { + "psr-4": { + "PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1-or-later" + ], + "authors": [ + { + "name": "Maarten Balliauw", + "homepage": "http://blog.maartenballiauw.be" + }, + { + "name": "Erik Tilt" + }, + { + "name": "Franck Lefevre", + "homepage": "http://rootslabs.net" + }, + { + "name": "Mark Baker", + "homepage": "http://markbakeruk.net" + } + ], + "description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine", + "homepage": "https://github.com/PHPOffice/PhpSpreadsheet", + "keywords": [ + "OpenXML", + "excel", + "gnumeric", + "ods", + "php", + "spreadsheet", + "xls", + "xlsx" + ], + "time": "2018-10-21T10:04:54+00:00" + }, { "name": "predis/predis", "version": "v1.1.1", @@ -3217,6 +3597,303 @@ ], "description": "The officially supported client for Postmark (http://postmarkapp.com)", "time": "2018-07-24T22:40:23+00:00" + }, + { + "name": "yajra/laravel-datatables", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/yajra/datatables.git", + "reference": "a5e2eaac3d7bc155502a37ab490cbcf0dee63e06" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/yajra/datatables/zipball/a5e2eaac3d7bc155502a37ab490cbcf0dee63e06", + "reference": "a5e2eaac3d7bc155502a37ab490cbcf0dee63e06", + "shasum": "" + }, + "require": { + "php": ">=7.0", + "yajra/laravel-datatables-buttons": "3.*|4.*", + "yajra/laravel-datatables-fractal": "1.*", + "yajra/laravel-datatables-html": "3.*", + "yajra/laravel-datatables-oracle": "8.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Arjay Angeles", + "email": "aqangeles@gmail.com" + } + ], + "description": "Laravel DataTables Complete Package.", + "keywords": [ + "datatables", + "jquery", + "laravel" + ], + "time": "2018-08-15T12:31:12+00:00" + }, + { + "name": "yajra/laravel-datatables-buttons", + "version": "v4.4.0", + "source": { + "type": "git", + "url": "https://github.com/yajra/laravel-datatables-buttons.git", + "reference": "649f0f6c02b391e349cff3f186aa88b61fb0cdd0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/yajra/laravel-datatables-buttons/zipball/649f0f6c02b391e349cff3f186aa88b61fb0cdd0", + "reference": "649f0f6c02b391e349cff3f186aa88b61fb0cdd0", + "shasum": "" + }, + "require": { + "illuminate/console": "^5.5", + "maatwebsite/excel": "^3.0", + "php": ">=7.0", + "yajra/laravel-datatables-html": "3.*", + "yajra/laravel-datatables-oracle": "8.*" + }, + "require-dev": { + "mockery/mockery": "~1.0", + "phpunit/phpunit": "~7.0" + }, + "suggest": { + "barryvdh/laravel-snappy": "Allows exporting of dataTable to PDF using the print view.", + "dompdf/dompdf": "Allows exporting of dataTable to PDF using the DomPDF." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + }, + "laravel": { + "providers": [ + "Yajra\\DataTables\\ButtonsServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Yajra\\DataTables\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Arjay Angeles", + "email": "aqangeles@gmail.com" + } + ], + "description": "Laravel DataTables Buttons Plugin.", + "keywords": [ + "buttons", + "datatables", + "jquery", + "laravel" + ], + "time": "2018-10-06T02:23:34+00:00" + }, + { + "name": "yajra/laravel-datatables-fractal", + "version": "v1.2.1", + "source": { + "type": "git", + "url": "https://github.com/yajra/laravel-datatables-fractal.git", + "reference": "23804250ce32ddba216295ce47f713f551dba45c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/yajra/laravel-datatables-fractal/zipball/23804250ce32ddba216295ce47f713f551dba45c", + "reference": "23804250ce32ddba216295ce47f713f551dba45c", + "shasum": "" + }, + "require": { + "league/fractal": "^0.17.0", + "php": ">=7.0", + "yajra/laravel-datatables-oracle": "8.*" + }, + "require-dev": { + "mockery/mockery": "0.9.*", + "phpunit/phpunit": "~6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + }, + "laravel": { + "providers": [ + "Yajra\\DataTables\\FractalServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Yajra\\DataTables\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Arjay Angeles", + "email": "aqangeles@gmail.com" + } + ], + "description": "Laravel DataTables Fractal Plugin.", + "keywords": [ + "api", + "datatables", + "fractal", + "laravel" + ], + "time": "2018-06-12T06:23:13+00:00" + }, + { + "name": "yajra/laravel-datatables-html", + "version": "v3.8.0", + "source": { + "type": "git", + "url": "https://github.com/yajra/laravel-datatables-html.git", + "reference": "84a3b61e0ecba78108c55a508db150e8c8db2e59" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/yajra/laravel-datatables-html/zipball/84a3b61e0ecba78108c55a508db150e8c8db2e59", + "reference": "84a3b61e0ecba78108c55a508db150e8c8db2e59", + "shasum": "" + }, + "require": { + "laravelcollective/html": "^5.4", + "php": ">=7.0", + "yajra/laravel-datatables-oracle": "8.*" + }, + "require-dev": { + "mockery/mockery": "0.9.*", + "phpunit/phpunit": "~6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "laravel": { + "providers": [ + "Yajra\\DataTables\\HtmlServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Yajra\\DataTables\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Arjay Angeles", + "email": "aqangeles@gmail.com" + } + ], + "description": "Laravel DataTables HTML builder plugin for Laravel 5.4+.", + "keywords": [ + "JS", + "datatables", + "html", + "jquery", + "laravel" + ], + "time": "2018-09-05T06:10:14+00:00" + }, + { + "name": "yajra/laravel-datatables-oracle", + "version": "v8.9.1", + "source": { + "type": "git", + "url": "https://github.com/yajra/laravel-datatables.git", + "reference": "851c4d4d307a66a4f8ab5c12444c1eb0104ecc80" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/yajra/laravel-datatables/zipball/851c4d4d307a66a4f8ab5c12444c1eb0104ecc80", + "reference": "851c4d4d307a66a4f8ab5c12444c1eb0104ecc80", + "shasum": "" + }, + "require": { + "illuminate/database": "5.4.*|5.5.*|5.6.*|5.7.*", + "illuminate/filesystem": "5.4.*|5.5.*|5.6.*|5.7.*", + "illuminate/http": "5.4.*|5.5.*|5.6.*|5.7.*", + "illuminate/support": "5.4.*|5.5.*|5.6.*|5.7.*", + "illuminate/view": "5.4.*|5.5.*|5.6.*|5.7.*", + "php": ">=7.0" + }, + "require-dev": { + "orchestra/testbench": "~3.5" + }, + "suggest": { + "yajra/laravel-datatables-buttons": "Plugin for server-side exporting of dataTables.", + "yajra/laravel-datatables-editor": "Plugin to use DataTables Editor (requires a license).", + "yajra/laravel-datatables-fractal": "Plugin for server-side response using Fractal.", + "yajra/laravel-datatables-html": "Plugin for server-side HTML builder of dataTables." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "8.0-dev" + }, + "laravel": { + "providers": [ + "Yajra\\DataTables\\DataTablesServiceProvider" + ], + "aliases": { + "DataTables": "Yajra\\DataTables\\Facades\\DataTables" + } + } + }, + "autoload": { + "psr-4": { + "Yajra\\DataTables\\": "src/" + }, + "files": [ + "src/helper.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Arjay Angeles", + "email": "aqangeles@gmail.com" + } + ], + "description": "jQuery DataTables API for Laravel 4|5", + "keywords": [ + "datatables", + "jquery", + "laravel" + ], + "time": "2018-10-05T06:10:33+00:00" } ], "packages-dev": [ diff --git a/config/app.php b/config/app.php index d5d66c7021b2..13eddf957dd3 100644 --- a/config/app.php +++ b/config/app.php @@ -159,7 +159,8 @@ return [ Illuminate\Translation\TranslationServiceProvider::class, Illuminate\Validation\ValidationServiceProvider::class, Illuminate\View\ViewServiceProvider::class, - + Yajra\DataTables\DataTablesServiceProvider::class, + Yajra\DataTables\HtmlServiceProvider::class, /* * Dependency Service Providers */ @@ -227,6 +228,7 @@ return [ 'URL' => Illuminate\Support\Facades\URL::class, 'Validator' => Illuminate\Support\Facades\Validator::class, 'View' => Illuminate\Support\Facades\View::class, + 'Datatables' => Yajra\Datatables\Facades\Datatables::class, /* * Dependency Facades diff --git a/config/datatables-html.php b/config/datatables-html.php new file mode 100644 index 000000000000..bab151726569 --- /dev/null +++ b/config/datatables-html.php @@ -0,0 +1,16 @@ + [ + 'class' => 'table', + 'id' => 'table table-striped table-bordered', + ], + /* + * Default condition to determine if a parameter is a callback or not + * Callbacks needs to start by those terms or they will be casted to string + */ + 'callback' => ['$', '$.', 'function'], +]; diff --git a/database/factories/ContactFactory.php b/database/factories/ClientContactFactory.php similarity index 52% rename from database/factories/ContactFactory.php rename to database/factories/ClientContactFactory.php index 80dfb6758720..ebf6dc93b852 100644 --- a/database/factories/ContactFactory.php +++ b/database/factories/ClientContactFactory.php @@ -13,12 +13,16 @@ use Faker\Generator as Faker; | */ -$factory->define(App\Models\Contact::class, function (Faker $faker) { +$factory->define(App\Models\ClientContact::class, function (Faker $faker) { return [ - 'first_name' => $faker->name, - 'email' => $faker->unique()->safeEmail, - 'password' => bcrypt('secret'), - 'remember_token' => str_random(10), - 'db' => config('database.default') + 'first_name' => $faker->firstName, + 'last_name' => $faker->lastName, + 'phone' => $faker->phoneNumber, + 'email_verified_at' => now(), + 'email' => $faker->unique()->safeEmail, + 'password' => bcrypt('password'), + 'remember_token' => str_random(10), + 'db' => config('database.default') ]; + }); diff --git a/database/factories/ClientFactory.php b/database/factories/ClientFactory.php new file mode 100644 index 000000000000..dc3a944ac0e8 --- /dev/null +++ b/database/factories/ClientFactory.php @@ -0,0 +1,19 @@ +define(App\Models\Client::class, function (Faker $faker) { + return [ + 'name' => $faker->name(), + 'website' => $faker->url, + 'private_notes' => $faker->text(200), + 'balance' => $faker->numberBetween(0,1000), + 'paid_to_date' => $faker->numberBetween(0,10000), + 'vat_number' => $faker->text(25), + 'id_number' => $faker->text(20), + 'custom_value1' => $faker->text(20), + 'custom_value2' => $faker->text(20), + 'payment_terms' => $faker->text(40), + ]; +}); + diff --git a/database/factories/ClientLocationFactory.php b/database/factories/ClientLocationFactory.php new file mode 100644 index 000000000000..84b8be8ff24c --- /dev/null +++ b/database/factories/ClientLocationFactory.php @@ -0,0 +1,18 @@ +define(App\Models\ClientLocation::class, function (Faker $faker) { + return [ + 'address1' => $faker->buildingNumber, + 'address2' => $faker->streetAddress, + 'city' => $faker->city, + 'state' => $faker->state, + 'postal_code' => $faker->postcode, + 'country_id' => 4, + 'latitude' => $faker->latitude, + 'longitude' => $faker->longitude, + 'description' => $faker->paragraph, + 'private_notes' => $faker->paragraph + ]; +}); diff --git a/database/migrations/2014_10_13_000000_create_users_table.php b/database/migrations/2014_10_13_000000_create_users_table.php index 585ce128ad64..6a289b4131fd 100644 --- a/database/migrations/2014_10_13_000000_create_users_table.php +++ b/database/migrations/2014_10_13_000000_create_users_table.php @@ -268,7 +268,7 @@ class CreateUsersTable extends Migration $table->string('email',100); $table->timestamp('email_verified_at')->nullable(); $table->string('confirmation_code')->nullable(); - $table->boolean('registered')->default(false); + $table->boolean('is_primary')->default(false); $table->boolean('confirmed')->default(false); $table->smallInteger('failed_logins')->nullable(); $table->string('oauth_user_id',100)->nullable()->unique(); diff --git a/database/seeds/UsersTableSeeder.php b/database/seeds/UsersTableSeeder.php index 3fa7467edadb..fbab34a9e6f3 100644 --- a/database/seeds/UsersTableSeeder.php +++ b/database/seeds/UsersTableSeeder.php @@ -9,6 +9,7 @@ use Illuminate\Database\Seeder; class UsersTableSeeder extends Seeder { + use \App\Utils\Traits\MakesHash; /** * Run the database seeds. * @@ -33,20 +34,17 @@ class UsersTableSeeder extends Seeder $account->default_company_id = $company->id; $account->save(); - $user = User::create([ + $user = factory(\App\Models\User::class)->create([ 'account_id' => $account->id, - 'first_name' => $faker->firstName, - 'last_name' => $faker->lastName, - 'email' => config('ninja.testvars.username'), - 'password' => Hash::make(config('ninja.testvars.password')), - 'email_verified_at' => now(), + 'confirmation_code' => $this->createDbHash(config('database.default')) ]); - $client = Client::create([ - 'name' => $faker->name, - 'company_id' => $company->id, + $client = factory(\App\Models\Client::class)->create([ + 'user_id' => $user->id, + 'company_id' => $company->id ]); + ClientContact::create([ 'first_name' => $faker->firstName, 'last_name' => $faker->lastName, @@ -65,5 +63,34 @@ class UsersTableSeeder extends Seeder 'is_admin' => 1, 'is_locked' => 0, ]); + + + factory(\App\Models\Client::class, 50)->create(['user_id' => $user->id, 'company_id' => $company->id])->each(function ($c) use ($user, $company){ + + factory(\App\Models\ClientContact::class,1)->create([ + 'user_id' => $user->id, + 'client_id' => $c->id, + 'company_id' => $company->id, + 'is_primary' => 1 + ]); + + factory(\App\Models\ClientContact::class,10)->create([ + 'user_id' => $user->id, + 'client_id' => $c->id, + 'company_id' => $company->id + ]); + + factory(\App\Models\ClientLocation::class,1)->create([ + 'client_id' => $c->id, + 'is_primary' => 1 + ]); + + factory(\App\Models\ClientLocation::class,10)->create([ + 'client_id' => $c->id, + ]); + + }); + + } } diff --git a/resources/views/client/list.blade.php b/resources/views/client/list.blade.php new file mode 100644 index 000000000000..0260e5cd25d3 --- /dev/null +++ b/resources/views/client/list.blade.php @@ -0,0 +1,54 @@ +@extends('layouts.master') + +@section('head') + + + +@endsection + +@section('header') + @include('header') + + @parent +@endsection + + +@section('sidebar') + @include('sidebar') +@endsection + +@section('body') +
+ + {{ Breadcrumbs::render('clients') }} + +
+
+
+
+ + {!! $html->table() !!} + +
+
+
+
+
+ + + + @include('dashboard.aside') + +@endsection + +@section('footer') + @include('footer') + + + {!! $html->scripts() !!} + +@endsection + + + + diff --git a/resources/views/dashboard/index.blade.php b/resources/views/dashboard/index.blade.php index 45d70293bdd1..b2ad22a97b6e 100644 --- a/resources/views/dashboard/index.blade.php +++ b/resources/views/dashboard/index.blade.php @@ -15,6 +15,9 @@ {{ Breadcrumbs::render('dashboard') }}
+ + +
@@ -26,4 +29,3 @@ @include('footer') @endsection - diff --git a/resources/views/email/auth/verify.blade.php b/resources/views/email/auth/verify.blade.php new file mode 100644 index 000000000000..390b6f943aa9 --- /dev/null +++ b/resources/views/email/auth/verify.blade.php @@ -0,0 +1,35 @@ +@component('mail::layout') + +{{-- Header --}} +@slot('header') +@component('mail::header', ['url' => config('app.url')]) +Header Title +@endcomponent +@endslot + +{{-- Body --}} +{{ $user }} +@lang('texts.confirmation_message') + +@component('mail::button', ['url' => url("/user/confirm/{$user->confirmation_code} ")]) +@lang('texts.confirm') +@endcomponent + +{{-- Subcopy --}} +@isset($subcopy) +@slot('subcopy') +@component('mail::subcopy') +{{ $subcopy }} +@endcomponent +@endslot +@endisset + + +{{-- Footer --}} +@slot('footer') +@component('mail::footer') +© {{ date('Y') }} {{ config('ninja.app_name') }}. +@endcomponent +@endslot + +@endcomponent \ No newline at end of file diff --git a/resources/views/email/auth/verify_text.blade.php b/resources/views/email/auth/verify_text.blade.php new file mode 100644 index 000000000000..fa91d2807d55 --- /dev/null +++ b/resources/views/email/auth/verify_text.blade.php @@ -0,0 +1 @@ +url("/user/confirm/{$user->confirmation_code}") \ No newline at end of file diff --git a/resources/views/layouts/master.blade.php b/resources/views/layouts/master.blade.php index 41dc87007253..2ef8ba65d053 100644 --- a/resources/views/layouts/master.blade.php +++ b/resources/views/layouts/master.blade.php @@ -59,7 +59,7 @@ - + diff --git a/resources/views/sidebar.blade.php b/resources/views/sidebar.blade.php index 555e09cfffaf..cab9be8eb538 100644 --- a/resources/views/sidebar.blade.php +++ b/resources/views/sidebar.blade.php @@ -9,7 +9,7 @@ diff --git a/resources/views/welcome.blade.php b/resources/views/welcome.blade.php deleted file mode 100644 index 9180a76906a6..000000000000 --- a/resources/views/welcome.blade.php +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - Laravel - - - - - - - - -
- @if (Route::has('login')) - - @endif - -
-
- Laravel -
- - -
-
- - diff --git a/routes/breadcrumbs.php b/routes/breadcrumbs.php index 5347cad6a79f..a4f86e14ce54 100644 --- a/routes/breadcrumbs.php +++ b/routes/breadcrumbs.php @@ -1,6 +1,12 @@ push(trans('texts.dashboard'), route('user.dashboard')); +}); + +// Dashboard > Client +Breadcrumbs::for('clients', function ($trail) { + $trail->parent('dashboard'); + $trail->push(trans('texts.clients'), route('clients.index')); }); \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index b564a32e77b9..658012d55293 100644 --- a/routes/web.php +++ b/routes/web.php @@ -40,21 +40,25 @@ Route::get('auth/{provider}/callback', 'Auth\LoginController@handleProviderCallb Route::group(['middleware' => ['auth:user', 'db']], function () { - Route::get('dashboard', 'HomeController@user')->name('user.dashboard'); + Route::get('dashboard', 'DashboardController@index')->name('user.dashboard'); Route::get('logout', 'Auth\LoginController@logout')->name('user.logout'); Route::resource('invoices', 'InvoiceController'); // name = (invoices. index / create / show / update / destroy / edit + Route::resource('clients', 'ClientController'); // name = (clients. index / create / show / update / destroy / edit Route::get('settings', 'SettingsController@index')->name('user.settings'); + + }); /* * Inbound routes requiring DB Lookup */ -Route::group(['middleware' => ['auth:user', 'db']], function () { +Route::group(['middleware' => ['url-db']], function () { Route::get('/user/confirm/{confirmation_code}', 'UserController@confirm'); }); + /* Authenticated Contact Routes */ @@ -66,3 +70,12 @@ Route::group(['prefix' => 'contact', 'middleware' => 'auth:contact'], function }); + +/* Dev Playground +Route::get('/mailable', function () { + $user = App\Models\User::find(1); + + return new App\Mail\VerifyUser($user); +}); + +*/ \ No newline at end of file