Save Client / Contacts (#2523)

* View composers

* Saving client and contacts

*  saving client and contacts

* update client job

* unique emails
This commit is contained in:
David Bomba 2018-11-27 17:59:16 +11:00 committed by GitHub
parent cdb98ce528
commit 348890e8fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 48777 additions and 53 deletions

View File

@ -4,14 +4,19 @@ namespace App\Http\Controllers;
use App\Http\Requests\Client\EditClientRequest; use App\Http\Requests\Client\EditClientRequest;
use App\Http\Requests\Client\UpdateClientRequest; use App\Http\Requests\Client\UpdateClientRequest;
use App\Jobs\Client\UpdateClient;
use App\Models\Client; use App\Models\Client;
use App\Repositories\ClientRepository; use App\Repositories\ClientRepository;
use App\Utils\Traits\MakesHash;
use App\Utils\Traits\UserSessionAttributes;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Yajra\DataTables\Facades\DataTables; use Yajra\DataTables\Facades\DataTables;
use Yajra\DataTables\Html\Builder; use Yajra\DataTables\Html\Builder;
class ClientController extends Controller class ClientController extends Controller
{ {
use UserSessionAttributes;
use MakesHash;
protected $clientRepo; protected $clientRepo;
@ -81,7 +86,6 @@ class ClientController extends Controller
'data' => 'function(d) { d.key = "value"; }', 'data' => 'function(d) { d.key = "value"; }',
]); ]);
//$data['header'] = $this->headerData();
$data['html'] = $html; $data['html'] = $html;
return view('client.list', $data); return view('client.list', $data);
@ -132,8 +136,8 @@ class ClientController extends Controller
{ {
$data = [ $data = [
'header' => $this->headerData(),
'client' => $client, 'client' => $client,
'hashed_id' => $this->encodePrimarykey($client->id)
]; ];
return view('client.edit', $data); return view('client.edit', $data);
@ -143,13 +147,12 @@ class ClientController extends Controller
* Update the specified resource in storage. * Update the specified resource in storage.
* *
* @param \Illuminate\Http\Request $request * @param \Illuminate\Http\Request $request
* @param int $id * @param App\Models\Client $client
* @return \Illuminate\Http\Response * @return \Illuminate\Http\Response
*/ */
public function update(UpdateClientRequest $request, Client $client) public function update(UpdateClientRequest $request, Client $client)
{ {
$client = UpdateClient::dispatchNow($request, $client);
$client = $this->clientRepo->save($request, $client);
$client->load('contacts', 'primary_contact'); $client->load('contacts', 'primary_contact');
return response()->json($client, 200); return response()->json($client, 200);

View File

@ -2,7 +2,6 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Utils\Traits\MakesHeaderData;
use App\Utils\Traits\UserSessionAttributes; use App\Utils\Traits\UserSessionAttributes;
use Illuminate\Foundation\Bus\DispatchesJobs; use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController; use Illuminate\Routing\Controller as BaseController;
@ -11,5 +10,5 @@ use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
class Controller extends BaseController class Controller extends BaseController
{ {
use AuthorizesRequests, DispatchesJobs, ValidatesRequests, MakesHeaderData; use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
} }

View File

@ -25,9 +25,7 @@ class DashboardController extends Controller
*/ */
public function index() public function index()
{ {
$data['header'] = $this->headerData(); return view('dashboard.index');
return view('dashboard.index', $data);
} }

View File

@ -23,6 +23,7 @@ class UpdateClientRequest extends Request
{ {
return [ return [
'name' => 'required', 'name' => 'required',
'contacts.*.email' => 'email|unique:client_contacts,id'
]; ];
} }

View File

@ -22,6 +22,9 @@ class HeaderComposer
private function headerData() private function headerData()
{ {
if(!auth()->user())
return [];
//companies //companies
$companies = auth()->user()->companies; $companies = auth()->user()->companies;

View File

@ -0,0 +1,41 @@
<?php
namespace App\Jobs\Client;
use App\Models\Client;
use App\Repositories\ClientRepository;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
class UpdateClient
{
use Dispatchable;
protected $request;
protected $client;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct(Request $request, Client $client)
{
$this->request = $request;
$this->client = $client;
}
/**
* Execute the job.
*
* @return void
*/
public function handle(ClientRepository $clientRepo)
{
return $clientRepo->save($this->request, $this->client);
}
}

View File

@ -18,13 +18,13 @@ class Client extends BaseModel
//protected $appends = ['client_id']; //protected $appends = ['client_id'];
protected $guarded = [ protected $guarded = [
'id' 'id',
'updated_at',
'created_at',
'deleted_at',
]; ];
public function getRouteKeyName() //protected $dates = ['deleted_at'];
{
return 'client_id';
}
public function getHashedIdAttribute() public function getHashedIdAttribute()
{ {

View File

@ -5,6 +5,7 @@ namespace App\Models;
use App\Utils\Traits\MakesHash; use App\Utils\Traits\MakesHash;
use Hashids\Hashids; use Hashids\Hashids;
use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable; use Illuminate\Notifications\Notifiable;
use Laracasts\Presenter\PresentableTrait; use Laracasts\Presenter\PresentableTrait;
@ -15,6 +16,7 @@ class ClientContact extends Authenticatable
use Notifiable; use Notifiable;
use MakesHash; use MakesHash;
use PresentableTrait; use PresentableTrait;
use SoftDeletes;
// protected $appends = ['contact_id']; // protected $appends = ['contact_id'];
@ -22,6 +24,8 @@ class ClientContact extends Authenticatable
protected $presenter = 'App\Models\Presenters\ClientContactPresenter'; protected $presenter = 'App\Models\Presenters\ClientContactPresenter';
protected $dates = ['deleted_at'];
protected $guarded = [ protected $guarded = [
'id', 'id',
]; ];

View File

@ -14,14 +14,7 @@ class ComposerServiceProvider extends ServiceProvider
*/ */
public function boot() public function boot()
{ {
View::composer( View::composer('*', 'App\Http\ViewComposers\HeaderComposer');
[
'client.edit',
'client.list',
'dashboard.index',
],
'App\Http\ViewComposers\HeaderComposer'
);
} }
/** /**

View File

@ -2,15 +2,53 @@
namespace App\Repositories; namespace App\Repositories;
use App\Models\Client;
use App\Models\ClientContact;
use Illuminate\Support\Facades\Log;
/** /**
* *
*/ */
class ClientContactRepository extends BaseRepository class ClientContactRepository extends BaseRepository
{ {
public function save($data) public function save(array $contacts, Client $client) : void
{ {
/* Convert array to collection */
$contacts = collect($contacts);
/* Get array of IDs which have been removed from the contacts array and soft delete each contact */
collect($client->contacts->pluck('id'))->diffKeys($contacts->pluck('id'))->each(function($contact){
ClientContact::destroy($contact);
});
/* Set first record to primary - always*/
$contacts = $contacts->sortBy('is_primary');
$contacts->first(function($contact){
$contact['is_primary'] = true;
});
//loop and update/create contacts
$contacts->each(function ($contact) use ($client){
$update_contact = ClientContact::firstOrNew(
['id' => $contact['id']],
[
'client_id' => $client->id,
'company_id' => $client->company_id
]
);
$update_contact->fill($contact);
$update_contact->save();
});
} }
} }

View File

@ -2,24 +2,32 @@
namespace App\Repositories; namespace App\Repositories;
use App\Models\Client;
use App\Repositories\ClientContactRepository; use App\Repositories\ClientContactRepository;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
/** /**
* *
*/ */
class ClientRepository extends BaseRepository class ClientRepository extends BaseRepository
{ {
protected $clientContactRepository; protected $clientContactRepo;
public function __construct(ClientContactRepository $clientContactRepository) public function __construct(ClientContactRepository $clientContactRepo)
{ {
$this->clientContactRepository = $clientContactRepository; $this->clientContactRepo = $clientContactRepo;
} }
public function save($data) public function save(Request $request, Client $client) : ?Client
{ {
$client->fill($request->all())->save(); Log::error(print_r($request->input(),1));
$client->fill($request->input());
$client->save();
$this->clientContactRepo->save($request->input('contacts'), $client);
return $client;
} }
} }

16916
public/css/ninja.css vendored

File diff suppressed because one or more lines are too long

16916
public/css/ninja.min.css vendored

File diff suppressed because one or more lines are too long

13214
public/js/client_edit.js vendored

File diff suppressed because one or more lines are too long

808
public/js/ninja.js vendored

File diff suppressed because one or more lines are too long

808
public/js/ninja.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -4,7 +4,8 @@ import axios, { AxiosRequestConfig, AxiosPromise } from 'axios';
var VueApp: any = Vue; var VueApp: any = Vue;
declare var clientObject: any; declare var client_object: any;
declare var hashed_id: string;
var App = new VueApp({ var App = new VueApp({
el : '#client_edit', el : '#client_edit',
@ -16,7 +17,7 @@ var App = new VueApp({
}, },
mounted(this: any) { mounted(this: any) {
//this.client = {!! $client !!}; //this.client = {!! $client !!};
this.client = clientObject; this.client = client_object;
console.dir(this.client); console.dir(this.client);
}, },
beforeMount: function () { beforeMount: function () {
@ -35,7 +36,7 @@ var App = new VueApp({
}, },
add(this: any){ add(this: any){
console.dir('i will add a contact here') console.dir('i will add a contact here')
this.client.contacts.push({first_name: '', last_name: '', email: '', phone: ''}); this.client.contacts.push({first_name: '', last_name: '', email: '', phone: '', id: -1});
window.scrollTo(0, document.body.scrollHeight || document.documentElement.scrollHeight); window.scrollTo(0, document.body.scrollHeight || document.documentElement.scrollHeight);
this.$nextTick(() => { this.$nextTick(() => {
let index = this.client.contacts.length - 1; let index = this.client.contacts.length - 1;
@ -46,7 +47,7 @@ var App = new VueApp({
submit(this: any) { submit(this: any) {
this.errors = {}; this.errors = {};
axios.put('/clients/', this.client).then(response => { axios.put('/clients/' + hashed_id, this.client).then(response => {
// axios.put('/clients/' + {{ $client->present()->id }}, this.client).then(response => { // axios.put('/clients/' + {{ $client->present()->id }}, this.client).then(response => {
this.client = response.data; this.client = response.data;
}).catch(error => { }).catch(error => {

View File

@ -46,12 +46,13 @@
</div> </div>
</form> </form>
</main>
<script> <script>
var clientObject = {!! $client !!}; var client_object = {!! $client !!};
var hashed_id = '{{ $hashed_id }}';
</script> </script>
<script src=" {{ mix('/js/client_edit.js') }}"></script> <script src=" {{ mix('/js/client_edit.js') }}"></script>
</main>
@endsection @endsection

View File

@ -1,5 +1,3 @@
@extends('layouts.app') @extends('layouts.app')
<h1>Contact homepage</h1> <h1>Contact homepage</h1>