Rework on product name/description and translate
This commit is contained in:
parent
bfd17b0686
commit
b719efb58c
@ -84,7 +84,7 @@ class ProductController extends Controller
|
|||||||
|
|
||||||
public function details_addedit(ProductAddEdit $request,Product $o)
|
public function details_addedit(ProductAddEdit $request,Product $o)
|
||||||
{
|
{
|
||||||
foreach ($request->except(['_token','submit','description']) as $key => $item)
|
foreach ($request->except(['_token','submit','translate']) as $key => $item)
|
||||||
$o->{$key} = $item;
|
$o->{$key} = $item;
|
||||||
|
|
||||||
$o->active = (bool)$request->active;
|
$o->active = (bool)$request->active;
|
||||||
@ -95,13 +95,12 @@ class ProductController extends Controller
|
|||||||
return redirect()->back()->withErrors($e->getMessage())->withInput();
|
return redirect()->back()->withErrors($e->getMessage())->withInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
$o->load(['description']);
|
$o->load(['translate']);
|
||||||
$oo = $o->description ?: new ProductTranslate;
|
$oo = $o->translate ?: new ProductTranslate;
|
||||||
|
foreach ($request->get('translate',[]) as $key => $item)
|
||||||
foreach ($request->get('description',[]) as $key => $item)
|
|
||||||
$oo->{$key} = $item;
|
$oo->{$key} = $item;
|
||||||
|
|
||||||
$o->description()->save($oo);
|
$o->translate()->save($oo);
|
||||||
|
|
||||||
return redirect()->back()
|
return redirect()->back()
|
||||||
->with('success','Product saved');
|
->with('success','Product saved');
|
||||||
|
@ -28,7 +28,9 @@ class ProductAddEdit extends FormRequest
|
|||||||
public function rules()
|
public function rules()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'description.name' => 'required|string|min:2|max:100',
|
'translate.name_short' => 'required|string|min:2|max:100',
|
||||||
|
'translate.name_detail' => 'required|string|min:2|max:100',
|
||||||
|
'translate.description' => 'required|string|min:2|max:255',
|
||||||
'active' => 'sometimes|accepted',
|
'active' => 'sometimes|accepted',
|
||||||
'model' => 'sometimes|string', // @todo Check that it is a valid model type
|
'model' => 'sometimes|string', // @todo Check that it is a valid model type
|
||||||
'model_id' => 'sometimes|int', // @todo Check that it is a valid model type
|
'model_id' => 'sometimes|int', // @todo Check that it is a valid model type
|
||||||
|
@ -31,9 +31,10 @@ use App\Traits\{ProductDetails,SiteID};
|
|||||||
* + category_name : Type of product supplied (Friendly Name for display, not for internal logic)
|
* + category_name : Type of product supplied (Friendly Name for display, not for internal logic)
|
||||||
* + supplied : Supplier product provided for this offering
|
* + supplied : Supplier product provided for this offering
|
||||||
* + supplier : Supplier for this offering
|
* + supplier : Supplier for this offering
|
||||||
* + name : Brief Name for our product // @todo we should change this to be consistent with service
|
* + name : Brief Name for our product with name_detail
|
||||||
* + name_short : Product ID for our Product
|
* + name_short : Product ID for our Product (description.name => name_short)
|
||||||
* + name_long : Long Name for our product
|
* + name_detail : Details of our product (description.description_short => name_detail)
|
||||||
|
* + description : Product description (description.description_full => description_full)
|
||||||
* + billing_interval : Default Billing Interval
|
* + billing_interval : Default Billing Interval
|
||||||
* + billing_interval_string: Default Billing Interval in human-readable form
|
* + billing_interval_string: Default Billing Interval in human-readable form
|
||||||
* + setup_charge : Charge to setup this product
|
* + setup_charge : Charge to setup this product
|
||||||
@ -73,21 +74,10 @@ class Product extends Model implements IDs
|
|||||||
'pricing'=>'collection',
|
'pricing'=>'collection',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $with = ['description'];
|
protected $with = ['translate'];
|
||||||
|
|
||||||
/* RELATIONS */
|
/* RELATIONS */
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the product name in the users language, and if the user isnt logged in, the sites language
|
|
||||||
*
|
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
|
||||||
*/
|
|
||||||
public function description()
|
|
||||||
{
|
|
||||||
return $this->hasOne(ProductTranslate::class)
|
|
||||||
->where('language_id',(Auth::user() && Auth::user()->language_id) ? Auth::user()->language_id : config('site')->language_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Which services are configured with this product
|
* Which services are configured with this product
|
||||||
*
|
*
|
||||||
@ -98,6 +88,17 @@ class Product extends Model implements IDs
|
|||||||
return $this->hasMany(Service::class);
|
return $this->hasMany(Service::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the product name in the users language, and if the user isnt logged in, the sites language
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
||||||
|
*/
|
||||||
|
public function translate()
|
||||||
|
{
|
||||||
|
return $this->hasOne(ProductTranslate::class)
|
||||||
|
->where('language_id',(Auth::user() && Auth::user()->language_id) ? Auth::user()->language_id : config('site')->language_id);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a child model with details of the service
|
* Return a child model with details of the service
|
||||||
* This will return a product/* model.
|
* This will return a product/* model.
|
||||||
@ -211,6 +212,16 @@ class Product extends Model implements IDs
|
|||||||
return $this->type->getContractTermAttribute();
|
return $this->type->getContractTermAttribute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This product full description
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getDescriptionAttribute(): string
|
||||||
|
{
|
||||||
|
return (($x=$this->translate) && $x->description) ? $x->description : 'No Description';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the minimum cost of this product
|
* Get the minimum cost of this product
|
||||||
*
|
*
|
||||||
@ -243,7 +254,17 @@ class Product extends Model implements IDs
|
|||||||
*/
|
*/
|
||||||
public function getNameAttribute(): string
|
public function getNameAttribute(): string
|
||||||
{
|
{
|
||||||
return $this->description ? $this->description->description_short : 'Unknown PRODUCT';
|
return $this->getNameShortAttribute().(($x=$this->getNameDetailAttribute()) ? ': '.$x : '');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Our products Long Name
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getNameDetailAttribute(): string
|
||||||
|
{
|
||||||
|
return $this->translate ? $this->translate->name_detail : 'Unknown Name';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -253,23 +274,13 @@ class Product extends Model implements IDs
|
|||||||
*/
|
*/
|
||||||
public function getNameShortAttribute(): string
|
public function getNameShortAttribute(): string
|
||||||
{
|
{
|
||||||
return $this->description ? $this->description->name : 'Unknown PID';
|
return $this->translate ? $this->translate->name_short : 'Unknown PID';
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This product full description
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getNameLongAttribute(): string
|
|
||||||
{
|
|
||||||
return $this->description->description_full;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Suppliers
|
* Suppliers
|
||||||
*
|
*
|
||||||
* @return Model
|
* @return Model|null
|
||||||
*/
|
*/
|
||||||
public function getSupplierAttribute(): ?Model
|
public function getSupplierAttribute(): ?Model
|
||||||
{
|
{
|
||||||
@ -279,7 +290,7 @@ class Product extends Model implements IDs
|
|||||||
/**
|
/**
|
||||||
* Suppliers product
|
* Suppliers product
|
||||||
*
|
*
|
||||||
* @return Model
|
* @return Model|null
|
||||||
*/
|
*/
|
||||||
public function getSuppliedAttribute(): ?Model
|
public function getSuppliedAttribute(): ?Model
|
||||||
{
|
{
|
||||||
|
@ -6,12 +6,7 @@ use Illuminate\Database\Eloquent\Model;
|
|||||||
|
|
||||||
class ProductTranslate extends Model
|
class ProductTranslate extends Model
|
||||||
{
|
{
|
||||||
protected $table = 'ab_product_translate';
|
protected $table = 'product_translate';
|
||||||
|
|
||||||
public $timestamps = FALSE;
|
public $timestamps = FALSE;
|
||||||
|
|
||||||
public function getDescriptionFullAttribute($value)
|
|
||||||
{
|
|
||||||
return unserialize($value);
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -328,7 +328,7 @@ class User extends Authenticatable implements IDs
|
|||||||
}
|
}
|
||||||
|
|
||||||
$result->load([
|
$result->load([
|
||||||
'product.description',
|
'product.translate',
|
||||||
'service.type',
|
'service.type',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
DB::statement('RENAME TABLE ab_product_translate TO product_translate');
|
||||||
|
DB::statement('ALTER TABLE product_translate MODIFY product_id int unsigned DEFAULT NULL');
|
||||||
|
DB::statement('ALTER TABLE product_translate MODIFY language_id int unsigned DEFAULT NULL');
|
||||||
|
|
||||||
|
DB::statement('ALTER TABLE product_translate RENAME COLUMN name TO name_short');
|
||||||
|
DB::statement('ALTER TABLE product_translate RENAME COLUMN description_short TO name_detail');
|
||||||
|
DB::statement('ALTER TABLE product_translate RENAME COLUMN description_full TO description');
|
||||||
|
|
||||||
|
Schema::table('product_translate', function (Blueprint $table) {
|
||||||
|
$table->dropForeign('ab_product_translate_site_id_foreign');
|
||||||
|
$table->dropIndex('ab_product_translate_id_site_id_index');
|
||||||
|
$table->dropIndex('ab_product_translate_site_id_foreign');
|
||||||
|
|
||||||
|
$table->foreign(['language_id'])->references(['id'])->on('languages');
|
||||||
|
$table->foreign(['product_id','site_id'])->references(['id','site_id'])->on('products');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
abort(500,'Cant go back');
|
||||||
|
}
|
||||||
|
};
|
@ -3,24 +3,56 @@
|
|||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<h3>Product Details @include('adminlte::widget.success_button')</h3>
|
<h3>Product Details @include('adminlte::widget.success_button')</h3>
|
||||||
<hr>
|
<hr>
|
||||||
|
@dump($errors)
|
||||||
|
|
||||||
<form class="g-0 needs-validation" method="POST" enctype="multipart/form-data" role="form">
|
<form class="g-0 needs-validation" method="POST" enctype="multipart/form-data" role="form">
|
||||||
@csrf
|
@csrf
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<!-- Product Name -->
|
<!-- Product ID -->
|
||||||
<div class="col-12 col-sm-9 col-md-12 col-xl-6">
|
<div class="col-12 col-sm-9 col-md-4 col-xl-3">
|
||||||
@include('adminlte::widget.form_text',[
|
@include('adminlte::widget.form_text',[
|
||||||
'label'=>'Product Name',
|
'label'=>'Product ID',
|
||||||
'icon'=>'fas fa-atom',
|
'icon'=>'fas fa-atom',
|
||||||
'id'=>'description.name',
|
'id'=>'translate.name_short',
|
||||||
'old'=>'description.name',
|
'old'=>'translate.name_short',
|
||||||
'name'=>'description[name]',
|
'name'=>'translate[name_short]',
|
||||||
'value'=>$o->name ?? '',
|
'value'=>$o->name_short ?? '',
|
||||||
])
|
])
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Product Name -->
|
||||||
|
<div class="col-12 col-sm-9 col-md-8 col-xl-9">
|
||||||
|
@include('adminlte::widget.form_text',[
|
||||||
|
'label'=>'Product Name',
|
||||||
|
'icon'=>'fas fa-atom',
|
||||||
|
'id'=>'translate.name_detail',
|
||||||
|
'old'=>'translate.name_detail',
|
||||||
|
'name'=>'translate[name_detail]',
|
||||||
|
'value'=>$o->name_detail ?? '',
|
||||||
|
])
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="form-group @error('description') is-invalid @enderror">
|
||||||
|
<!-- Product Description -->
|
||||||
|
<label for="description_full" class="col-form-label">Product Description</label>
|
||||||
|
<div class="input-group">
|
||||||
|
<div class="w-100">
|
||||||
|
<textarea class="textarea" id="description" name="translate[description]" placeholder="Full Description">{!! old('description',$o->description) ?? '' !!}</textarea>
|
||||||
|
<span class="invalid-feedback" role="alert">
|
||||||
|
@error('description')
|
||||||
|
{{ $message }}
|
||||||
|
@enderror
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
<!-- Active -->
|
<!-- Active -->
|
||||||
<div class="col-3">
|
<div class="col-3">
|
||||||
@include('adminlte::widget.form_toggle',[
|
@include('adminlte::widget.form_toggle',[
|
||||||
@ -43,7 +75,7 @@
|
|||||||
'old'=>'model',
|
'old'=>'model',
|
||||||
'name'=>'model',
|
'name'=>'model',
|
||||||
'options'=>$o->availableTypes()->transform(function($item) { return ['id'=>$item,'value'=>$item]; }),
|
'options'=>$o->availableTypes()->transform(function($item) { return ['id'=>$item,'value'=>$item]; }),
|
||||||
'value'=>get_class($o->type) ?? '',
|
'value'=>($o->type && $x=get_class($o->type)) ? $x : '',
|
||||||
])
|
])
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -97,7 +129,9 @@
|
|||||||
|
|
||||||
@section('page-scripts')
|
@section('page-scripts')
|
||||||
@css(select2)
|
@css(select2)
|
||||||
|
@css(simplemde)
|
||||||
@js(select2,autofocus)
|
@js(select2,autofocus)
|
||||||
|
@js(simplemde)
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
// Get a list of supplier items matching this type to populate model_id
|
// Get a list of supplier items matching this type to populate model_id
|
||||||
@ -129,6 +163,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
|
new SimpleMDE({ element: $('.textarea')[0], forceSync: true });
|
||||||
|
|
||||||
$('#model').on('change',function(item) {
|
$('#model').on('change',function(item) {
|
||||||
if ($(this).val()) {
|
if ($(this).val()) {
|
||||||
$('#supplier_product').show();
|
$('#supplier_product').show();
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('contentheader_title')
|
@section('contentheader_title')
|
||||||
Service: {{ $o->sid }} <strong>{{ $o->product->name }}</strong>
|
Service: {{ $o->sid }} <strong>{{ $o->product->name_detail }}</strong>
|
||||||
@endsection
|
@endsection
|
||||||
@section('contentheader_description')
|
@section('contentheader_description')
|
||||||
{{ $o->name }}
|
{{ $o->name }}
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
<td><a href="{{ url('u/service',[$oo->id]) }}">{{ $oo->sid }}</a></td>
|
<td><a href="{{ url('u/service',[$oo->id]) }}">{{ $oo->sid }}</a></td>
|
||||||
<td>{{ $oo->product->category_name }}</td>
|
<td>{{ $oo->product->category_name }}</td>
|
||||||
<td>{{ $oo->name_short }}</td>
|
<td>{{ $oo->name_short }}</td>
|
||||||
<td>{{ $oo->product->name }}</td>
|
<td>{{ $oo->product->name_short }}</td>
|
||||||
<td>{{ $oo->external_billing ? '-' : $oo->invoice_next->format('Y-m-d') }}</td>
|
<td>{{ $oo->external_billing ? '-' : $oo->invoice_next->format('Y-m-d') }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
@ -36,8 +36,8 @@
|
|||||||
@foreach($xx=$offering->items->with(['products.product.services'])->get() as $oo)
|
@foreach($xx=$offering->items->with(['products.product.services'])->get() as $oo)
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ $oo->id }}</td>
|
<td>{{ $oo->id }}</td>
|
||||||
<td>{{ $oo->name }}</td>
|
<td>{{ $oo->name_short }}</td>
|
||||||
<td>{{ $oo->name_long }}</td>
|
<td>{{ $oo->name_detail }}</td>
|
||||||
<td class="text-right">{{ $oo->active ? 'YES' : 'NO' }}</td>
|
<td class="text-right">{{ $oo->active ? 'YES' : 'NO' }}</td>
|
||||||
<td class="text-right">{{ number_format($oo->setup_cost_taxable,2) }}</td>
|
<td class="text-right">{{ number_format($oo->setup_cost_taxable,2) }}</td>
|
||||||
<td class="text-right">{{ number_format($oo->base_cost_taxable,2) }}</td>
|
<td class="text-right">{{ number_format($oo->base_cost_taxable,2) }}</td>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<!-- $o = Product::class -->
|
<!-- $o = Product::class -->
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<p>{!! $o->name_long !!}</p>
|
<p>{!! $o->name_detail !!}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<table class="table table-condensed">
|
<table class="table table-condensed">
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<!-- $o = Product::class -->
|
<!-- $o = Product::class -->
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<p>{!! $o->name_long !!}</p>
|
<p>{!! $o->name_detail !!}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<table class="table table-condensed">
|
<table class="table table-condensed">
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<!-- $o = Product::class -->
|
<!-- $o = Product::class -->
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<p>{!! $o->name_long !!}</p>
|
<p>{!! $o->name_detail !!}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<table class="table table-condensed">
|
<table class="table table-condensed">
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<!-- $o = Product::class -->
|
<!-- $o = Product::class -->
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<p>{!! $o->name_long !!}</p>
|
<p>{!! $o->name_detail !!}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<table class="table table-condensed">
|
<table class="table table-condensed">
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<!-- $o = Product::class -->
|
<!-- $o = Product::class -->
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<p>{!! $o->name_long !!}</p>
|
<p>{!! $o->name_detail !!}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<table class="table table-condensed">
|
<table class="table table-condensed">
|
||||||
|
Loading…
Reference in New Issue
Block a user