More work on ordering
This commit is contained in:
parent
499d44289e
commit
5373e6b246
@ -3,9 +3,13 @@
|
|||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
use App\Models\Product;
|
|
||||||
use Igaster\LaravelTheme\Facades\Theme;
|
use Igaster\LaravelTheme\Facades\Theme;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
use App\Models\{Product,Service};
|
||||||
|
use App\User;
|
||||||
|
|
||||||
class OrderController extends Controller
|
class OrderController extends Controller
|
||||||
{
|
{
|
||||||
@ -30,5 +34,50 @@ class OrderController extends Controller
|
|||||||
|
|
||||||
public function submit(Request $request)
|
public function submit(Request $request)
|
||||||
{
|
{
|
||||||
|
Validator::make($request->all(),[
|
||||||
|
'product_id'=>'required|exists:ab_product,id',
|
||||||
|
])
|
||||||
|
->sometimes('order_email','required|email',function($input) use ($request) {
|
||||||
|
return ($input->order_email AND ! $input->order_email_manual) OR (! $input->order_email_manual);
|
||||||
|
})
|
||||||
|
->sometimes('order_email_manual','required|email',function($input) use ($request) {
|
||||||
|
return $input->order_email_manual AND ! $input->order_email;
|
||||||
|
})->validate();
|
||||||
|
|
||||||
|
// Check the plugin details.
|
||||||
|
$po = Product::findOrFail($request->post('product_id'));
|
||||||
|
|
||||||
|
// Check we have the custom attributes for the product
|
||||||
|
$options = $po->orderValidation($request);
|
||||||
|
|
||||||
|
$uo = User::where('email','=',$request->post('order_email') ?: $request->post('order_email_manual'))->firstOrFail();
|
||||||
|
|
||||||
|
$ao = $request->input('account_id')
|
||||||
|
? $uo->accounts->where('account_id',$request->input('account_id'))
|
||||||
|
: $uo->accounts->first();
|
||||||
|
|
||||||
|
$so = new Service;
|
||||||
|
$so->id = Service::NextId();
|
||||||
|
|
||||||
|
// @todo Make this automatic
|
||||||
|
$so->site_id = config('SITE_SETUP')->id;
|
||||||
|
$so->product_id = $request->post('product_id');
|
||||||
|
$so->order_status = 'ORDER-SUBMIT';
|
||||||
|
$so->orderby_id = Auth::user()->id;
|
||||||
|
|
||||||
|
if ($options->order_info)
|
||||||
|
{
|
||||||
|
$so->order_info = $options->order_info;
|
||||||
|
unset($options->order_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
$so = $ao->services()->save($so);
|
||||||
|
|
||||||
|
if ($options instanceOf Model) {
|
||||||
|
$options->service_id = $so->id;
|
||||||
|
$options->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
return view('order_received',['o'=>$so]);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -20,4 +20,9 @@ class ResellerServicesController extends Controller
|
|||||||
{
|
{
|
||||||
return ['data'=>Auth::user()->all_clients()->values()];
|
return ['data'=>Auth::user()->all_clients()->values()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function service_movements()
|
||||||
|
{
|
||||||
|
return ['data'=>Auth::user()->all_client_service_movements()->values()];
|
||||||
|
}
|
||||||
}
|
}
|
30
app/Models/AdslPlan.php
Normal file
30
app/Models/AdslPlan.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
use App\Traits\OrderServiceOptions;
|
||||||
|
|
||||||
|
class AdslPlan extends Model
|
||||||
|
{
|
||||||
|
use OrderServiceOptions;
|
||||||
|
|
||||||
|
protected $table = 'ab_adsl_plan';
|
||||||
|
|
||||||
|
protected $order_attributes = [
|
||||||
|
'options.address'=>[
|
||||||
|
'request'=>'options.address',
|
||||||
|
'key'=>'service_address',
|
||||||
|
'validation'=>'required|string:10',
|
||||||
|
'validation_message'=>'Address is a required field.',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $order_model = ServiceAdsl::class;
|
||||||
|
|
||||||
|
public function product()
|
||||||
|
{
|
||||||
|
return $this->hasOne(AdslSupplierPlan::class,'id','adsl_supplier_plan_id');
|
||||||
|
}
|
||||||
|
}
|
15
app/Models/AdslSupplierPlan.php
Normal file
15
app/Models/AdslSupplierPlan.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class AdslSupplierPlan extends Model
|
||||||
|
{
|
||||||
|
protected $table = 'ab_adsl_supplier_plan';
|
||||||
|
|
||||||
|
public function getNameAttribute()
|
||||||
|
{
|
||||||
|
return $this->speed;
|
||||||
|
}
|
||||||
|
}
|
35
app/Models/PlanVoip.php
Normal file
35
app/Models/PlanVoip.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
use App\Traits\OrderServiceOptions;
|
||||||
|
|
||||||
|
class PlanVoip extends Model
|
||||||
|
{
|
||||||
|
use OrderServiceOptions;
|
||||||
|
|
||||||
|
protected $order_attributes = [
|
||||||
|
'options.phonenumber'=>[
|
||||||
|
'request'=>'options.phonenumber',
|
||||||
|
'key'=>'service_number',
|
||||||
|
'validation'=>'required|min:10',
|
||||||
|
'validation_message'=>'Phone Number is a required field.',
|
||||||
|
],
|
||||||
|
'options.supplier'=>[
|
||||||
|
'request'=>'options.supplier',
|
||||||
|
'key'=>'order_info.supplier',
|
||||||
|
'validation'=>'required|min:4',
|
||||||
|
'validation_message'=>'Phone Supplier is a required field.',
|
||||||
|
],
|
||||||
|
'options.supplieraccnum'=>[
|
||||||
|
'request'=>'options.supplieraccnum',
|
||||||
|
'key'=>'order_info.supplieraccnum',
|
||||||
|
'validation'=>'required|min:4',
|
||||||
|
'validation_message'=>'Phone Supplier Account Number is a required field.',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $order_model = ServiceVoip::class;
|
||||||
|
}
|
@ -4,6 +4,7 @@ namespace App\Models;
|
|||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class Product extends Model
|
class Product extends Model
|
||||||
{
|
{
|
||||||
@ -25,22 +26,93 @@ class Product extends Model
|
|||||||
return $this->prod_plugin_file;
|
return $this->prod_plugin_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getContractTermAttribute()
|
||||||
|
{
|
||||||
|
switch ($this->prod_plugin_file) {
|
||||||
|
case 'ADSL': return $this->plugin()->contract_term;
|
||||||
|
// @todo Incorporate into DB
|
||||||
|
case 'VOIP': return 12;
|
||||||
|
|
||||||
|
// @todo Change this after contracts implemented.
|
||||||
|
default:
|
||||||
|
return 'TBA';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDefaultBillingAttribute()
|
||||||
|
{
|
||||||
|
return array_get($this->PricePeriods(),$this->price_recurr_default);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDefaultCostAttribute()
|
||||||
|
{
|
||||||
|
// @todo Integrate this into a Tax::class
|
||||||
|
return array_get($this->price_array,sprintf('%s.1.price_base',$this->price_recurr_default))*1.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getDefaultLanguage()
|
||||||
|
{
|
||||||
|
return config('SITE_SETUP')->language;
|
||||||
|
}
|
||||||
|
|
||||||
public function getDescriptionAttribute()
|
public function getDescriptionAttribute()
|
||||||
{
|
{
|
||||||
// @todo If the user has selected a specific language.
|
// @todo If the user has selected a specific language.
|
||||||
return $this->description($this->getDefaultLanguage());
|
return $this->description($this->getDefaultLanguage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getMinimumCostAttribute()
|
||||||
|
{
|
||||||
|
$table = [
|
||||||
|
0=>4,
|
||||||
|
1=>1,
|
||||||
|
2=>1/3,
|
||||||
|
3=>1/6,
|
||||||
|
4=>1/12,
|
||||||
|
5=>1/24,
|
||||||
|
6=>1/36,
|
||||||
|
7=>1/48,
|
||||||
|
8=>1/60,
|
||||||
|
];
|
||||||
|
|
||||||
|
return $this->setup_cost + ( $this->default_cost * array_get($table,$this->price_recurr_default) * $this->contract_term);
|
||||||
|
}
|
||||||
|
|
||||||
public function getNameAttribute()
|
public function getNameAttribute()
|
||||||
{
|
{
|
||||||
return $this->name(Auth::user()->language);
|
return $this->name(Auth::user()->language);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getProductTypeAttribute()
|
||||||
|
{
|
||||||
|
return $this->plugin()->product->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPriceArrayAttribute()
|
||||||
|
{
|
||||||
|
return unserialize($this->price_group);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPriceTypeAttribute()
|
||||||
|
{
|
||||||
|
$table = [
|
||||||
|
0=>_('One-time Charge'),
|
||||||
|
1=>_('Recurring Membership/Subscription'),
|
||||||
|
2=>_('Trial for Membership/Subscription'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
public function getProductIdAttribute()
|
public function getProductIdAttribute()
|
||||||
{
|
{
|
||||||
return sprintf('#%04s',$this->id);
|
return sprintf('#%04s',$this->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getSetupCostAttribute()
|
||||||
|
{
|
||||||
|
// @todo Integrate this into a Tax::class
|
||||||
|
return array_get($this->price_array,sprintf('%s.1.price_setup',$this->price_recurr_default))*1.1;
|
||||||
|
}
|
||||||
|
|
||||||
public function scopeActive()
|
public function scopeActive()
|
||||||
{
|
{
|
||||||
return $this->where('active',TRUE);
|
return $this->where('active',TRUE);
|
||||||
@ -54,9 +126,34 @@ class Product extends Model
|
|||||||
return $this->descriptions->where('language_id',$lo->id)->first()->description_short;
|
return $this->descriptions->where('language_id',$lo->id)->first()->description_short;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getDefaultLanguage()
|
public function orderValidation(Request $request)
|
||||||
{
|
{
|
||||||
return config('SITE_SETUP')->language;
|
return $this->plugin()->orderValidation($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function plugin()
|
||||||
|
{
|
||||||
|
switch ($this->prod_plugin_file) {
|
||||||
|
case 'ADSL':
|
||||||
|
return AdslPlan::findOrFail($this->prod_plugin_data);
|
||||||
|
case 'VOIP':
|
||||||
|
return new PlanVoip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function PricePeriods()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
0=>_('Weekly'),
|
||||||
|
1=>_('Monthly'),
|
||||||
|
2=>_('Quarterly'),
|
||||||
|
3=>_('Semi-Annually'),
|
||||||
|
4=>_('Annually'),
|
||||||
|
5=>_('Two years'),
|
||||||
|
6=>_('Three Years'),
|
||||||
|
7=>_('Four Years'),
|
||||||
|
8=>_('Five Years'),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3,14 +3,25 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use App\Traits\NextKey;
|
||||||
|
|
||||||
class Service extends Model
|
class Service extends Model
|
||||||
{
|
{
|
||||||
|
use NextKey;
|
||||||
|
|
||||||
protected $table = 'ab_service';
|
protected $table = 'ab_service';
|
||||||
protected $with = ['product.descriptions','account.language','service_adsl','service_domain.tld','service_ssl','service_voip'];
|
protected $with = ['product.descriptions','account.language','service_adsl','service_domain.tld','service_ssl','service_voip'];
|
||||||
protected $dates = ['date_last_invoice','date_next_invoice'];
|
protected $dates = ['date_last_invoice','date_next_invoice'];
|
||||||
|
protected $casts = [
|
||||||
|
'order_info'=>'array',
|
||||||
|
];
|
||||||
|
public $incrementing = FALSE;
|
||||||
|
|
||||||
|
const CREATED_AT = 'date_orig';
|
||||||
|
const UPDATED_AT = 'date_last';
|
||||||
|
|
||||||
protected $appends = [
|
protected $appends = [
|
||||||
|
'account_name',
|
||||||
'category',
|
'category',
|
||||||
'name',
|
'name',
|
||||||
'next_invoice',
|
'next_invoice',
|
||||||
@ -19,7 +30,9 @@ class Service extends Model
|
|||||||
'service_id_url',
|
'service_id_url',
|
||||||
'status',
|
'status',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $visible = [
|
protected $visible = [
|
||||||
|
'account_name',
|
||||||
'active',
|
'active',
|
||||||
'category',
|
'category',
|
||||||
'data_orig',
|
'data_orig',
|
||||||
@ -32,6 +45,10 @@ class Service extends Model
|
|||||||
'status',
|
'status',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
private $inactive_status = [
|
||||||
|
'CANCELLED',
|
||||||
|
];
|
||||||
|
|
||||||
public function account()
|
public function account()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Account::class);
|
return $this->belongsTo(Account::class);
|
||||||
@ -70,9 +87,16 @@ class Service extends Model
|
|||||||
/**
|
/**
|
||||||
* Only query active categories
|
* Only query active categories
|
||||||
*/
|
*/
|
||||||
public function scopeActive()
|
public function scopeActive($query)
|
||||||
{
|
{
|
||||||
return $this->where('active',TRUE);
|
return $query->where(function () use ($query) {
|
||||||
|
return $query->where('active',TRUE)->orWhereNotIn('order_status',$this->inactive_status);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAccountNameAttribute()
|
||||||
|
{
|
||||||
|
return $this->account->company;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCategoryAttribute()
|
public function getCategoryAttribute()
|
||||||
@ -82,10 +106,10 @@ class Service extends Model
|
|||||||
|
|
||||||
public function getNameAttribute()
|
public function getNameAttribute()
|
||||||
{
|
{
|
||||||
if (! isset($this->getServiceDetail()->name))
|
if (! isset($this->ServicePlugin()->name))
|
||||||
return 'Unknown';
|
return 'Unknown';
|
||||||
|
|
||||||
return $this->getServiceDetail()->name;
|
return $this->ServicePlugin()->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getNextInvoiceAttribute()
|
public function getNextInvoiceAttribute()
|
||||||
@ -98,28 +122,6 @@ class Service extends Model
|
|||||||
return $this->product->name($this->account->language);
|
return $this->product->name($this->account->language);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This function will return the associated service model for the product type
|
|
||||||
*/
|
|
||||||
public function getServiceDetail()
|
|
||||||
{
|
|
||||||
switch ($this->product->prod_plugin_file)
|
|
||||||
{
|
|
||||||
case 'ADSL': return $this->service_adsl;
|
|
||||||
case 'DOMAIN': return $this->service_domain;
|
|
||||||
case 'HOST': return $this->service_host;
|
|
||||||
case 'SSL': return $this->service_ssl;
|
|
||||||
case 'VOIP': return $this->service_voip;
|
|
||||||
default: return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getStatusAttribute()
|
|
||||||
{
|
|
||||||
return $this->active ? 'Active' : 'Inactive';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getServiceExpireAttribute()
|
public function getServiceExpireAttribute()
|
||||||
{
|
{
|
||||||
return 'TBA';
|
return 'TBA';
|
||||||
@ -139,4 +141,41 @@ class Service extends Model
|
|||||||
{
|
{
|
||||||
return sprintf('%02s.%04s.%04s',$this->site_id,$this->account_id,$this->id);
|
return sprintf('%02s.%04s.%04s',$this->site_id,$this->account_id,$this->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getStatusAttribute()
|
||||||
|
{
|
||||||
|
return $this->order_status ? $this->order_status : ( $this->active ? 'Active' : 'Inactive');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setDateOrigAttribute($value)
|
||||||
|
{
|
||||||
|
$this->attributes['date_orig'] = $value->timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setDateLastAttribute($value)
|
||||||
|
{
|
||||||
|
$this->attributes['date_last'] = $value->timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isActive()
|
||||||
|
{
|
||||||
|
return $this->active OR ($this->order_status AND ! in_array($this->order_status,$this->inactive_status));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will return the associated service model for the product type
|
||||||
|
*/
|
||||||
|
private function ServicePlugin()
|
||||||
|
{
|
||||||
|
switch ($this->product->prod_plugin_file)
|
||||||
|
{
|
||||||
|
case 'ADSL': return $this->service_adsl;
|
||||||
|
case 'DOMAIN': return $this->service_domain;
|
||||||
|
case 'HOST': return $this->service_host;
|
||||||
|
case 'SSL': return $this->service_ssl;
|
||||||
|
case 'VOIP': return $this->service_voip;
|
||||||
|
|
||||||
|
default: return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -3,13 +3,17 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use App\Models\Service_Model as Model;
|
use App\Models\Service_Model as Model;
|
||||||
|
use App\Traits\NextKey;
|
||||||
|
|
||||||
class ServiceAdsl extends Model
|
class ServiceAdsl extends Model
|
||||||
{
|
{
|
||||||
|
use NextKey;
|
||||||
|
|
||||||
protected $table = 'ab_service__adsl';
|
protected $table = 'ab_service__adsl';
|
||||||
|
public $timestamps = FALSE;
|
||||||
|
|
||||||
public function getNameAttribute()
|
public function getNameAttribute()
|
||||||
{
|
{
|
||||||
return $this->service_number;
|
return $this->service_number ?: $this->service_address;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,10 +3,14 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use App\Models\Service_Model as Model;
|
use App\Models\Service_Model as Model;
|
||||||
|
use App\Traits\NextKey;
|
||||||
|
|
||||||
class ServiceDomain extends Model
|
class ServiceDomain extends Model
|
||||||
{
|
{
|
||||||
|
use NextKey;
|
||||||
|
|
||||||
protected $table = 'ab_service__domain';
|
protected $table = 'ab_service__domain';
|
||||||
|
public $timestamps = FALSE;
|
||||||
|
|
||||||
public function tld()
|
public function tld()
|
||||||
{
|
{
|
||||||
|
@ -3,10 +3,14 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use App\Models\Service_Model as Model;
|
use App\Models\Service_Model as Model;
|
||||||
|
use App\Traits\NextKey;
|
||||||
|
|
||||||
class ServiceHost extends Model
|
class ServiceHost extends Model
|
||||||
{
|
{
|
||||||
|
use NextKey;
|
||||||
|
|
||||||
protected $table = 'ab_service__hosting';
|
protected $table = 'ab_service__hosting';
|
||||||
|
public $timestamps = FALSE;
|
||||||
|
|
||||||
public function getNameAttribute()
|
public function getNameAttribute()
|
||||||
{
|
{
|
||||||
|
@ -3,10 +3,13 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use App\Models\Service_Model as Model;
|
use App\Models\Service_Model as Model;
|
||||||
|
use App\Traits\NextKey;
|
||||||
use App\Classes\SSL;
|
use App\Classes\SSL;
|
||||||
|
|
||||||
class ServiceSsl extends Model
|
class ServiceSsl extends Model
|
||||||
{
|
{
|
||||||
|
use NextKey;
|
||||||
|
|
||||||
protected $table = 'ab_service__ssl';
|
protected $table = 'ab_service__ssl';
|
||||||
protected $_o = NULL;
|
protected $_o = NULL;
|
||||||
|
|
||||||
|
@ -3,10 +3,13 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use App\Models\Service_Model as Model;
|
use App\Models\Service_Model as Model;
|
||||||
|
use App\Traits\NextKey;
|
||||||
|
|
||||||
class ServiceVoip extends Model
|
class ServiceVoip extends Model
|
||||||
{
|
{
|
||||||
|
use NextKey;
|
||||||
protected $table = 'ab_service__voip';
|
protected $table = 'ab_service__voip';
|
||||||
|
public $timestamps = FALSE;
|
||||||
|
|
||||||
public function getNameAttribute()
|
public function getNameAttribute()
|
||||||
{
|
{
|
||||||
|
24
app/Traits/NextKey.php
Normal file
24
app/Traits/NextKey.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Works out the next ID to use for an Eloquent Table.
|
||||||
|
*/
|
||||||
|
namespace App\Traits;
|
||||||
|
|
||||||
|
trait NextKey
|
||||||
|
{
|
||||||
|
public static function boot()
|
||||||
|
{
|
||||||
|
parent::boot();
|
||||||
|
|
||||||
|
static::creating(function($model)
|
||||||
|
{
|
||||||
|
$model->id = self::NextId();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function NextId()
|
||||||
|
{
|
||||||
|
return (new self)->max('id')+1;
|
||||||
|
}
|
||||||
|
}
|
50
app/Traits/OrderServiceOptions.php
Normal file
50
app/Traits/OrderServiceOptions.php
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and returns the Service Options Model for an Order.
|
||||||
|
*/
|
||||||
|
namespace App\Traits;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
trait OrderServiceOptions
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
protected $order_attributes = [
|
||||||
|
'options.input'=>[
|
||||||
|
'request'=>'options.input',
|
||||||
|
'key'=>'column',
|
||||||
|
'validation'=>'required|string:10',
|
||||||
|
'validation_message'=>'It is a required field.',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $order_model = NULL;
|
||||||
|
*/
|
||||||
|
|
||||||
|
public function orderValidation(Request $request)
|
||||||
|
{
|
||||||
|
if (! isset($this->order_attributes))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
$request->validate(collect($this->order_attributes)->pluck('validation','request')->toArray());
|
||||||
|
|
||||||
|
if (! isset($this->order_model))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
$o = new $this->order_model;
|
||||||
|
|
||||||
|
$x = [];
|
||||||
|
foreach ($this->order_attributes as $k => $v)
|
||||||
|
{
|
||||||
|
$x[$v['key']] = $request->input($k);
|
||||||
|
}
|
||||||
|
|
||||||
|
$o->forceFill(array_undot($x));
|
||||||
|
|
||||||
|
// @todo Make this automatic
|
||||||
|
$o->site_id = config('SITE_SETUP')->id;
|
||||||
|
|
||||||
|
return $o;
|
||||||
|
}
|
||||||
|
}
|
48
app/User.php
48
app/User.php
@ -9,6 +9,7 @@ use Laravel\Passport\HasApiTokens;
|
|||||||
use Leenooks\Carbon;
|
use Leenooks\Carbon;
|
||||||
use Leenooks\Traits\UserSwitch;
|
use Leenooks\Traits\UserSwitch;
|
||||||
use App\Notifications\ResetPasswordNotification;
|
use App\Notifications\ResetPasswordNotification;
|
||||||
|
use App\Models\Service;
|
||||||
|
|
||||||
class User extends Authenticatable
|
class User extends Authenticatable
|
||||||
{
|
{
|
||||||
@ -159,8 +160,9 @@ class User extends Authenticatable
|
|||||||
|
|
||||||
public function getServicesActiveAttribute()
|
public function getServicesActiveAttribute()
|
||||||
{
|
{
|
||||||
return $this->services
|
return $this->services->filter(function($item) {
|
||||||
->where('active',TRUE);
|
return $item->isActive();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getServicesCountHtmlAttribute()
|
public function getServicesCountHtmlAttribute()
|
||||||
@ -188,6 +190,11 @@ class User extends Authenticatable
|
|||||||
return sprintf('<a href="/u/account/view/%s">%s</a>',$this->id,$this->user_id);
|
return sprintf('<a href="/u/account/view/%s">%s</a>',$this->id,$this->user_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function sendPasswordResetNotification($token)
|
||||||
|
{
|
||||||
|
$this->notify(new ResetPasswordNotification($token));
|
||||||
|
}
|
||||||
|
|
||||||
/** Scopes **/
|
/** Scopes **/
|
||||||
|
|
||||||
public function scopeActive()
|
public function scopeActive()
|
||||||
@ -195,6 +202,17 @@ class User extends Authenticatable
|
|||||||
return $this->where('active',TRUE);
|
return $this->where('active',TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the user is an admin of the account with $id
|
||||||
|
*
|
||||||
|
* @param $id
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isAdmin($id)
|
||||||
|
{
|
||||||
|
return $id AND $this->isReseller() AND in_array($id,$this->all_accounts()->pluck('id')->toArray());
|
||||||
|
}
|
||||||
|
|
||||||
/** Functions */
|
/** Functions */
|
||||||
|
|
||||||
public function all_accounts()
|
public function all_accounts()
|
||||||
@ -208,7 +226,6 @@ class User extends Authenticatable
|
|||||||
|
|
||||||
return $result->flatten();
|
return $result->flatten();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function all_clients($level=0)
|
public function all_clients($level=0)
|
||||||
{
|
{
|
||||||
$result = collect();
|
$result = collect();
|
||||||
@ -229,6 +246,16 @@ class User extends Authenticatable
|
|||||||
return $result->flatten();
|
return $result->flatten();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function all_client_service_movements()
|
||||||
|
{
|
||||||
|
$s = Service::active()->where('order_status','!=','ACTIVE');
|
||||||
|
$aa = $this->all_accounts()->pluck('id')->unique()->toArray();
|
||||||
|
|
||||||
|
return $s->get()->filter(function($item) use ($aa) {
|
||||||
|
return in_array($item->account_id,$aa);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// List all the agents, including agents of agents
|
// List all the agents, including agents of agents
|
||||||
public function all_agents($level=0)
|
public function all_agents($level=0)
|
||||||
{
|
{
|
||||||
@ -250,17 +277,6 @@ class User extends Authenticatable
|
|||||||
return $result->flatten();
|
return $result->flatten();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if the user is an admin of the account with $id
|
|
||||||
*
|
|
||||||
* @param $id
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isAdmin($id)
|
|
||||||
{
|
|
||||||
return $id AND $this->isReseller() AND in_array($id,$this->all_accounts()->pluck('id')->toArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if the logged in user is a reseller or wholesaler
|
* Determine if the logged in user is a reseller or wholesaler
|
||||||
*
|
*
|
||||||
@ -285,8 +301,4 @@ class User extends Authenticatable
|
|||||||
elseif (! $this->all_agents()->count() AND ! $this->all_clients()->count())
|
elseif (! $this->all_agents()->count() AND ! $this->all_clients()->count())
|
||||||
return 'customer';
|
return 'customer';
|
||||||
}
|
}
|
||||||
public function sendPasswordResetNotification($token)
|
|
||||||
{
|
|
||||||
$this->notify(new ResetPasswordNotification($token));
|
|
||||||
}
|
|
||||||
}
|
}
|
6
composer.lock
generated
6
composer.lock
generated
@ -2463,11 +2463,11 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "leenooks/laravel",
|
"name": "leenooks/laravel",
|
||||||
"version": "0.2.0",
|
"version": "0.2.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://dev.leenooks.net/leenooks/laravel",
|
"url": "https://dev.leenooks.net/leenooks/laravel",
|
||||||
"reference": "98b7b9f6a80274f40c7c02f3281ba78ecfb27603"
|
"reference": "f8d743296580ccf17260505be0b5baee17ac82c6"
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"igaster/laravel-theme": "2.0.6",
|
"igaster/laravel-theme": "2.0.6",
|
||||||
@ -2503,7 +2503,7 @@
|
|||||||
"laravel",
|
"laravel",
|
||||||
"leenooks"
|
"leenooks"
|
||||||
],
|
],
|
||||||
"time": "2018-08-07T14:14:48+00:00"
|
"time": "2018-08-11T05:11:34+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "maximebf/debugbar",
|
"name": "maximebf/debugbar",
|
||||||
|
38
database/migrations/2018_08_10_115648_service_add_status.php
Normal file
38
database/migrations/2018_08_10_115648_service_add_status.php
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class ServiceAddStatus extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('ab_service', function (Blueprint $table) {
|
||||||
|
$table->integer('orderby_id')->unsigned()->nullable();
|
||||||
|
$table->string('order_status')->nullable();
|
||||||
|
$table->json('order_info')->nullable();
|
||||||
|
$table->foreign('orderby_id')->references('id')->on('users');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('ab_service', function (Blueprint $table) {
|
||||||
|
$table->dropForeign(['orderby_id']);
|
||||||
|
$table->dropColumn('orderby_id');
|
||||||
|
$table->dropColumn('order_status');
|
||||||
|
$table->dropColumn('order_info');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -12,13 +12,47 @@
|
|||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('main-content')
|
@section('main-content')
|
||||||
|
<div class="row">
|
||||||
|
@include('widgets.account_summary')
|
||||||
|
</div>
|
||||||
|
<ul class="nav nav-tabs">
|
||||||
|
<li class="active">
|
||||||
|
<a href="#personal-tab" data-toggle="tab">Personal</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#clients-tab" data-toggle="tab">Clients</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="tab-content">
|
||||||
|
<div class="tab-pane active" id="personal-tab">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-7">
|
||||||
|
@include('widgets.services_active')
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-5">
|
||||||
|
@include('widgets.invoices_due')
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-5">
|
||||||
|
@include('widgets.payment_history')
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tab-pane" id="clients-tab">
|
||||||
|
<div class="row">
|
||||||
<div class="col-xs-6">
|
<div class="col-xs-6">
|
||||||
@include('r.accounts')
|
@include('r.accounts')
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-xs-6">
|
||||||
|
@include('r.service_movements')
|
||||||
|
</div>
|
||||||
<div class="col-xs-6">
|
<div class="col-xs-6">
|
||||||
@include('r.agents')
|
@include('r.agents')
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-6">
|
<div class="col-xs-6">
|
||||||
@include('r.clients')
|
@include('r.clients')
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@endsection
|
@endsection
|
@ -0,0 +1,81 @@
|
|||||||
|
<div class="box box-warning small">
|
||||||
|
<div class="box-header">
|
||||||
|
<h3 class="box-title">Service Movements</h3>
|
||||||
|
<div class="box-tools pull-right">
|
||||||
|
<button type="button" class="btn btn-box-tool" data-widget="collapse" data-toggle="tooltip" title="Collapse">
|
||||||
|
<i class="fa fa-minus"></i></button>
|
||||||
|
<button type="button" class="btn btn-box-tool" data-widget="remove" data-toggle="tooltip" title="Remove">
|
||||||
|
<i class="fa fa-times"></i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="box-body">
|
||||||
|
@if ($user->all_client_service_movements()->count())
|
||||||
|
<table class="table table-bordered table-striped table-hover" id="service_movements" style="width: 100%;">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>Account</th>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>Product</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tfoot>
|
||||||
|
<tr>
|
||||||
|
<th>Count {{ $user->all_client_service_movements()->count() }}</th>
|
||||||
|
<th colspan="4"> </th>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
|
@else
|
||||||
|
<p>No Service Movements</p>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@section('page-scripts')
|
||||||
|
@css('https://cdn.datatables.net/responsive/2.2.1/css/responsive.dataTables.min.css')
|
||||||
|
@css('https://cdn.datatables.net/rowgroup/1.0.2/css/rowGroup.dataTables.min.css')
|
||||||
|
@js('https://cdn.datatables.net/responsive/2.2.1/js/dataTables.responsive.min.js')
|
||||||
|
@js('https://cdn.datatables.net/rowgroup/1.0.2/js/dataTables.rowGroup.min.js')
|
||||||
|
|
||||||
|
<style>
|
||||||
|
table.dataTable td {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(document).ready(function() {
|
||||||
|
$('#service_movements').DataTable( {
|
||||||
|
responsive: true,
|
||||||
|
ajax: {
|
||||||
|
url: "/api/r/service_movements"
|
||||||
|
},
|
||||||
|
columns: [
|
||||||
|
{ data: "service_id_url" },
|
||||||
|
{ data: "account_name" },
|
||||||
|
{ data: "name" },
|
||||||
|
{ data: "status" },
|
||||||
|
{ data: "product_name" }
|
||||||
|
],
|
||||||
|
language: {
|
||||||
|
emptyTable: "No Active Clients"
|
||||||
|
},
|
||||||
|
order: [1, 'asc'],
|
||||||
|
rowGroup: {
|
||||||
|
dataSrc: 'product_name',
|
||||||
|
startRender: null,
|
||||||
|
endRender: function ( rows, group ) {
|
||||||
|
return rows.count()+' x ' + group;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
orderFixed: [4, 'asc']
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#service_movements tbody').on('click','tr', function () {
|
||||||
|
$(this).toggleClass('selected');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@append
|
@ -14,44 +14,7 @@
|
|||||||
@section('main-content')
|
@section('main-content')
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@if ($o->accounts->count() > 2)
|
@include('widgets.account_summary')
|
||||||
<div class="col-sm-3">
|
|
||||||
<div class="info-box">
|
|
||||||
<span class="info-box-icon bg-orange"><i class="fa fa-user"></i></span>
|
|
||||||
<div class="info-box-content">
|
|
||||||
<span class="info-box-text">Accounts Linked</span>
|
|
||||||
<span class="info-box-number">{{ $o->accounts->count() }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
<div class="col-sm-3">
|
|
||||||
<div class="info-box">
|
|
||||||
<span class="info-box-icon bg-red"><i class="fa fa-dollar"></i></span>
|
|
||||||
<div class="info-box-content">
|
|
||||||
<span class="info-box-text">Account Balance</span>
|
|
||||||
<span class="info-box-number"><small>$</small> {{ number_format($o->invoices_due->sum('due'),2) }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-3">
|
|
||||||
<div class="info-box">
|
|
||||||
<span class="info-box-icon bg-green"><i class="fa fa-clone"></i></span>
|
|
||||||
<div class="info-box-content">
|
|
||||||
<span class="info-box-text">Active Services</span>
|
|
||||||
<span class="info-box-number">{{ $o->services_active->count() }} <small>/{{ $o->services->count() }}</small></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-3">
|
|
||||||
<div class="info-box">
|
|
||||||
<span class="info-box-icon bg-blue"><i class="fa fa-hashtag"></i></span>
|
|
||||||
<div class="info-box-content">
|
|
||||||
<span class="info-box-text">Invoices Due</span>
|
|
||||||
<span class="info-box-number">{{ $o->invoices_due->count() }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
@if ($o->accounts->count() > 2)
|
||||||
|
<div class="col-sm-3">
|
||||||
|
<div class="info-box">
|
||||||
|
<span class="info-box-icon bg-orange"><i class="fa fa-user"></i></span>
|
||||||
|
<div class="info-box-content">
|
||||||
|
<span class="info-box-text">Accounts Linked</span>
|
||||||
|
<span class="info-box-number">{{ $o->accounts->count() }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
<div class="col-sm-3">
|
||||||
|
<div class="info-box">
|
||||||
|
<span class="info-box-icon bg-red"><i class="fa fa-dollar"></i></span>
|
||||||
|
<div class="info-box-content">
|
||||||
|
<span class="info-box-text">Account Balance</span>
|
||||||
|
<span class="info-box-number"><small>$</small> {{ number_format($o->invoices_due->sum('due'),2) }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-3">
|
||||||
|
<div class="info-box">
|
||||||
|
<span class="info-box-icon bg-green"><i class="fa fa-clone"></i></span>
|
||||||
|
<div class="info-box-content">
|
||||||
|
<span class="info-box-text">Active Services</span>
|
||||||
|
<span class="info-box-number">{{ $o->services_active->count() }} <small>/{{ $o->services->count() }}</small></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-3">
|
||||||
|
<div class="info-box">
|
||||||
|
<span class="info-box-icon bg-blue"><i class="fa fa-hashtag"></i></span>
|
||||||
|
<div class="info-box-content">
|
||||||
|
<span class="info-box-text">Invoices Due</span>
|
||||||
|
<span class="info-box-number">{{ $o->invoices_due->count() }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -49,14 +49,6 @@
|
|||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$('#services').DataTable( {
|
$('#services').DataTable( {
|
||||||
rowGroup: {
|
|
||||||
dataSrc: 'product_name',
|
|
||||||
startRender: null,
|
|
||||||
endRender: function ( rows, group ) {
|
|
||||||
return rows.count()+' x ' + group;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
orderFixed: [3, 'asc'],
|
|
||||||
responsive: true,
|
responsive: true,
|
||||||
ajax: {
|
ajax: {
|
||||||
url: "/api/u/services"
|
url: "/api/u/services"
|
||||||
@ -72,7 +64,15 @@
|
|||||||
language: {
|
language: {
|
||||||
emptyTable: "No Active Services"
|
emptyTable: "No Active Services"
|
||||||
},
|
},
|
||||||
order: [5, 'asc']
|
order: [5, 'asc'],
|
||||||
|
rowGroup: {
|
||||||
|
dataSrc: 'product_name',
|
||||||
|
startRender: null,
|
||||||
|
endRender: function ( rows, group ) {
|
||||||
|
return rows.count()+' x ' + group;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
orderFixed: [3, 'asc']
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#services tbody').on('click','tr', function () {
|
$('#services tbody').on('click','tr', function () {
|
||||||
|
@ -65,30 +65,30 @@
|
|||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
|
|
||||||
<ul class="nav nav-tabs">
|
<ul class="nav nav-tabs">
|
||||||
<li class="active">
|
<li>
|
||||||
<a href="#tab_1" data-toggle="tab">New Client</a>
|
<a href="#tab_1" data-toggle="tab">New Client</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li class="active">
|
||||||
<a href="#tab_2" data-toggle="tab">Existing Client</a>
|
<a href="#tab_2" data-toggle="tab">Existing Client</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
<div class="tab-pane row fade in active" id="tab_1">
|
<div class="tab-pane row fade" id="tab_1">
|
||||||
<div class="control-group form-group col-sm-12 {{ $errors->has('order_email') ? 'has-error' : '' }}">
|
<div class="control-group form-group col-sm-12 {{ $errors->has('order_email_manual') ? 'has-error' : '' }}">
|
||||||
<label for="order_email">New Client Email</label>
|
<label for="order_email_manual">New Client Email</label>
|
||||||
<input type="email" class="form-control" id="order_email" name="order_email" placeholder="New Client Email" value="{{ old('order_email') }}">
|
<input type="email" class="form-control" id="order_email_manual" name="order_email_manual" placeholder="New Client Email" value="{{ old('order_email_manual') }}">
|
||||||
<span class="help-block">{{ $errors->first('order_email') }}</span>
|
<span class="help-block">{{ $errors->first('order_email_manual') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="tab-pane row fade" id="tab_2">
|
<div class="tab-pane row fade in active" id="tab_2">
|
||||||
<div class="control-group form-group col-sm-12 {{ $errors->has('order_email') ? 'has-error' : '' }}">
|
<div class="control-group form-group col-sm-12 {{ $errors->has('order_email') ? 'has-error' : '' }}">
|
||||||
<label for="order_email">Client Account</label>
|
<label for="order_email">Client Account</label>
|
||||||
<select class="form-control" id="order_email" name="order_email" value="{{ old('order_email') }}">
|
<select class="form-control" id="order_email" name="order_email">
|
||||||
<option value=""> </option>
|
<option value=""> </option>
|
||||||
@foreach ($user->all_clients()->sortBy('sur_first_name') as $o)
|
@foreach ($user->all_clients()->sortBy('sur_first_name') as $o)
|
||||||
<option value="{{ $o->email }}">{{ $o->sur_first_name }}</option>
|
<option value="{{ $o->email }}" @if($o->email == old('order_email')) selected @endif>{{ $o->sur_first_name }}</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
<span class="help-block">{{ $errors->first('order_email') }}</span>
|
<span class="help-block">{{ $errors->first('order_email') }}</span>
|
||||||
@ -124,6 +124,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@else
|
||||||
|
<input type="hidden" name="order_email" value="{{ $user->email }}">
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<!-- Product -->
|
<!-- Product -->
|
||||||
@ -135,27 +137,48 @@
|
|||||||
<div class="panel-collapse margin-bottom-20">
|
<div class="panel-collapse margin-bottom-20">
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
|
<div class="control-group form-group col-sm-12 {{ $errors->has('product_options') ? 'has-error' : '' }}">
|
||||||
|
<span class="help-block">{{ $errors->first('product_options') }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="control-group form-group col-sm-6 {{ $errors->has('product_id') ? 'has-error' : '' }}">
|
<div class="control-group form-group col-sm-6 {{ $errors->has('product_id') ? 'has-error' : '' }}">
|
||||||
<label for="order_email">Product</label>
|
<label for="order_email">Product</label>
|
||||||
<select class="form-control" id="product_id" name="product_id" value="{{ old('product_id') }}">
|
<select class="form-control" id="product_id" name="product_id">
|
||||||
<option value=""> </option>
|
<option value=""> </option>
|
||||||
|
@php
|
||||||
|
$po = $selected = NULL;
|
||||||
|
@endphp
|
||||||
@foreach (\App\Models\Product::active()->get()->sortBy('name') as $o)
|
@foreach (\App\Models\Product::active()->get()->sortBy('name') as $o)
|
||||||
<option value="{{ $o->id }}">{{ $o->name }}</option>
|
@php
|
||||||
|
if ($o->id == old('product_id'))
|
||||||
|
{
|
||||||
|
$selected = 'selected';
|
||||||
|
$po = $o;
|
||||||
|
} else {
|
||||||
|
$selected = NULL;
|
||||||
|
}
|
||||||
|
@endphp
|
||||||
|
<option value="{{ $o->id }}" {{ $selected }}>{{ $o->name }}</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
<span class="help-block">{{ $errors->first('product_id') }}</span>
|
<span class="help-block">{{ $errors->first('product_id') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6" id="product_info"></div>
|
<div class="col-sm-6" id="product_info">
|
||||||
|
@if (old('product_id'))
|
||||||
|
@include('widgets.product_description',['o'=>$po])
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-12" id="product_order"></div>
|
<div class="col-md-12" id="product_order">
|
||||||
|
@if (old('product_id'))
|
||||||
|
@include('widgets.product_order',['o'=>$po])
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-2"><button class="btn btn-block btn-primary">Previous</button></div>
|
<div class="col-sm-2"><button class="btn btn-block btn-primary">Previous</button></div>
|
||||||
</div>
|
<div class="col-sm-2 pull-right"><input type="submit" class="btn btn-block btn-primary" value="Submit Order"></div>
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-2"><input type="submit" class="btn btn-block btn-primary" value="Submit Order"></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -205,7 +228,6 @@
|
|||||||
// Send the request and update sub category dropdown
|
// Send the request and update sub category dropdown
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: "GET",
|
type: "GET",
|
||||||
//data: "key="+$(this).val(),
|
|
||||||
dataType: "html",
|
dataType: "html",
|
||||||
cache: true,
|
cache: true,
|
||||||
url: '{{ url('product_info') }}'+'/'+$(this).val(),
|
url: '{{ url('product_info') }}'+'/'+$(this).val(),
|
||||||
@ -220,7 +242,7 @@
|
|||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: "GET",
|
type: "GET",
|
||||||
//data: "key="+$(this).val(),
|
// data: "old=",
|
||||||
dataType: "html",
|
dataType: "html",
|
||||||
cache: true,
|
cache: true,
|
||||||
url: '{{ url('product_order') }}'+'/'+$(this).val(),
|
url: '{{ url('product_order') }}'+'/'+$(this).val(),
|
||||||
|
12
resources/theme/frontend/metronic/order_received.blade.php
Normal file
12
resources/theme/frontend/metronic/order_received.blade.php
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
@section('htmlheader_title')
|
||||||
|
{{ trans('message.home') }}
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('main-content')
|
||||||
|
<div class="col-md-12">
|
||||||
|
<h2>Order Service</h2>
|
||||||
|
<p>Your order has been received - #{{ $o->id }}. An email will be sent to you with as your order progresses.</p>
|
||||||
|
</div>
|
||||||
|
@endsection
|
@ -1,9 +1,9 @@
|
|||||||
<fieldset class="form-group col-sm-12">
|
<fieldset class="form-group col-sm-12">
|
||||||
<label>ADSL</label>
|
<label>ADSL</label>
|
||||||
|
|
||||||
<div class="form-group col-sm-12 {{ $errors->has('product_options.address') ? 'has-error' : '' }}">
|
<div class="form-group col-sm-12 {{ $errors->has('options.address') ? 'has-error' : '' }}">
|
||||||
<label for="product_options.address">Site Address</label>
|
<label for="options.address">Site Address</label>
|
||||||
<input type="text" class="form-control" id="product_options.address" name="product_options[address]" placeholder="Site Address" value="{{ old('product_options.address') }}">
|
<input type="text" class="form-control" id="options.address" name="options[address]" placeholder="Site Address" value="{{ old('options.address') }}">
|
||||||
<span class="help-block">{{ $errors->first('product_options.address') }} {{ $errors->first('product_options.address') }}</span>
|
<span class="help-block">{{ $errors->first('options.address') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
@ -1,21 +1,21 @@
|
|||||||
<fieldset class="form-group">
|
<fieldset class="form-group">
|
||||||
<label class="col-md-12">VOIP</label>
|
<label class="col-md-12">VOIP</label>
|
||||||
|
|
||||||
<div class="form-group col-sm-6 {{ $errors->has('product_options.phonenumber') ? 'has-error' : '' }}">
|
<div class="form-group col-sm-6 {{ $errors->has('options.phonenumber') ? 'has-error' : '' }}">
|
||||||
<label for="product_options.phonenumber">Phone Number</label>
|
<label for="options.phonenumber">Phone Number</label>
|
||||||
<input type="text" class="form-control" id="product_options.phonenumber" name="product_options[phonenumber]" placeholder="Phone Number with Area Code" value="{{ old('product_options.phonenumber') }}">
|
<input type="text" class="form-control" id="options.phonenumber" name="options[phonenumber]" placeholder="Phone Number with Area Code" value="{{ old('options.phonenumber') }}">
|
||||||
<span class="help-block">{{ $errors->first('product_options.phonenumber') }} {{ $errors->first('product_options.phonenumber') }}</span>
|
<span class="help-block">{{ $errors->first('options.phonenumber') }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group col-sm-6 {{ $errors->has('product_options.supplier') ? 'has-error' : '' }}">
|
<div class="form-group col-sm-6 {{ $errors->has('options.supplier') ? 'has-error' : '' }}">
|
||||||
<label for="product_order.supplier">Existing Supplier</label>
|
<label for="options.supplier">Existing Supplier</label>
|
||||||
<input type="text" class="form-control" id="product_options.supplier" name="product_options[supplier]" placeholder="eg: Telstra" value="{{ old('product_options.supplier') }}">
|
<input type="text" class="form-control" id="options.supplier" name="options[supplier]" placeholder="eg: Telstra" value="{{ old('options.supplier') }}">
|
||||||
<span class="help-block">{{ $errors->first('product_options.supplier') }} {{ $errors->first('product_options.supplier') }}</span>
|
<span class="help-block">{{ $errors->first('options.supplier') }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group col-sm-6 {{ $errors->has('product_options.supplieraccnum') ? 'has-error' : '' }}">
|
<div class="form-group col-sm-6 {{ $errors->has('options.supplieraccnum') ? 'has-error' : '' }}">
|
||||||
<label for="product_options.supplieraccnum">Suppliers Account Number</label>
|
<label for="options.supplieraccnum">Suppliers Account Number</label>
|
||||||
<input type="text" class="form-control" id="product_options.supplieraccnum" name="product_options[supplieraccnum]" placeholder="Refer to Bill" value="{{ old('product_options.supplieraccnum') }}">
|
<input type="text" class="form-control" id="options.supplieraccnum" name="options[supplieraccnum]" placeholder="Refer to Bill" value="{{ old('options.supplieraccnum') }}">
|
||||||
<span class="help-block">{{ $errors->first('product_options.supplieraccnum') }} {{ $errors->first('product_options.supplieraccnum') }}</span>
|
<span class="help-block">{{ $errors->first('options.supplieraccnum') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
@ -5,26 +5,30 @@
|
|||||||
<table class="table table-condensed">
|
<table class="table table-condensed">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Type</th>
|
<th>Type</th>
|
||||||
<td class="text-right">ADSL</td>
|
<td class="text-right">{{ $o->product_type }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Setup Cost</th>
|
<th>Setup Charges <sup>*</sup></th>
|
||||||
<td class="text-right">TBA</td>
|
<td class="text-right">${{ is_numeric($o->setup_cost) ? number_format($o->setup_cost,2) : $o->setup_cost }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Monthly Cost</th>
|
<th>Cost</th>
|
||||||
<td class="text-right">TBA</td>
|
<td class="text-right">${{ is_numeric($o->default_cost) ? number_format($o->default_cost,2) : $o->default_cost }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Default Billing</th>
|
<th>Default Billing</th>
|
||||||
<td class="text-right">TBA</td>
|
<td class="text-right">{{ is_numeric($o->default_billing) ? number_format($o->default_billing,2) : $o->default_billing }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Contract Term</th>
|
<th>Contract Term</th>
|
||||||
<td class="text-right">TBA</td>
|
<td class="text-right">{{ $o->contract_term }} mths</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Minimum Costs</th>
|
<th>Minimum Costs <sup>*</sup></th>
|
||||||
<td class="text-right">TBA</td>
|
<td class="text-right">${{ is_numeric($o->minimum_cost) ? number_format($o->minimum_cost,2) : $o->minimum_cost }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
<tfoot>
|
||||||
|
<tr><td colspan="2"><sup>* Additional setup charges may apply for complex installations.</sup></td></tr>
|
||||||
|
</tfoot>
|
||||||
</table>
|
</table>
|
@ -8,23 +8,23 @@
|
|||||||
<td class="text-right">VOIP</td>
|
<td class="text-right">VOIP</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Setup Cost</th>
|
<th>Setup Charges</th>
|
||||||
<td class="text-right">TBA</td>
|
<td class="text-right">${{ is_numeric($o->setup_cost) ? number_format($o->setup_cost,2) : $o->setup_cost }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Monthly Cost</th>
|
<th>Cost</th>
|
||||||
<td class="text-right">TBA</td>
|
<td class="text-right">${{ is_numeric($o->default_cost) ? number_format($o->default_cost,2) : $o->default_cost }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Default Billing</th>
|
<th>Default Billing</th>
|
||||||
<td class="text-right">TBA</td>
|
<td class="text-right">{{ is_numeric($o->default_billing) ? number_format($o->default_billing,2) : $o->default_billing }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Contract Term</th>
|
<th>Contract Term</th>
|
||||||
<td class="text-right">TBA</td>
|
<td class="text-right">{{ $o->contract_term }} mths</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Minimum Costs</th>
|
<th>Minimum Costs</th>
|
||||||
<td class="text-right">TBA</td>
|
<td class="text-right">${{ is_numeric($o->minimum_cost) ? number_format($o->minimum_cost,2) : $o->minimum_cost }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
@ -23,6 +23,7 @@ Route::group(['middleware'=>['auth:api','role:reseller']], function() {
|
|||||||
Route::get('/r/agents','ResellerServicesController@agents');
|
Route::get('/r/agents','ResellerServicesController@agents');
|
||||||
Route::get('/r/accounts','ResellerServicesController@accounts');
|
Route::get('/r/accounts','ResellerServicesController@accounts');
|
||||||
Route::get('/r/clients','ResellerServicesController@clients');
|
Route::get('/r/clients','ResellerServicesController@clients');
|
||||||
|
Route::get('/r/service_movements','ResellerServicesController@service_movements');
|
||||||
});
|
});
|
||||||
|
|
||||||
Route::group(['middleware'=>'auth:api'], function() {
|
Route::group(['middleware'=>'auth:api'], function() {
|
||||||
|
Loading…
Reference in New Issue
Block a user