Refactor clients (#2513)

* attempting to bind vue to blade partials

* typo for vue

* working on client contact page

* refactor shipping-billing addresses back to client model

* clean up
This commit is contained in:
David Bomba 2018-11-21 19:28:07 +11:00 committed by GitHub
parent af9ae06289
commit 0f66625cdf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 352 additions and 100420 deletions

View File

@ -107,7 +107,10 @@ class ClientController extends Controller
*/
public function show($id)
{
//
$client = Client::find(2);
$client->load('contacts', 'primary_contact');
return response()->json($client, 200);
}
/**
@ -119,7 +122,7 @@ class ClientController extends Controller
public function edit(EditClientRequest $request, Client $client)
{
$client->load('contacts', 'primary_billing_location', 'primary_shipping_location', 'locations', 'primary_contact');
$client->load('contacts', 'primary_contact');
$data = [
'header' => $this->headerData(),
@ -147,7 +150,7 @@ class ClientController extends Controller
$client->contacts()->delete();
$client->contacts()->create($request->input('contacts'));
$client->load('contacts', 'primary_billing_location', 'primary_shipping_location', 'locations', 'primary_contact');
$client->load('contacts', 'primary_contact');
return response()->json($client, 200);

View File

@ -26,7 +26,7 @@ class Client extends BaseModel
return 'client_id';
}
public function getClientIdAttribute()
public function getHashedIdAttribute()
{
return $this->encodePrimaryKey($this->id);
}
@ -36,21 +36,6 @@ class Client extends BaseModel
return $this->hasMany(ClientContact::class);
}
public function locations()
{
return $this->hasMany(ClientLocation::class);
}
public function primary_billing_location()
{
return $this->hasOne(ClientLocation::class)->whereIsPrimaryBilling(true);
}
public function primary_shipping_location()
{
return $this->hasOne(ClientLocation::class)->whereIsPrimaryShipping(true);
}
public function primary_contact()
{
return $this->hasMany(ClientContact::class)->whereIsPrimary(true);

View File

@ -7,33 +7,29 @@ use Hashids\Hashids;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laracasts\Presenter\PresentableTrait;
class ClientContact extends Authenticatable
{
use Notifiable;
use MakesHash;
protected $appends = ['contact_id'];
use PresentableTrait;
// protected $appends = ['contact_id'];
protected $guard = 'contact';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $presenter = 'App\Models\Presenters\ClientContactPresenter';
protected $guarded = [
'id',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
'id',
'password',
'remember_token',
];

View File

@ -14,7 +14,17 @@ $factory->define(App\Models\Client::class, function (Faker $faker) {
'custom_value1' => $faker->text(20),
'custom_value2' => $faker->text(20),
'payment_terms' => $faker->text(40),
'address1' => $faker->buildingNumber,
'address2' => $faker->streetAddress,
'city' => $faker->city,
'state' => $faker->state,
'postal_code' => $faker->postcode,
'country_id' => 4,
'shipping_address1' => $faker->buildingNumber,
'shipping_address2' => $faker->streetAddress,
'shipping_city' => $faker->city,
'shipping_state' => $faker->state,
'shipping_postal_code' => $faker->postcode,
'shipping_country_id' => 4,
];
});

View File

@ -222,6 +222,20 @@ class CreateUsersTable extends Migration
$table->unsignedInteger('size_id')->nullable();
$table->unsignedInteger('currency_id')->nullable();
$table->string('address1')->nullable();
$table->string('address2')->nullable();
$table->string('city')->nullable();
$table->string('state')->nullable();
$table->string('postal_code')->nullable();
$table->unsignedInteger('country_id')->nullable();
$table->string('shipping_address1')->nullable();
$table->string('shipping_address2')->nullable();
$table->string('shipping_city')->nullable();
$table->string('shipping_state')->nullable();
$table->string('shipping_postal_code')->nullable();
$table->unsignedInteger('shipping_country_id')->nullable();
$table->boolean('is_deleted')->default(false);
$table->string('payment_terms')->nullable(); //todo type? depends how we are storing this

View File

@ -76,7 +76,7 @@ class RandomDataSeeder extends Seeder
'client_id' => $c->id,
'company_id' => $company->id
]);
/*
factory(\App\Models\ClientLocation::class,1)->create([
'client_id' => $c->id,
'is_primary_billing' => 1
@ -85,7 +85,7 @@ class RandomDataSeeder extends Seeder
factory(\App\Models\ClientLocation::class,10)->create([
'client_id' => $c->id,
]);
*/
});

