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

Explicit route model binding (#2498)

* Switch to explicit route model binding
This commit is contained in:
David Bomba 2018-11-12 18:52:20 +11:00 committed by GitHub
parent b989cf82b7
commit 6769ade16f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 1536 additions and 84 deletions

View File

@ -116,11 +116,9 @@ class ClientController extends Controller
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit(EditClientRequest $request)
public function edit(EditClientRequest $request, Client $client)
{
$client = $request->entity(Client::class, request('client'));
$client->load('contacts', 'primary_billing_location', 'primary_shipping_location', 'locations', 'primary_contact');
$data = [
@ -141,8 +139,7 @@ class ClientController extends Controller
*/
public function update(UpdateClientRequest $request, $id)
{
\Illuminate\Support\Facades\Log::error(print_r($request->input('contacts'),1));
$client = $request->entity(Client::class, request('client'));
$client->fill($request->all())->save();

View File

@ -5,39 +5,28 @@ namespace App\Models;
use Laracasts\Presenter\PresentableTrait;
use Hashids\Hashids;
use App\Utils\Traits\MakesHash;
use Illuminate\Database\Eloquent\SoftDeletes;
class Client extends BaseModel
{
use PresentableTrait;
use MakesHash;
use SoftDeletes;
protected $presenter = 'App\Models\Presenters\ClientPresenter';
protected $appends = ['hash_id'];
protected $appends = ['client_id'];
protected $fillable = [
'name',
'id_number',
'vat_number',
'work_phone',
'custom_value1',
'custom_value2',
'address1',
'address2',
'city',
'state',
'postal_code',
'country_id',
'private_notes',
'size_id',
'industry_id',
'currency_id',
'language_id',
'payment_terms',
'website',
protected $guarded = [
'id'
];
public function getHashIdAttribute()
public function getRouteKeyName()
{
return 'client_id';
}
public function getClientIdAttribute()
{
return $this->encodePrimaryKey($this->id);
}
@ -54,12 +43,12 @@ class Client extends BaseModel
public function primary_billing_location()
{
return $this->hasMany(ClientLocation::class)->whereIsPrimaryBilling(true);
return $this->hasOne(ClientLocation::class)->whereIsPrimaryBilling(true);
}
public function primary_shipping_location()
{
return $this->hasMany(ClientLocation::class)->whereIsPrimaryShipping(true);
return $this->hasOne(ClientLocation::class)->whereIsPrimaryShipping(true);
}
public function primary_contact()

View File

@ -7,6 +7,7 @@ use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvi
class RouteServiceProvider extends ServiceProvider
{
use \App\Utils\Traits\MakesHash;
/**
* This namespace is applied to your controller routes.
*
@ -26,6 +27,10 @@ class RouteServiceProvider extends ServiceProvider
//
parent::boot();
Route::bind('client', function ($value) {
return \App\Models\Client::where('id', $this->decodePrimaryKey($value))->first() ?? abort(404);
});
}
/**

706
public/js/ninja.js vendored
View File

@ -2664,6 +2664,11 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
//
//
//
//
//
//
//
//
/* harmony default export */ __webpack_exports__["default"] = ({
props: ['client', 'errors']
@ -2732,6 +2737,8 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
//
//
//
//
//
/* harmony default export */ __webpack_exports__["default"] = ({
data: function data() {
@ -2752,6 +2759,13 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
this.client = this.clientdata;
},
methods: {
copy: function copy(type) {
if (type.includes('copy_billing')) {
this.client.primary_shipping_location = Object.assign({}, this.client.primary_billing_location);
} else {
this.client.primary_billing_location = Object.assign({}, this.client.primary_shipping_location);
}
},
remove: function remove(itemId) {
this.client.contacts = this.client.contacts.filter(function (item) {
return itemId != item.id;
@ -2768,6 +2782,8 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
}).catch(function (error) {
if (error.response.status === 422) {
_this.errors = error.response.data.errors || {};
} else if (error.response.status === 419) {
//csrf token has expired, we'll need to force a page reload
}
});
}
@ -2784,6 +2800,106 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/***/ }),
/***/ "./node_modules/babel-loader/lib/index.js?{\"cacheDirectory\":true,\"presets\":[[\"env\",{\"modules\":false,\"targets\":{\"browsers\":[\"> 2%\"],\"uglify\":true}}]],\"plugins\":[\"transform-object-rest-spread\",[\"transform-runtime\",{\"polyfill\":false,\"helpers\":false}]]}!./node_modules/vue-loader/lib/selector.js?type=script&index=0!./resources/js/components/client/ClientPrimaryAddress.vue":
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
/* harmony default export */ __webpack_exports__["default"] = ({
props: ['client']
});
/***/ }),
/***/ "./node_modules/babel-loader/lib/index.js?{\"cacheDirectory\":true,\"presets\":[[\"env\",{\"modules\":false,\"targets\":{\"browsers\":[\"> 2%\"],\"uglify\":true}}]],\"plugins\":[\"transform-object-rest-spread\",[\"transform-runtime\",{\"polyfill\":false,\"helpers\":false}]]}!./node_modules/vue-loader/lib/selector.js?type=script&index=0!./resources/js/components/generic/Address.vue":
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
/* harmony default export */ __webpack_exports__["default"] = ({
props: ['data', 'errors'],
default: function _default() {}
});
/***/ }),
/***/ "./node_modules/is-buffer/index.js":
/***/ (function(module, exports) {
@ -20533,6 +20649,303 @@ if (false) {
/***/ }),
/***/ "./node_modules/vue-loader/lib/template-compiler/index.js?{\"id\":\"data-v-8ea46bbe\",\"hasScoped\":false,\"buble\":{\"transforms\":{}}}!./node_modules/vue-loader/lib/selector.js?type=template&index=0!./resources/js/components/generic/Address.vue":
/***/ (function(module, exports, __webpack_require__) {
var render = function() {
var _vm = this
var _h = _vm.$createElement
var _c = _vm._self._c || _h
return _c("div", { staticClass: "card-body" }, [
_c("div", { staticClass: "form-group row" }, [
_c(
"label",
{
staticClass: "col-sm-3 col-form-label text-right",
attrs: { for: "name" }
},
[_vm._v(_vm._s(_vm.trans("texts.address1")))]
),
_vm._v(" "),
_c("div", { staticClass: "col-sm-9" }, [
_c("input", {
directives: [
{
name: "model",
rawName: "v-model",
value: _vm.data.address1,
expression: "data.address1"
}
],
staticClass: "form-control",
attrs: {
type: "text",
name: "address1",
placeholder: _vm.trans("texts.address1"),
id: "address1"
},
domProps: { value: _vm.data.address1 },
on: {
input: function($event) {
if ($event.target.composing) {
return
}
_vm.$set(_vm.data, "address1", $event.target.value)
}
}
}),
_vm._v(" "),
_vm.errors && _vm.errors.address1
? _c("div", { staticClass: "text-danger" }, [
_vm._v(_vm._s(_vm.errors.address1[0]))
])
: _vm._e()
])
]),
_vm._v(" "),
_c("div", { staticClass: "form-group row" }, [
_c(
"label",
{
staticClass: "col-sm-3 col-form-label text-right",
attrs: { for: "name" }
},
[_vm._v(_vm._s(_vm.trans("texts.address2")))]
),
_vm._v(" "),
_c("div", { staticClass: "col-sm-9" }, [
_c("input", {
directives: [
{
name: "model",
rawName: "v-model",
value: _vm.data.address2,
expression: "data.address2"
}
],
staticClass: "form-control",
attrs: {
type: "text",
name: "address2",
placeholder: _vm.trans("texts.address2"),
id: "address2"
},
domProps: { value: _vm.data.address2 },
on: {
input: function($event) {
if ($event.target.composing) {
return
}
_vm.$set(_vm.data, "address2", $event.target.value)
}
}
}),
_vm._v(" "),
_vm.errors && _vm.errors.address2
? _c("div", { staticClass: "text-danger" }, [
_vm._v(_vm._s(_vm.errors.address2[0]))
])
: _vm._e()
])
]),
_vm._v(" "),
_c("div", { staticClass: "form-group row" }, [
_c(
"label",
{
staticClass: "col-sm-3 col-form-label text-right",
attrs: { for: "name" }
},
[_vm._v(_vm._s(_vm.trans("texts.city")))]
),
_vm._v(" "),
_c("div", { staticClass: "col-sm-9" }, [
_c("input", {
directives: [
{
name: "model",
rawName: "v-model",
value: _vm.data.city,
expression: "data.city"
}
],
staticClass: "form-control",
attrs: {
type: "text",
name: "city",
placeholder: _vm.trans("texts.city"),
id: "city"
},
domProps: { value: _vm.data.city },
on: {
input: function($event) {
if ($event.target.composing) {
return
}
_vm.$set(_vm.data, "city", $event.target.value)
}
}
}),
_vm._v(" "),
_vm.errors && _vm.errors.city
? _c("div", { staticClass: "text-danger" }, [
_vm._v(_vm._s(_vm.errors.city[0]))
])
: _vm._e()
])
]),
_vm._v(" "),
_c("div", { staticClass: "form-group row" }, [
_c(
"label",
{
staticClass: "col-sm-3 col-form-label text-right",
attrs: { for: "name" }
},
[_vm._v(_vm._s(_vm.trans("texts.state")))]
),
_vm._v(" "),
_c("div", { staticClass: "col-sm-9" }, [
_c("input", {
directives: [
{
name: "model",
rawName: "v-model",
value: _vm.data.state,
expression: "data.state"
}
],
staticClass: "form-control",
attrs: {
type: "text",
name: "state",
placeholder: _vm.trans("texts.state"),
id: "state"
},
domProps: { value: _vm.data.state },
on: {
input: function($event) {
if ($event.target.composing) {
return
}
_vm.$set(_vm.data, "state", $event.target.value)
}
}
}),
_vm._v(" "),
_vm.errors && _vm.errors.state
? _c("div", { staticClass: "text-danger" }, [
_vm._v(_vm._s(_vm.errors.state[0]))
])
: _vm._e()
])
]),
_vm._v(" "),
_c("div", { staticClass: "form-group row" }, [
_c(
"label",
{
staticClass: "col-sm-3 col-form-label text-right",
attrs: { for: "name" }
},
[_vm._v(_vm._s(_vm.trans("texts.postal_code")))]
),
_vm._v(" "),
_c("div", { staticClass: "col-sm-9" }, [
_c("input", {
directives: [
{
name: "model",
rawName: "v-model",
value: _vm.data.postal_code,
expression: "data.postal_code"
}
],
staticClass: "form-control",
attrs: {
type: "text",
name: "postal_code",
placeholder: _vm.trans("texts.postal_code"),
id: "postal_code"
},
domProps: { value: _vm.data.postal_code },
on: {
input: function($event) {
if ($event.target.composing) {
return
}
_vm.$set(_vm.data, "postal_code", $event.target.value)
}
}
}),
_vm._v(" "),
_vm.errors && _vm.errors.postal_code
? _c("div", { staticClass: "text-danger" }, [
_vm._v(_vm._s(_vm.errors.postal_code[0]))
])
: _vm._e()
])
]),
_vm._v(" "),
_c("div", { staticClass: "form-group row" }, [
_c(
"label",
{
staticClass: "col-sm-3 col-form-label text-right",
attrs: { for: "name" }
},
[_vm._v(_vm._s(_vm.trans("texts.country")))]
),
_vm._v(" "),
_c("div", { staticClass: "col-sm-9" }, [
_c("input", {
directives: [
{
name: "model",
rawName: "v-model",
value: _vm.data.country,
expression: "data.country"
}
],
staticClass: "form-control",
attrs: {
type: "text",
name: "country",
placeholder: _vm.trans("texts.country"),
id: "country"
},
domProps: { value: _vm.data.country },
on: {
input: function($event) {
if ($event.target.composing) {
return
}
_vm.$set(_vm.data, "country", $event.target.value)
}
}
}),
_vm._v(" "),
_vm.errors && _vm.errors.country
? _c("div", { staticClass: "text-danger" }, [
_vm._v(_vm._s(_vm.errors.country[0]))
])
: _vm._e()
])
])
])
}
var staticRenderFns = []
render._withStripped = true
module.exports = { render: render, staticRenderFns: staticRenderFns }
if (false) {
module.hot.accept()
if (module.hot.data) {
require("vue-hot-reload-api") .rerender("data-v-8ea46bbe", module.exports)
}
}
/***/ }),
/***/ "./node_modules/vue-loader/lib/template-compiler/index.js?{\"id\":\"data-v-924a4434\",\"hasScoped\":false,\"buble\":{\"transforms\":{}}}!./node_modules/vue-loader/lib/selector.js?type=template&index=0!./resources/js/components/client/ClientContactEdit.vue":
/***/ (function(module, exports, __webpack_require__) {
@ -20814,6 +21227,127 @@ if (false) {
/***/ }),
/***/ "./node_modules/vue-loader/lib/template-compiler/index.js?{\"id\":\"data-v-f01efeb4\",\"hasScoped\":false,\"buble\":{\"transforms\":{}}}!./node_modules/vue-loader/lib/selector.js?type=template&index=0!./resources/js/components/client/ClientPrimaryAddress.vue":
/***/ (function(module, exports, __webpack_require__) {
var render = function() {
var _vm = this
var _h = _vm.$createElement
var _c = _vm._self._c || _h
return _c("div", [
_c("ul", { staticClass: "nav nav-tabs", attrs: { role: "tablist" } }, [
_c("li", { staticClass: "nav-item" }, [
_c(
"a",
{
staticClass: "nav-link active",
attrs: {
"data-toggle": "tab",
href: "#billing",
role: "tab",
"aria-controls": "billing"
}
},
[_vm._v(_vm._s(_vm.trans("texts.billing_address")))]
)
]),
_vm._v(" "),
_c("li", { staticClass: "nav-item" }, [
_c(
"a",
{
staticClass: "nav-link",
attrs: {
"data-toggle": "tab",
href: "#shipping",
role: "tab",
"aria-controls": "shipping"
}
},
[_vm._v(_vm._s(_vm.trans("texts.shipping_address")))]
)
])
]),
_vm._v(" "),
_c("div", { staticClass: "tab-content" }, [
_c(
"div",
{
staticClass: "tab-pane active",
attrs: { id: "billing", role: "tabpanel" }
},
[
_c(
"button",
{
staticClass: "btn btn-sm btn-light",
attrs: { type: "button" },
on: {
click: function($event) {
_vm.$emit("copy", "copy_shipping")
}
}
},
[_vm._v(" " + _vm._s(_vm.trans("texts.copy_shipping")))]
),
_vm._v(" "),
_c("generic-address", {
attrs: {
data: _vm.client.primary_billing_location
? _vm.client.primary_billing_location
: "null"
}
})
],
1
),
_vm._v(" "),
_c(
"div",
{
staticClass: "tab-pane",
attrs: { id: "shipping", role: "tabpanel" }
},
[
_c(
"button",
{
staticClass: "btn btn-sm btn-light",
attrs: { type: "button" },
on: {
click: function($event) {
_vm.$emit("copy", " copy_billing")
}
}
},
[_vm._v(" " + _vm._s(_vm.trans("texts.copy_billing")))]
),
_vm._v(" "),
_c("generic-address", {
attrs: {
data: _vm.client.primary_shipping_location
? _vm.client.primary_shipping_location
: "null"
}
})
],
1
)
])
])
}
var staticRenderFns = []
render._withStripped = true
module.exports = { render: render, staticRenderFns: staticRenderFns }
if (false) {
module.hot.accept()
if (module.hot.data) {
require("vue-hot-reload-api") .rerender("data-v-f01efeb4", module.exports)
}
}
/***/ }),
/***/ "./node_modules/vue-loader/lib/template-compiler/index.js?{\"id\":\"data-v-f2594bfc\",\"hasScoped\":false,\"buble\":{\"transforms\":{}}}!./node_modules/vue-loader/lib/selector.js?type=template&index=0!./resources/js/components/client/ClientEditForm.vue":
/***/ (function(module, exports, __webpack_require__) {
@ -20896,6 +21430,22 @@ var render = function() {
})
],
1
),
_vm._v(" "),
_c(
"div",
{ staticClass: "card" },
[
_c("div", { staticClass: "card-header bg-primary2" }, [
_vm._v(_vm._s(_vm.trans("texts.address")))
]),
_vm._v(" "),
_c("client-primary-address", {
attrs: { client: _vm.client },
on: { copy: _vm.copy }
})
],
1
)
]),
_vm._v(" "),
@ -20907,7 +21457,7 @@ var render = function() {
_c("div", { staticClass: "card-header bg-primary2" }, [
_vm._v(
_vm._s(_vm.trans("texts.contact_information")) +
"\n "
"\n "
),
_c("span", { staticClass: "float-right" }, [
_c(
@ -21016,14 +21566,14 @@ var render = function() {
_vm.$set(_vm.client, "name", $event.target.value)
}
}
})
]),
_vm._v(" "),
_vm.errors && _vm.errors.name
? _c("div", { staticClass: "text-danger" }, [
_vm._v(_vm._s(_vm.errors.name[0]))
])
: _vm._e()
}),
_vm._v(" "),
_vm.errors && _vm.errors.name
? _c("div", { staticClass: "text-danger" }, [
_vm._v(_vm._s(_vm.errors.name[0]))
])
: _vm._e()
])
]),
_vm._v(" "),
_c("div", { staticClass: "form-group row" }, [
@ -21062,7 +21612,13 @@ var render = function() {
_vm.$set(_vm.client, "id_number", $event.target.value)
}
}
})
}),
_vm._v(" "),
_vm.errors && _vm.errors.id_number
? _c("div", { staticClass: "text-danger" }, [
_vm._v(_vm._s(_vm.errors.id_number[0]))
])
: _vm._e()
])
]),
_vm._v(" "),
@ -21102,7 +21658,13 @@ var render = function() {
_vm.$set(_vm.client, "vat_number", $event.target.value)
}
}
})
}),
_vm._v(" "),
_vm.errors && _vm.errors.vat_number
? _c("div", { staticClass: "text-danger" }, [
_vm._v(_vm._s(_vm.errors.vat_number[0]))
])
: _vm._e()
])
]),
_vm._v(" "),
@ -21142,7 +21704,13 @@ var render = function() {
_vm.$set(_vm.client, "website", $event.target.value)
}
}
})
}),
_vm._v(" "),
_vm.errors && _vm.errors.website
? _c("div", { staticClass: "text-danger" }, [
_vm._v(_vm._s(_vm.errors.website[0]))
])
: _vm._e()
])
]),
_vm._v(" "),
@ -21183,7 +21751,13 @@ var render = function() {
_vm.$set(_vm.client, "custom_value1", $event.target.value)
}
}
})
}),
_vm._v(" "),
_vm.errors && _vm.errors.custom_value1
? _c("div", { staticClass: "text-danger" }, [
_vm._v(_vm._s(_vm.errors.custom_value1[0]))
])
: _vm._e()
])
])
: _vm._e(),
@ -21224,7 +21798,13 @@ var render = function() {
_vm.$set(_vm.client, "custom_value2", $event.target.value)
}
}
})
}),
_vm._v(" "),
_vm.errors && _vm.errors.custom_value2
? _c("div", { staticClass: "text-danger" }, [
_vm._v(_vm._s(_vm.errors.custom_value2[0]))
])
: _vm._e()
])
])
])
@ -32301,6 +32881,8 @@ Vue.prototype.trans = function (string) {
Vue.component('example-component', __webpack_require__("./resources/js/components/ExampleComponent.vue"));
Vue.component('client-edit', __webpack_require__("./resources/js/components/client/ClientEdit.vue"));
Vue.component('client-primary-address', __webpack_require__("./resources/js/components/client/ClientPrimaryAddress.vue"));
Vue.component('generic-address', __webpack_require__("./resources/js/components/generic/Address.vue"));
Vue.component('client-edit-form', __webpack_require__("./resources/js/components/client/ClientEditForm.vue"));
Vue.component('contact-edit', __webpack_require__("./resources/js/components/client/ClientContactEdit.vue"));
@ -32549,6 +33131,102 @@ if (false) {(function () {
module.exports = Component.exports
/***/ }),
/***/ "./resources/js/components/client/ClientPrimaryAddress.vue":
/***/ (function(module, exports, __webpack_require__) {
var disposed = false
var normalizeComponent = __webpack_require__("./node_modules/vue-loader/lib/component-normalizer.js")
/* script */
var __vue_script__ = __webpack_require__("./node_modules/babel-loader/lib/index.js?{\"cacheDirectory\":true,\"presets\":[[\"env\",{\"modules\":false,\"targets\":{\"browsers\":[\"> 2%\"],\"uglify\":true}}]],\"plugins\":[\"transform-object-rest-spread\",[\"transform-runtime\",{\"polyfill\":false,\"helpers\":false}]]}!./node_modules/vue-loader/lib/selector.js?type=script&index=0!./resources/js/components/client/ClientPrimaryAddress.vue")
/* template */
var __vue_template__ = __webpack_require__("./node_modules/vue-loader/lib/template-compiler/index.js?{\"id\":\"data-v-f01efeb4\",\"hasScoped\":false,\"buble\":{\"transforms\":{}}}!./node_modules/vue-loader/lib/selector.js?type=template&index=0!./resources/js/components/client/ClientPrimaryAddress.vue")
/* template functional */
var __vue_template_functional__ = false
/* styles */
var __vue_styles__ = null
/* scopeId */
var __vue_scopeId__ = null
/* moduleIdentifier (server only) */
var __vue_module_identifier__ = null
var Component = normalizeComponent(
__vue_script__,
__vue_template__,
__vue_template_functional__,
__vue_styles__,
__vue_scopeId__,
__vue_module_identifier__
)
Component.options.__file = "resources/js/components/client/ClientPrimaryAddress.vue"
/* hot reload */
if (false) {(function () {
var hotAPI = require("vue-hot-reload-api")
hotAPI.install(require("vue"), false)
if (!hotAPI.compatible) return
module.hot.accept()
if (!module.hot.data) {
hotAPI.createRecord("data-v-f01efeb4", Component.options)
} else {
hotAPI.reload("data-v-f01efeb4", Component.options)
}
module.hot.dispose(function (data) {
disposed = true
})
})()}
module.exports = Component.exports
/***/ }),
/***/ "./resources/js/components/generic/Address.vue":
/***/ (function(module, exports, __webpack_require__) {
var disposed = false
var normalizeComponent = __webpack_require__("./node_modules/vue-loader/lib/component-normalizer.js")
/* script */
var __vue_script__ = __webpack_require__("./node_modules/babel-loader/lib/index.js?{\"cacheDirectory\":true,\"presets\":[[\"env\",{\"modules\":false,\"targets\":{\"browsers\":[\"> 2%\"],\"uglify\":true}}]],\"plugins\":[\"transform-object-rest-spread\",[\"transform-runtime\",{\"polyfill\":false,\"helpers\":false}]]}!./node_modules/vue-loader/lib/selector.js?type=script&index=0!./resources/js/components/generic/Address.vue")
/* template */
var __vue_template__ = __webpack_require__("./node_modules/vue-loader/lib/template-compiler/index.js?{\"id\":\"data-v-8ea46bbe\",\"hasScoped\":false,\"buble\":{\"transforms\":{}}}!./node_modules/vue-loader/lib/selector.js?type=template&index=0!./resources/js/components/generic/Address.vue")
/* template functional */
var __vue_template_functional__ = false
/* styles */
var __vue_styles__ = null
/* scopeId */
var __vue_scopeId__ = null
/* moduleIdentifier (server only) */
var __vue_module_identifier__ = null
var Component = normalizeComponent(
__vue_script__,
__vue_template__,
__vue_template_functional__,
__vue_styles__,
__vue_scopeId__,
__vue_module_identifier__
)
Component.options.__file = "resources/js/components/generic/Address.vue"
/* hot reload */
if (false) {(function () {
var hotAPI = require("vue-hot-reload-api")
hotAPI.install(require("vue"), false)
if (!hotAPI.compatible) return
module.hot.accept()
if (!module.hot.data) {
hotAPI.createRecord("data-v-8ea46bbe", Component.options)
} else {
hotAPI.reload("data-v-8ea46bbe", Component.options)
}
module.hot.dispose(function (data) {
disposed = true
})
})()}
module.exports = Component.exports
/***/ }),
/***/ 0:

706
public/js/ninja.min.js vendored
View File

@ -2664,6 +2664,11 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
//
//
//
//
//
//
//
//
/* harmony default export */ __webpack_exports__["default"] = ({
props: ['client', 'errors']
@ -2732,6 +2737,8 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
//
//
//
//
//
/* harmony default export */ __webpack_exports__["default"] = ({
data: function data() {
@ -2752,6 +2759,13 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
this.client = this.clientdata;
},
methods: {
copy: function copy(type) {
if (type.includes('copy_billing')) {
this.client.primary_shipping_location = Object.assign({}, this.client.primary_billing_location);
} else {
this.client.primary_billing_location = Object.assign({}, this.client.primary_shipping_location);
}
},
remove: function remove(itemId) {
this.client.contacts = this.client.contacts.filter(function (item) {
return itemId != item.id;
@ -2768,6 +2782,8 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
}).catch(function (error) {
if (error.response.status === 422) {
_this.errors = error.response.data.errors || {};
} else if (error.response.status === 419) {
//csrf token has expired, we'll need to force a page reload
}
});
}
@ -2784,6 +2800,106 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/***/ }),
/***/ "./node_modules/babel-loader/lib/index.js?{\"cacheDirectory\":true,\"presets\":[[\"env\",{\"modules\":false,\"targets\":{\"browsers\":[\"> 2%\"],\"uglify\":true}}]],\"plugins\":[\"transform-object-rest-spread\",[\"transform-runtime\",{\"polyfill\":false,\"helpers\":false}]]}!./node_modules/vue-loader/lib/selector.js?type=script&index=0!./resources/js/components/client/ClientPrimaryAddress.vue":
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
/* harmony default export */ __webpack_exports__["default"] = ({
props: ['client']
});
/***/ }),
/***/ "./node_modules/babel-loader/lib/index.js?{\"cacheDirectory\":true,\"presets\":[[\"env\",{\"modules\":false,\"targets\":{\"browsers\":[\"> 2%\"],\"uglify\":true}}]],\"plugins\":[\"transform-object-rest-spread\",[\"transform-runtime\",{\"polyfill\":false,\"helpers\":false}]]}!./node_modules/vue-loader/lib/selector.js?type=script&index=0!./resources/js/components/generic/Address.vue":
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
/* harmony default export */ __webpack_exports__["default"] = ({
props: ['data', 'errors'],
default: function _default() {}
});
/***/ }),
/***/ "./node_modules/is-buffer/index.js":
/***/ (function(module, exports) {
@ -20533,6 +20649,303 @@ if (false) {
/***/ }),
/***/ "./node_modules/vue-loader/lib/template-compiler/index.js?{\"id\":\"data-v-8ea46bbe\",\"hasScoped\":false,\"buble\":{\"transforms\":{}}}!./node_modules/vue-loader/lib/selector.js?type=template&index=0!./resources/js/components/generic/Address.vue":
/***/ (function(module, exports, __webpack_require__) {
var render = function() {
var _vm = this
var _h = _vm.$createElement
var _c = _vm._self._c || _h
return _c("div", { staticClass: "card-body" }, [
_c("div", { staticClass: "form-group row" }, [
_c(
"label",
{
staticClass: "col-sm-3 col-form-label text-right",
attrs: { for: "name" }
},
[_vm._v(_vm._s(_vm.trans("texts.address1")))]
),
_vm._v(" "),
_c("div", { staticClass: "col-sm-9" }, [
_c("input", {
directives: [
{
name: "model",
rawName: "v-model",
value: _vm.data.address1,
expression: "data.address1"
}
],
staticClass: "form-control",
attrs: {
type: "text",
name: "address1",
placeholder: _vm.trans("texts.address1"),
id: "address1"
},
domProps: { value: _vm.data.address1 },
on: {
input: function($event) {
if ($event.target.composing) {
return
}
_vm.$set(_vm.data, "address1", $event.target.value)
}
}
}),
_vm._v(" "),
_vm.errors && _vm.errors.address1
? _c("div", { staticClass: "text-danger" }, [
_vm._v(_vm._s(_vm.errors.address1[0]))
])
: _vm._e()
])
]),
_vm._v(" "),
_c("div", { staticClass: "form-group row" }, [
_c(
"label",
{
staticClass: "col-sm-3 col-form-label text-right",
attrs: { for: "name" }
},
[_vm._v(_vm._s(_vm.trans("texts.address2")))]
),
_vm._v(" "),
_c("div", { staticClass: "col-sm-9" }, [
_c("input", {
directives: [
{
name: "model",
rawName: "v-model",
value: _vm.data.address2,
expression: "data.address2"
}
],
staticClass: "form-control",
attrs: {
type: "text",
name: "address2",
placeholder: _vm.trans("texts.address2"),
id: "address2"
},
domProps: { value: _vm.data.address2 },
on: {
input: function($event) {
if ($event.target.composing) {
return
}
_vm.$set(_vm.data, "address2", $event.target.value)
}
}
}),
_vm._v(" "),
_vm.errors && _vm.errors.address2
? _c("div", { staticClass: "text-danger" }, [
_vm._v(_vm._s(_vm.errors.address2[0]))
])
: _vm._e()
])
]),
_vm._v(" "),
_c("div", { staticClass: "form-group row" }, [
_c(
"label",
{
staticClass: "col-sm-3 col-form-label text-right",
attrs: { for: "name" }
},
[_vm._v(_vm._s(_vm.trans("texts.city")))]
),
_vm._v(" "),
_c("div", { staticClass: "col-sm-9" }, [
_c("input", {
directives: [
{
name: "model",
rawName: "v-model",
value: _vm.data.city,
expression: "data.city"
}
],
staticClass: "form-control",
attrs: {
type: "text",
name: "city",
placeholder: _vm.trans("texts.city"),
id: "city"
},
domProps: { value: _vm.data.city },
on: {
input: function($event) {
if ($event.target.composing) {
return
}
_vm.$set(_vm.data, "city", $event.target.value)
}
}
}),
_vm._v(" "),
_vm.errors && _vm.errors.city
? _c("div", { staticClass: "text-danger" }, [
_vm._v(_vm._s(_vm.errors.city[0]))
])
: _vm._e()
])
]),
_vm._v(" "),
_c("div", { staticClass: "form-group row" }, [
_c(
"label",
{
staticClass: "col-sm-3 col-form-label text-right",
attrs: { for: "name" }
},
[_vm._v(_vm._s(_vm.trans("texts.state")))]
),
_vm._v(" "),
_c("div", { staticClass: "col-sm-9" }, [
_c("input", {
directives: [
{
name: "model",
rawName: "v-model",
value: _vm.data.state,
expression: "data.state"
}
],
staticClass: "form-control",
attrs: {
type: "text",
name: "state",
placeholder: _vm.trans("texts.state"),
id: "state"
},
domProps: { value: _vm.data.state },
on: {
input: function($event) {
if ($event.target.composing) {
return
}
_vm.$set(_vm.data, "state", $event.target.value)
}
}
}),
_vm._v(" "),
_vm.errors && _vm.errors.state
? _c("div", { staticClass: "text-danger" }, [
_vm._v(_vm._s(_vm.errors.state[0]))
])
: _vm._e()
])
]),
_vm._v(" "),
_c("div", { staticClass: "form-group row" }, [
_c(
"label",
{
staticClass: "col-sm-3 col-form-label text-right",
attrs: { for: "name" }
},
[_vm._v(_vm._s(_vm.trans("texts.postal_code")))]
),
_vm._v(" "),
_c("div", { staticClass: "col-sm-9" }, [
_c("input", {
directives: [
{
name: "model",
rawName: "v-model",
value: _vm.data.postal_code,
expression: "data.postal_code"
}
],
staticClass: "form-control",
attrs: {
type: "text",
name: "postal_code",
placeholder: _vm.trans("texts.postal_code"),
id: "postal_code"
},
domProps: { value: _vm.data.postal_code },
on: {
input: function($event) {
if ($event.target.composing) {
return
}
_vm.$set(_vm.data, "postal_code", $event.target.value)
}
}
}),
_vm._v(" "),
_vm.errors && _vm.errors.postal_code
? _c("div", { staticClass: "text-danger" }, [
_vm._v(_vm._s(_vm.errors.postal_code[0]))
])
: _vm._e()
])
]),
_vm._v(" "),
_c("div", { staticClass: "form-group row" }, [
_c(
"label",
{
staticClass: "col-sm-3 col-form-label text-right",
attrs: { for: "name" }
},
[_vm._v(_vm._s(_vm.trans("texts.country")))]
),
_vm._v(" "),
_c("div", { staticClass: "col-sm-9" }, [
_c("input", {
directives: [
{
name: "model",
rawName: "v-model",
value: _vm.data.country,
expression: "data.country"
}
],
staticClass: "form-control",
attrs: {
type: "text",
name: "country",
placeholder: _vm.trans("texts.country"),
id: "country"
},
domProps: { value: _vm.data.country },
on: {
input: function($event) {
if ($event.target.composing) {
return
}
_vm.$set(_vm.data, "country", $event.target.value)
}
}
}),
_vm._v(" "),
_vm.errors && _vm.errors.country
? _c("div", { staticClass: "text-danger" }, [
_vm._v(_vm._s(_vm.errors.country[0]))
])
: _vm._e()
])
])
])
}
var staticRenderFns = []
render._withStripped = true
module.exports = { render: render, staticRenderFns: staticRenderFns }
if (false) {
module.hot.accept()
if (module.hot.data) {
require("vue-hot-reload-api") .rerender("data-v-8ea46bbe", module.exports)
}
}
/***/ }),
/***/ "./node_modules/vue-loader/lib/template-compiler/index.js?{\"id\":\"data-v-924a4434\",\"hasScoped\":false,\"buble\":{\"transforms\":{}}}!./node_modules/vue-loader/lib/selector.js?type=template&index=0!./resources/js/components/client/ClientContactEdit.vue":
/***/ (function(module, exports, __webpack_require__) {
@ -20814,6 +21227,127 @@ if (false) {
/***/ }),
/***/ "./node_modules/vue-loader/lib/template-compiler/index.js?{\"id\":\"data-v-f01efeb4\",\"hasScoped\":false,\"buble\":{\"transforms\":{}}}!./node_modules/vue-loader/lib/selector.js?type=template&index=0!./resources/js/components/client/ClientPrimaryAddress.vue":
/***/ (function(module, exports, __webpack_require__) {
var render = function() {
var _vm = this
var _h = _vm.$createElement
var _c = _vm._self._c || _h
return _c("div", [
_c("ul", { staticClass: "nav nav-tabs", attrs: { role: "tablist" } }, [
_c("li", { staticClass: "nav-item" }, [
_c(
"a",
{
staticClass: "nav-link active",
attrs: {
"data-toggle": "tab",
href: "#billing",
role: "tab",
"aria-controls": "billing"
}
},
[_vm._v(_vm._s(_vm.trans("texts.billing_address")))]
)
]),
_vm._v(" "),
_c("li", { staticClass: "nav-item" }, [
_c(
"a",
{
staticClass: "nav-link",
attrs: {
"data-toggle": "tab",
href: "#shipping",
role: "tab",
"aria-controls": "shipping"
}
},
[_vm._v(_vm._s(_vm.trans("texts.shipping_address")))]
)
])
]),
_vm._v(" "),
_c("div", { staticClass: "tab-content" }, [
_c(
"div",
{
staticClass: "tab-pane active",
attrs: { id: "billing", role: "tabpanel" }
},
[
_c(
"button",
{
staticClass: "btn btn-sm btn-light",
attrs: { type: "button" },
on: {
click: function($event) {
_vm.$emit("copy", "copy_shipping")
}
}
},
[_vm._v(" " + _vm._s(_vm.trans("texts.copy_shipping")))]
),
_vm._v(" "),
_c("generic-address", {
attrs: {
data: _vm.client.primary_billing_location
? _vm.client.primary_billing_location
: "null"
}
})
],
1
),
_vm._v(" "),
_c(
"div",
{
staticClass: "tab-pane",
attrs: { id: "shipping", role: "tabpanel" }
},
[
_c(
"button",
{
staticClass: "btn btn-sm btn-light",
attrs: { type: "button" },
on: {
click: function($event) {
_vm.$emit("copy", " copy_billing")
}
}
},
[_vm._v(" " + _vm._s(_vm.trans("texts.copy_billing")))]
),
_vm._v(" "),
_c("generic-address", {
attrs: {
data: _vm.client.primary_shipping_location
? _vm.client.primary_shipping_location
: "null"
}
})
],
1
)
])
])
}
var staticRenderFns = []
render._withStripped = true
module.exports = { render: render, staticRenderFns: staticRenderFns }
if (false) {
module.hot.accept()
if (module.hot.data) {
require("vue-hot-reload-api") .rerender("data-v-f01efeb4", module.exports)
}
}
/***/ }),
/***/ "./node_modules/vue-loader/lib/template-compiler/index.js?{\"id\":\"data-v-f2594bfc\",\"hasScoped\":false,\"buble\":{\"transforms\":{}}}!./node_modules/vue-loader/lib/selector.js?type=template&index=0!./resources/js/components/client/ClientEditForm.vue":
/***/ (function(module, exports, __webpack_require__) {
@ -20896,6 +21430,22 @@ var render = function() {
})
],
1
),
_vm._v(" "),
_c(
"div",
{ staticClass: "card" },
[
_c("div", { staticClass: "card-header bg-primary2" }, [
_vm._v(_vm._s(_vm.trans("texts.address")))
]),
_vm._v(" "),
_c("client-primary-address", {
attrs: { client: _vm.client },
on: { copy: _vm.copy }
})
],
1
)
]),
_vm._v(" "),
@ -20907,7 +21457,7 @@ var render = function() {
_c("div", { staticClass: "card-header bg-primary2" }, [
_vm._v(
_vm._s(_vm.trans("texts.contact_information")) +
"\n "
"\n "
),
_c("span", { staticClass: "float-right" }, [
_c(
@ -21016,14 +21566,14 @@ var render = function() {
_vm.$set(_vm.client, "name", $event.target.value)
}
}
})
]),
_vm._v(" "),
_vm.errors && _vm.errors.name
? _c("div", { staticClass: "text-danger" }, [
_vm._v(_vm._s(_vm.errors.name[0]))
])
: _vm._e()
}),
_vm._v(" "),
_vm.errors && _vm.errors.name
? _c("div", { staticClass: "text-danger" }, [
_vm._v(_vm._s(_vm.errors.name[0]))
])
: _vm._e()
])
]),
_vm._v(" "),
_c("div", { staticClass: "form-group row" }, [
@ -21062,7 +21612,13 @@ var render = function() {
_vm.$set(_vm.client, "id_number", $event.target.value)
}
}
})
}),
_vm._v(" "),
_vm.errors && _vm.errors.id_number
? _c("div", { staticClass: "text-danger" }, [
_vm._v(_vm._s(_vm.errors.id_number[0]))
])
: _vm._e()
])
]),
_vm._v(" "),
@ -21102,7 +21658,13 @@ var render = function() {
_vm.$set(_vm.client, "vat_number", $event.target.value)
}
}
})
}),
_vm._v(" "),
_vm.errors && _vm.errors.vat_number
? _c("div", { staticClass: "text-danger" }, [
_vm._v(_vm._s(_vm.errors.vat_number[0]))
])
: _vm._e()
])
]),
_vm._v(" "),
@ -21142,7 +21704,13 @@ var render = function() {
_vm.$set(_vm.client, "website", $event.target.value)
}
}
})
}),
_vm._v(" "),
_vm.errors && _vm.errors.website
? _c("div", { staticClass: "text-danger" }, [
_vm._v(_vm._s(_vm.errors.website[0]))
])
: _vm._e()
])
]),
_vm._v(" "),
@ -21183,7 +21751,13 @@ var render = function() {
_vm.$set(_vm.client, "custom_value1", $event.target.value)
}
}
})
}),
_vm._v(" "),
_vm.errors && _vm.errors.custom_value1
? _c("div", { staticClass: "text-danger" }, [
_vm._v(_vm._s(_vm.errors.custom_value1[0]))
])
: _vm._e()
])
])
: _vm._e(),
@ -21224,7 +21798,13 @@ var render = function() {
_vm.$set(_vm.client, "custom_value2", $event.target.value)
}
}
})
}),
_vm._v(" "),
_vm.errors && _vm.errors.custom_value2
? _c("div", { staticClass: "text-danger" }, [
_vm._v(_vm._s(_vm.errors.custom_value2[0]))
])
: _vm._e()
])
])
])
@ -32301,6 +32881,8 @@ Vue.prototype.trans = function (string) {
Vue.component('example-component', __webpack_require__("./resources/js/components/ExampleComponent.vue"));
Vue.component('client-edit', __webpack_require__("./resources/js/components/client/ClientEdit.vue"));
Vue.component('client-primary-address', __webpack_require__("./resources/js/components/client/ClientPrimaryAddress.vue"));
Vue.component('generic-address', __webpack_require__("./resources/js/components/generic/Address.vue"));
Vue.component('client-edit-form', __webpack_require__("./resources/js/components/client/ClientEditForm.vue"));
Vue.component('contact-edit', __webpack_require__("./resources/js/components/client/ClientContactEdit.vue"));
@ -32549,6 +33131,102 @@ if (false) {(function () {
module.exports = Component.exports
/***/ }),
/***/ "./resources/js/components/client/ClientPrimaryAddress.vue":
/***/ (function(module, exports, __webpack_require__) {
var disposed = false
var normalizeComponent = __webpack_require__("./node_modules/vue-loader/lib/component-normalizer.js")
/* script */
var __vue_script__ = __webpack_require__("./node_modules/babel-loader/lib/index.js?{\"cacheDirectory\":true,\"presets\":[[\"env\",{\"modules\":false,\"targets\":{\"browsers\":[\"> 2%\"],\"uglify\":true}}]],\"plugins\":[\"transform-object-rest-spread\",[\"transform-runtime\",{\"polyfill\":false,\"helpers\":false}]]}!./node_modules/vue-loader/lib/selector.js?type=script&index=0!./resources/js/components/client/ClientPrimaryAddress.vue")
/* template */
var __vue_template__ = __webpack_require__("./node_modules/vue-loader/lib/template-compiler/index.js?{\"id\":\"data-v-f01efeb4\",\"hasScoped\":false,\"buble\":{\"transforms\":{}}}!./node_modules/vue-loader/lib/selector.js?type=template&index=0!./resources/js/components/client/ClientPrimaryAddress.vue")
/* template functional */
var __vue_template_functional__ = false
/* styles */
var __vue_styles__ = null
/* scopeId */
var __vue_scopeId__ = null
/* moduleIdentifier (server only) */
var __vue_module_identifier__ = null
var Component = normalizeComponent(
__vue_script__,
__vue_template__,
__vue_template_functional__,
__vue_styles__,
__vue_scopeId__,
__vue_module_identifier__
)
Component.options.__file = "resources/js/components/client/ClientPrimaryAddress.vue"
/* hot reload */
if (false) {(function () {
var hotAPI = require("vue-hot-reload-api")
hotAPI.install(require("vue"), false)
if (!hotAPI.compatible) return
module.hot.accept()
if (!module.hot.data) {
hotAPI.createRecord("data-v-f01efeb4", Component.options)
} else {
hotAPI.reload("data-v-f01efeb4", Component.options)
}
module.hot.dispose(function (data) {
disposed = true
})
})()}
module.exports = Component.exports
/***/ }),
/***/ "./resources/js/components/generic/Address.vue":
/***/ (function(module, exports, __webpack_require__) {
var disposed = false
var normalizeComponent = __webpack_require__("./node_modules/vue-loader/lib/component-normalizer.js")
/* script */
var __vue_script__ = __webpack_require__("./node_modules/babel-loader/lib/index.js?{\"cacheDirectory\":true,\"presets\":[[\"env\",{\"modules\":false,\"targets\":{\"browsers\":[\"> 2%\"],\"uglify\":true}}]],\"plugins\":[\"transform-object-rest-spread\",[\"transform-runtime\",{\"polyfill\":false,\"helpers\":false}]]}!./node_modules/vue-loader/lib/selector.js?type=script&index=0!./resources/js/components/generic/Address.vue")
/* template */
var __vue_template__ = __webpack_require__("./node_modules/vue-loader/lib/template-compiler/index.js?{\"id\":\"data-v-8ea46bbe\",\"hasScoped\":false,\"buble\":{\"transforms\":{}}}!./node_modules/vue-loader/lib/selector.js?type=template&index=0!./resources/js/components/generic/Address.vue")
/* template functional */
var __vue_template_functional__ = false
/* styles */
var __vue_styles__ = null
/* scopeId */
var __vue_scopeId__ = null
/* moduleIdentifier (server only) */
var __vue_module_identifier__ = null
var Component = normalizeComponent(
__vue_script__,
__vue_template__,
__vue_template_functional__,
__vue_styles__,
__vue_scopeId__,
__vue_module_identifier__
)
Component.options.__file = "resources/js/components/generic/Address.vue"
/* hot reload */
if (false) {(function () {
var hotAPI = require("vue-hot-reload-api")
hotAPI.install(require("vue"), false)
if (!hotAPI.compatible) return
module.hot.accept()
if (!module.hot.data) {
hotAPI.createRecord("data-v-8ea46bbe", Component.options)
} else {
hotAPI.reload("data-v-8ea46bbe", Component.options)
}
module.hot.dispose(function (data) {
disposed = true
})
})()}
module.exports = Component.exports
/***/ }),
/***/ 0:

2
resources/js/app.js vendored
View File

@ -28,6 +28,8 @@ Vue.prototype.trans = string => _.get(window.i18n, string);
Vue.component('example-component', require('./components/ExampleComponent.vue'));
Vue.component('client-edit', require('./components/client/ClientEdit.vue'));
Vue.component('client-primary-address', require('./components/client/ClientPrimaryAddress.vue'));
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'));

View File

@ -4,14 +4,15 @@
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.client_name') }}</label>
<div class="col-sm-9">
<input type="text" name="name" :placeholder="trans('texts.client_name')" v-model="client.name" class="form-control" id="name">
<div v-if="errors && errors.name" class="text-danger">{{ errors.name[0] }}</div>
</div>
<div v-if="errors && errors.name" class="text-danger">{{ errors.name[0] }}</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.id_number') }}</label>
<div class="col-sm-9">
<input type="text" name="id_number" :placeholder="trans('texts.id_number')" v-model="client.id_number" class="form-control" id="id_number">
<div v-if="errors && errors.id_number" class="text-danger">{{ errors.id_number[0] }}</div>
</div>
</div>
@ -19,6 +20,7 @@
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.vat_number') }}</label>
<div class="col-sm-9">
<input type="text" name="vat_number" :placeholder="trans('texts.vat_number')" v-model="client.vat_number" class="form-control" id="vat_number">
<div v-if="errors && errors.vat_number" class="text-danger">{{ errors.vat_number[0] }}</div>
</div>
</div>
@ -26,6 +28,7 @@
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.website') }}</label>
<div class="col-sm-9">
<input type="text" name="website" :placeholder="trans('texts.website')" v-model="client.website" class="form-control" id="websites">
<div v-if="errors && errors.website" class="text-danger">{{ errors.website[0] }}</div>
</div>
</div>
@ -33,6 +36,7 @@
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.custom_value1') }}</label>
<div class="col-sm-9">
<input type="text" name="custom_value1" :placeholder="trans('texts.custom_value1')" v-model="client.custom_value1" class="form-control" id="custom_value1">
<div v-if="errors && errors.custom_value1" class="text-danger">{{ errors.custom_value1[0] }}</div>
</div>
</div>
@ -40,6 +44,7 @@
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.custom_value2') }}</label>
<div class="col-sm-9">
<input type="text" name="custom_value2" :placeholder="trans('texts.custom_value2')" v-model="client.custom_value2" class="form-control" id="custom_value2">
<div v-if="errors && errors.custom_value2" class="text-danger">{{ errors.custom_value2[0] }}</div>
</div>
</div>
</div>

View File

@ -19,37 +19,39 @@
</span>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="card">
<div class="card-header bg-primary2">{{ trans('texts.edit_client') }}</div>
<!-- Client Details and Address Column -->
<div class="col-md-6">
<div class="card">
<div class="card-header bg-primary2">{{ trans('texts.edit_client') }}</div>
<client-edit :client="client" :errors="errors"></client-edit>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-header bg-primary2">{{ trans('texts.address') }}</div>
<client-primary-address v-bind:client="client" @copy="copy"></client-primary-address>
</div>
</div>
<!-- End Client Details and Address Column -->
<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>
<contact-edit v-for="(contact, index) in client.contacts"
v-bind:contact="contact"
v-bind:index="index"
:key="contact.id"
@remove="remove"></contact-edit>
</div>
</div>
</div>
<!-- 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>
<contact-edit v-for="(contact, index) in client.contacts"
v-bind:contact="contact"
v-bind:index="index"
:key="contact.id"
@remove="remove"></contact-edit>
</div>
</div>
<!-- End Contact Details Column -->
</div>
</div>
</form>
</template>
@ -72,6 +74,13 @@ export default {
this.client = this.clientdata;
},
methods: {
copy(type) {
if(type.includes('copy_billing')){
this.client.primary_shipping_location = Object.assign({}, this.client.primary_billing_location);
}else {
this.client.primary_billing_location = Object.assign({}, this.client.primary_shipping_location);
}
},
remove (itemId) {
this.client.contacts = this.client.contacts.filter(function (item) {
return itemId != item.id;
@ -88,6 +97,9 @@ export default {
if (error.response.status === 422) {
this.errors = error.response.data.errors || {};
}
else if(error.response.status === 419) {
//csrf token has expired, we'll need to force a page reload
}
});
},

View File

@ -0,0 +1,28 @@
<template>
<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" v-on:click="$emit('copy', 'copy_shipping')"> {{ trans('texts.copy_shipping') }}</button>
<generic-address :data="client.primary_billing_location ? client.primary_billing_location : 'null'"></generic-address>
</div>
<div class="tab-pane" id="shipping" role="tabpanel">
<button type="button" class="btn btn-sm btn-light" v-on:click="$emit('copy',' copy_billing')"> {{ trans('texts.copy_billing') }}</button>
<generic-address :data="client.primary_shipping_location ? client.primary_shipping_location : 'null'"></generic-address>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['client']
}
</script>

View File

@ -0,0 +1,58 @@
<template>
<div class="card-body">
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.address1') }}</label>
<div class="col-sm-9">
<input type="text" name="address1" :placeholder="trans('texts.address1')" v-model="data.address1" class="form-control" id="address1">
<div v-if="errors && errors.address1" class="text-danger">{{ errors.address1[0] }}</div>
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.address2') }}</label>
<div class="col-sm-9">
<input type="text" name="address2" :placeholder="trans('texts.address2')" v-model="data.address2" class="form-control" id="address2">
<div v-if="errors && errors.address2" class="text-danger">{{ errors.address2[0] }}</div>
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.city') }}</label>
<div class="col-sm-9">
<input type="text" name="city" :placeholder="trans('texts.city')" v-model="data.city" class="form-control" id="city">
<div v-if="errors && errors.city" class="text-danger">{{ errors.city[0] }}</div>
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.state') }}</label>
<div class="col-sm-9">
<input type="text" name="state" :placeholder="trans('texts.state')" v-model="data.state" class="form-control" id="state">
<div v-if="errors && errors.state" class="text-danger">{{ errors.state[0] }}</div>
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.postal_code') }}</label>
<div class="col-sm-9">
<input type="text" name="postal_code" :placeholder="trans('texts.postal_code')" v-model="data.postal_code" class="form-control" id="postal_code">
<div v-if="errors && errors.postal_code" class="text-danger">{{ errors.postal_code[0] }}</div>
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.country') }}</label>
<div class="col-sm-9">
<input type="text" name="country" :placeholder="trans('texts.country')" v-model="data.country" class="form-control" id="country">
<div v-if="errors && errors.country" class="text-danger">{{ errors.country[0] }}</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['data', 'errors'],
default: () => {}
}
</script>