mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-31 22:34:37 -04:00
Save Client / Contacts (#2523)
* View composers * Saving client and contacts * saving client and contacts * update client job * unique emails
This commit is contained in:
parent
cdb98ce528
commit
348890e8fa
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ class UpdateClientRequest extends Request
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'name' => 'required',
|
'name' => 'required',
|
||||||
|
'contacts.*.email' => 'email|unique:client_contacts,id'
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
41
app/Jobs/Client/UpdateClient.php
Normal file
41
app/Jobs/Client/UpdateClient.php
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
@ -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()
|
||||||
{
|
{
|
||||||
|
@ -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',
|
||||||
];
|
];
|
||||||
|
@ -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'
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -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
16916
public/css/ninja.css
vendored
File diff suppressed because one or more lines are too long
16916
public/css/ninja.min.css
vendored
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
13214
public/js/client_edit.js
vendored
File diff suppressed because one or more lines are too long
808
public/js/ninja.js
vendored
808
public/js/ninja.js
vendored
File diff suppressed because one or more lines are too long
808
public/js/ninja.min.js
vendored
808
public/js/ninja.min.js
vendored
File diff suppressed because one or more lines are too long
@ -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 => {
|
||||||
|
@ -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
|
@ -1,5 +1,3 @@
|
|||||||
@extends('layouts.app')
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<h1>Contact homepage</h1>
|
<h1>Contact homepage</h1>
|
Loading…
x
Reference in New Issue
Block a user