16890
public/css/ninja.css vendored

File diff suppressed because one or more lines are too long

16890
public/css/ninja.min.css vendored

File diff suppressed because one or more lines are too long

33244
public/js/ninja.js vendored

File diff suppressed because one or more lines are too long

33244
public/js/ninja.min.js vendored

File diff suppressed because one or more lines are too long

7
resources/js/app.js vendored
View File

@ -17,14 +17,13 @@ window.axios.defaults.headers.common = {
};
/* Allows us to use our native translation easily using {{ trans() }} syntax */
const _ = require('lodash');
Vue.prototype.trans = string => _.get(window.i18n, string);
//const _ = require('lodash');
//Vue.prototype.trans = string => _.get(window.i18n, string);
/**
* Next, we will create a fresh Vue application instance and attach it to
* the page. Then, you may begin adding components to this application
* or customize the JavaScript scaffolding to fit your unique needs.
*/
Vue.component('example-component', require('./components/ExampleComponent.vue'));
Vue.component('client-edit', require('./components/client/ClientEdit.vue'));
@ -32,7 +31,7 @@ Vue.component('client-primary-address', require('./components/client/ClientPrima
Vue.component('generic-address', require('./components/generic/Address.vue'));
Vue.component('client-edit-form', require('./components/client/ClientEditForm.vue'));
Vue.component('contact-edit', require('./components/client/ClientContactEdit.vue'));
*/
window.onload = function () {
const app = new Vue({

View File

@ -1,11 +1,107 @@
@extends('layouts.master', ['header' => $header])
@section('body')
<main class="main" id="app">
<main class="main" id="client_edit">
<!-- Breadcrumb-->
{{ Breadcrumbs::render('clients.edit', $client) }}
<client-edit-form v-bind:clientdata="{{ $client }}"></client-edit-form>
<form>
<div class="container-fluid">
<div class="row form-group">
<div class="col-md-12">
<span class="float-right">
<div class="btn-group ml-2">
<button class="btn btn-lg btn-success" type="button"><i class="fa fa-save"></i> {{ trans('texts.save') }}</button>
<button class="btn btn-lg btn-success dropdown-toggle dropdown-toggle-split" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="sr-only">Toggle Dropdown</span>
</button>
<div class="dropdown-menu">
<a class="dropdown-item" href="#"><i class="fa fa-plus-circle"></i> {{ trans('texts.add_contact') }}</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">{{ trans('texts.archive_client') }}</a>
<a class="dropdown-item" href="#">{{ trans('texts.delete_client') }}</a>
</div>
</div>
</span>
</div>
</div>
<div class="row">
<!-- Client Details and Address Column -->
<div class="col-md-6">
@include('client.partial.client_details', $client)
@include('client.partial.client_location')
</div>
<!-- End Client Details and Address Column -->
<!-- Contact Details Column -->
<div class="col-md-6">
<div class="card">
<div class="card-header bg-primary2">{{ trans('texts.contact_information') }}
<span class="float-right">
<button type="button" class="btn btn-primary btn-sm"><i class="fa fa-plus-circle"></i> {{ trans('texts.add_contact') }}</button>
</span>
</div>
<template v-for="contact in client.contacts">
@include('client.partial.contact_details')
</template>
</div>
</div>
<!-- End Contact Details Column -->
</div>
</div>
</form>
<script>
new Vue({
el : '#client_edit',
data: function () {
return {
'client': [],
'errors': [],
}
},
mounted() {
console.log('Component mounted.')
//this.getItinerary()
this.client = {!! $client !!}
},
beforeMount: function () {
console.log('before mount')
},
created:function() {
console.dir('created')
},
updated:function() {
console.dir('updated');
},
methods:{
copy(type) {
console.dir('inside ');
if(type.includes('copy_billing')){
this.client.shipping_address1 = this.client.address1;
this.client.shipping_address2 = this.client.address2;
this.client.shipping_city = this.client.city;
this.client.shipping_state = this.client.state;
this.client.shipping_postal_code = this.client.postal_code;
this.client.shipping_country_id = this.client.country_id;
}else {
this.client.address1 = this.client.shipping_address1;
this.client.address2 = this.client.shipping_address2;
this.client.city = this.client.shipping_city;
this.client.state = this.client.shipping_state;
this.client.postal_code = this.client.shipping_postal_code;
this.client.country_id = this.client.shipping_country_id;
}
}
}
});
</script>
</main>

View File

@ -1,48 +1,45 @@
<div class="col-lg-5">
<div class="card">
<div class="card-header bg-primary">@lang('texts.edit_client')</div>
<div class="card-body">
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.client_name')</label>
<div class="col-sm-9">
{{ html()->input('name')->placeholder(__('texts.client_name'))->value($client->present()->name)->class('form-control')->id('name') }}
</div>
<div class="card">
<div class="card-header bg-primary2">@lang('texts.edit_client')</div>
<div class="card-body">
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.client_name')</label>
<div class="col-sm-9">
<input name="name" placeholder="@lang('texts.name')" class="form-control" v-model="client.name" value="{{ $client->present()->name }}" id="name">
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.id_number')</label>
<div class="col-sm-9">
{{ html()->input('id_number')->placeholder(__('texts.id_number'))->value($client->id_number)->class('form-control')->id('id_number') }}
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.id_number')</label>
<div class="col-sm-9">
<input name="id_number" placeholder="@lang('texts.id_number')" class="form-control" v-model="client.id_number">
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.vat_number')</label>
<div class="col-sm-9">
{{ html()->input('vat_number')->placeholder(__('texts.vat_number'))->value($client->vat_number)->class('form-control')->id('vat_number') }}
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.vat_number')</label>
<div class="col-sm-9">
<input name="vat_number" placeholder="@lang('texts.vat_number')" class="form-control" v-model="client.vat_number">
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.website')</label>
<div class="col-sm-9">
{{ html()->input('website')->placeholder(__('texts.website'))->value($client->website)->class('form-control')->id('website') }}
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.website')</label>
<div class="col-sm-9">
<input name="website" placeholder="@lang('texts.website')" class="form-control" v-model="client.website">
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.custom_value1')</label>
<div class="col-sm-9">
{{ html()->input('custom_value1')->placeholder(__('texts.custom_value1'))->value($client->custom_value1)->class('form-control')->id('custom_value1') }}
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.custom_value1')</label>
<div class="col-sm-9">
<input name="custom_value1" placeholder="@lang('texts.custom_value1')" class="form-control" v-model="client.custom_value1">
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.custom_value2')</label>
<div class="col-sm-9">
{{ html()->input('custom_value2')->placeholder(__('texts.custom_value2'))->value($client->custom_value2)->class('form-control')->id('custom_value2') }}
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.custom_value2')</label>
<div class="col-sm-9">
<input name="custom_value2" placeholder="@lang('texts.custom_value2')" class="form-control" v-model="client.custom_value2">
</div>
</div>
</div>

View File

@ -1,50 +1,112 @@
<div class="card">
<div class="card-header bg-primary">{{ $address }}</div>
<div class="card-header bg-primary2">{{ trans('texts.address') }}</div>
<div>
<ul class="nav nav-tabs" role="tablist">
<li class="nav-item">
<a class="nav-link active" data-toggle="tab" href="#billing" role="tab" aria-controls="billing">{{ trans('texts.billing_address') }}</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#shipping" role="tab" aria-controls="shipping">{{ trans('texts.shipping_address') }}</a>
</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="billing" role="tabpanel">
<button type="button" class="btn btn-sm btn-light" @click="copy('copy_shipping')"> {{ trans('texts.copy_shipping') }}</button>
<div class="card-body">
<div class="form-group row">
<label for="name" class="col-lg-3 col-form-label text-right">@lang('texts.address1')</label>
<div class="col-lg-9">
<input name="address1" placeholder="@lang('texts.address1')" class="form-control" v-model="client.address1">
</div>
</div>
<div class="card-body">
<div class="form-group row">
<label for="name" class="col-lg-3 col-form-label text-right">@lang('texts.address1')</label>
<div class="col-lg-9">
{{ html()->input('address1')->placeholder(__('texts.address1'))->value($location->address1)->class('form-control')->id('address1') }}
<div class="form-group row">
<label for="name" class="col-lg-3 col-form-label text-right">@lang('texts.address2')</label>
<div class="col-lg-9">
<input name="address2" placeholder="@lang('texts.address2')" class="form-control" v-model="client.address2" id="address2">
</div>
</div>
<div class="form-group row">
<label for="name" class="col-lg-3 col-form-label text-right">@lang('texts.city')</label>
<div class="col-lg-9">
<input name="city" placeholder="@lang('texts.city')" class="form-control" v-model="client.city" id="city">
</div>
</div>
<div class="form-group row">
<label for="name" class="col-lg-3 col-form-label text-right">@lang('texts.state')</label>
<div class="col-lg-9">
<input name="state" placeholder="@lang('texts.state')" class="form-control" v-model="client.state" id="state">
</div>
</div>
<div class="form-group row">
<label for="name" class="col-lg-3 col-form-label text-right">@lang('texts.postal_code')</label>
<div class="col-lg-9">
<input name="postal_code" placeholder="@lang('texts.postal_code')" class="form-control" v-model="client.postal_code" id="postal_code">
</div>
</div>
<div class="form-group row">
<label for="name" class="col-lg-3 col-form-label text-right">@lang('texts.country')</label>
<div class="col-lg-9">
<input name="country_id" placeholder="@lang('texts.country')" class="form-control" v-model="client.country_id" id="country">
</div>
</div>
</div>
</div>
<div class="tab-pane" id="shipping" role="tabpanel">
<button type="button" class="btn btn-sm btn-light" @click="copy('copy_billing')"> {{ trans('texts.copy_billing') }}</button>
<div class="card-body">
<div class="form-group row">
<label for="name" class="col-lg-3 col-form-label text-right">@lang('texts.address1')</label>
<div class="col-lg-9">
<input name="shipping_address1" placeholder="@lang('texts.address1')" class="form-control" v-model="client.shipping_address1">
</div>
</div>
<div class="form-group row">
<label for="name" class="col-lg-3 col-form-label text-right">@lang('texts.address2')</label>
<div class="col-lg-9">
<input name="shipping_address2" placeholder="@lang('texts.address2')" class="form-control" v-model="client.shipping_address2" id="address2">
</div>
</div>
<div class="form-group row">
<label for="name" class="col-lg-3 col-form-label text-right">@lang('texts.city')</label>
<div class="col-lg-9">
<input name="shipping_city" placeholder="@lang('texts.city')" class="form-control" v-model="client.shipping_city" id="city">
</div>
</div>
<div class="form-group row">
<label for="name" class="col-lg-3 col-form-label text-right">@lang('texts.state')</label>
<div class="col-lg-9">
<input name="shipping_state" placeholder="@lang('texts.state')" class="form-control" v-model="client.shipping_state" id="state">
</div>
</div>
<div class="form-group row">
<label for="name" class="col-lg-3 col-form-label text-right">@lang('texts.postal_code')</label>
<div class="col-lg-9">
<input name="shipping_postal_code" placeholder="@lang('texts.postal_code')" class="form-control" v-model="client.shipping_postal_code" id="postal_code">
</div>
</div>
<div class="form-group row">
<label for="name" class="col-lg-3 col-form-label text-right">@lang('texts.country')</label>
<div class="col-lg-9">
<input name="shipping_country_id" placeholder="@lang('texts.country')" class="form-control" v-model="client.shipping_country_id" id="country">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="form-group row">
<label for="name" class="col-lg-3 col-form-label text-right">@lang('texts.address2')</label>
<div class="col-lg-9">
{{ html()->input('address2')->placeholder(__('texts.address2'))->value($location->address2)->class('form-control')->id('address2') }}
</div>
</div>
<div class="form-group row">
<label for="name" class="col-lg-3 col-form-label text-right">@lang('texts.city')</label>
<div class="col-lg-9">
{{ html()->input('city')->placeholder(__('texts.city'))->value($location->city)->class('form-control')->id('city') }}
</div>
</div>
<div class="form-group row">
<label for="name" class="col-lg-3 col-form-label text-right">@lang('texts.state')</label>
<div class="col-lg-9">
{{ html()->input('state')->placeholder(__('texts.state'))->value($location->state)->class('form-control')->id('state') }}
</div>
</div>
<div class="form-group row">
<label for="name" class="col-lg-3 col-form-label text-right">@lang('texts.postal_code')</label>
<div class="col-lg-9">
{{ html()->input('postal_code')->placeholder(__('texts.postal_code'))->value($location->postal_code)->class('form-control')->id('postal_code') }}
</div>
</div>
<div class="form-group row">
<label for="name" class="col-lg-3 col-form-label text-right">@lang('texts.country')</label>
<div class="col-lg-9">
{{ html()->input('country')->placeholder(__('texts.country'))->value($location->country)->class('form-control')->id('country') }}
</div>
</div>
</div>
</div>

View File

@ -1,51 +1,49 @@
<div class="col-lg-6">
<div class="card">
<div class="card-header bg-primary">@lang('texts.contact_information')</div>
<div class="card-body">
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.first_name')</label>
<div class="col-sm-9">
{{ html()->input('first_name')->placeholder(__('texts.first_name'))->value($contact->first_name)->class('form-control')->id('first_name') }}
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.last_name')</label>
<div class="col-sm-9">
{{ html()->input('last_name')->placeholder(__('texts.last_name'))->value($contact->last_name)->class('form-control')->id('last_name') }}
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.email')</label>
<div class="col-sm-9">
{{ html()->input('email')->placeholder(__('texts.email'))->value($contact->first_name)->class('form-control')->id('email') }}
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.phone')</label>
<div class="col-sm-9">
{{ html()->input('phone')->placeholder(__('texts.phone'))->value($contact->phone)->class('form-control')->id('phone') }}
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.custom_value1')</label>
<div class="col-sm-9">
{{ html()->input('custom_value1')->placeholder(__('texts.custom_value1'))->value($contact->custom_value1)->class('form-control')->id('custom_value1') }}
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.custom_value2')</label>
<div class="col-sm-9">
{{ html()->input('custom_value2')->placeholder(__('texts.custom_value2'))->value($contact->custom_value2)->class('form-control')->id('custom_value2') }}
</div>
</div>
<div class="card-body">
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.first_name')</label>
<div class="col-sm-9">
<input name="id" type="hidden" v-model="contact.id" value="{{ $client->present()->id }}">
<input name="first_name" placeholder="@lang('texts.first_name')" class="form-control" v-model="contact.first_name">
</div>
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.last_name')</label>
<div class="col-sm-9">
<input name="last_name" placeholder="@lang('texts.last_name')" class="form-control" v-model="contact.last_name">
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.email')</label>
<div class="col-sm-9">
<input name="email" placeholder="@lang('texts.email')" class="form-control" v-model="contact.email">
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.phone')</label>
<div class="col-sm-9">
<input name="phone" placeholder="@lang('texts.phone')" class="form-control" v-model="contact.phone">
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.custom_value1')</label>
<div class="col-sm-9">
<input name="custom_value1" placeholder="@lang('texts.custom_value1')" class="form-control" v-model="contact.custom_value1">
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.custom_value2')</label>
<div class="col-sm-9">
<input name="custom_value2" placeholder="@lang('texts.custom_value2')" class="form-control" v-model="contact.custom_value2">
</div>
</div>
<div class="float-right">
<button type="button" class="btn btn-danger" v-on:click="$emit('remove',contact.id)"> {{ trans('texts.remove_contact') }}</button>
</div>
</div>