Tweaks
|
@ -22,6 +22,7 @@ class CreateProductsTable extends Migration
|
|||
$table->integer('product_quantity');
|
||||
$table->integer('product_cost');
|
||||
$table->integer('product_price');
|
||||
$table->string('product_unit')->nullable();
|
||||
$table->integer('product_stock_alert');
|
||||
$table->integer('product_order_tax')->nullable();
|
||||
$table->tinyInteger('product_tax_type')->nullable();
|
||||
|
|
|
@ -6,6 +6,7 @@ use Illuminate\Database\Eloquent\Model;
|
|||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Spatie\MediaLibrary\HasMedia;
|
||||
use Spatie\MediaLibrary\InteractsWithMedia;
|
||||
use Spatie\MediaLibrary\MediaCollections\Models\Media;
|
||||
|
||||
class Product extends Model implements HasMedia
|
||||
{
|
||||
|
@ -25,6 +26,12 @@ class Product extends Model implements HasMedia
|
|||
->useFallbackUrl('/images/fallback_product_image.png');
|
||||
}
|
||||
|
||||
public function registerMediaConversions(Media $media = null): void {
|
||||
$this->addMediaConversion('thumb')
|
||||
->width(50)
|
||||
->height(50);
|
||||
}
|
||||
|
||||
public function setProductCostAttribute($value) {
|
||||
$this->attributes['product_cost'] = ($value * 100);
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ class ProductController extends Controller
|
|||
|
||||
if ($request->has('document')) {
|
||||
foreach ($request->input('document', []) as $file) {
|
||||
$product->addMedia(storage_path('temp/dropzone/' . $file))->toMediaCollection('images');
|
||||
$product->addMedia(Storage::path('temp/dropzone/' . $file))->toMediaCollection('images');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@ class ProductController extends Controller
|
|||
|
||||
foreach ($request->input('document', []) as $file) {
|
||||
if (count($media) === 0 || !in_array($file, $media)) {
|
||||
$product->addMedia(storage_path('temp/dropzone/' . $file))->toMediaCollection('images');
|
||||
$product->addMedia(Storage::path('temp/dropzone/' . $file))->toMediaCollection('images');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ class StoreProductRequest extends FormRequest
|
|||
'product_name' => ['required', 'string', 'max:255'],
|
||||
'product_code' => ['required', 'string', 'max:255', 'unique:products,product_code'],
|
||||
'product_barcode_symbology' => ['required', 'string', 'max:255'],
|
||||
'product_unit' => ['required', 'string', 'max:255'],
|
||||
'product_quantity' => ['required', 'integer', 'min:1'],
|
||||
'product_cost' => ['required', 'numeric', 'max:2147483647'],
|
||||
'product_price' => ['required', 'numeric', 'max:2147483647'],
|
||||
|
|
|
@ -19,6 +19,7 @@ class UpdateProductRequest extends FormRequest
|
|||
'product_name' => ['required', 'string', 'max:255'],
|
||||
'product_code' => ['required', 'string', 'max:255', 'unique:products,product_code,' . $this->product->id],
|
||||
'product_barcode_symbology' => ['required', 'string', 'max:255'],
|
||||
'product_unit' => ['required', 'string', 'max:255'],
|
||||
'product_quantity' => ['required', 'integer', 'min:1'],
|
||||
'product_cost' => ['required', 'numeric', 'max:2147483647'],
|
||||
'product_price' => ['required', 'numeric', 'max:2147483647'],
|
||||
|
|
|
@ -97,13 +97,13 @@
|
|||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="col-md-6">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label for="product_order_tax">Tax (%)</label>
|
||||
<input type="number" class="form-control" name="product_order_tax" value="{{ old('product_order_tax') }}" min="1">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label for="product_tax_type">Tax type</label>
|
||||
<select class="form-control" name="product_tax_type" id="product_tax_type">
|
||||
|
@ -113,6 +113,17 @@
|
|||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label for="product_unit">Unit <i class="bi bi-question-circle-fill text-info" data-toggle="tooltip" data-placement="top" title="This text will be placed after Product Quantity."></i> <span class="text-danger">*</span></label>
|
||||
<input type="text" class="form-control" name="product_unit" value="{{ old('product_unit') }}" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="product_note">Note</label>
|
||||
<textarea name="product_note" id="product_note" rows="4 " class="form-control"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -122,7 +133,7 @@
|
|||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="form-group">
|
||||
<label for="image">Product Images <i class="bi bi-question-circle-fill text-info" data-toggle="tooltip" data-placement="top" title="Max Files: 3, Max File Size: 1MB"></i></label>
|
||||
<label for="image">Product Images <i class="bi bi-question-circle-fill text-info" data-toggle="tooltip" data-placement="top" title="Max Files: 3, Max File Size: 1MB, Image Size: 400x400"></i></label>
|
||||
<div class="dropzone d-flex flex-wrap align-items-center justify-content-center" id="document-dropzone">
|
||||
<div class="dz-message" data-dz-message>
|
||||
<i class="bi bi-cloud-arrow-up"></i>
|
||||
|
@ -152,7 +163,7 @@
|
|||
addRemoveLinks: true,
|
||||
dictRemoveFile: "<i class='bi bi-x-circle text-danger'></i> remove",
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': "{{ csrf_token() }}"
|
||||
"X-CSRF-TOKEN": "{{ csrf_token() }}"
|
||||
},
|
||||
success: function (file, response) {
|
||||
$('form').append('<input type="hidden" name="document[]" value="' + response.name + '">');
|
||||
|
@ -166,6 +177,14 @@
|
|||
} else {
|
||||
name = uploadedDocumentMap[file.name];
|
||||
}
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "{{ route('dropzone.delete') }}",
|
||||
data: {
|
||||
'_token': "{{ csrf_token() }}",
|
||||
'file_name': `${name}`
|
||||
},
|
||||
});
|
||||
$('form').find('input[name="document[]"][value="' + name + '"]').remove();
|
||||
},
|
||||
init: function () {
|
||||
|
|
|
@ -97,13 +97,13 @@
|
|||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="col-md-6">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label for="product_order_tax">Tax (%)</label>
|
||||
<input type="number" class="form-control" name="product_order_tax" value="{{ $product->product_order_tax }}" min="0" max="100">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label for="product_tax_type">Tax type</label>
|
||||
<select class="form-control" name="product_tax_type" id="product_tax_type">
|
||||
|
@ -113,6 +113,16 @@
|
|||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label for="product_unit">Unit <i class="bi bi-question-circle-fill text-info" data-toggle="tooltip" data-placement="top" title="This text will be placed after Product Quantity."></i> <span class="text-danger">*</span></label>
|
||||
<input type="text" class="form-control" name="product_unit" value="{{ old('product_unit') ?? $product->product_unit }}" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="product_note">Note</label>
|
||||
<textarea name="product_note" id="product_note" rows="4 " class="form-control">{{ $product->product_note }}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -122,7 +132,7 @@
|
|||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="form-group">
|
||||
<label for="image">Product Images <i class="bi bi-question-circle-fill text-info" data-toggle="tooltip" data-placement="top" title="Max Files: 3, Max File Size: 1MB"></i></label>
|
||||
<label for="image">Product Images <i class="bi bi-question-circle-fill text-info" data-toggle="tooltip" data-placement="top" title="Max Files: 3, Max File Size: 1MB, Image Size: 400x400"></i></label>
|
||||
<div class="dropzone d-flex flex-wrap align-items-center justify-content-center" id="document-dropzone">
|
||||
<div class="dz-message" data-dz-message>
|
||||
<i class="bi bi-cloud-arrow-up"></i>
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
<div class="col-lg-9">
|
||||
<div class="card h-100">
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
|
@ -49,7 +49,14 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<th>Quantity</th>
|
||||
<td>{{ $product->product_quantity }}</td>
|
||||
<td>{{ $product->product_quantity . ' ' . $product->product_unit }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Stock Worth</th>
|
||||
<td>
|
||||
COST:: {{ format_currency($product->product_cost * $product->product_quantity) }} /
|
||||
PRICE:: {{ format_currency($product->product_price * $product->product_quantity) }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Alert Quantity</th>
|
||||
|
@ -71,13 +78,17 @@
|
|||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Note</th>
|
||||
<td>{{ $product->product_note ?? 'N/A' }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4">
|
||||
<div class="col-lg-3">
|
||||
<div class="card h-100">
|
||||
<div class="card-body">
|
||||
@forelse($product->getMedia('images') as $media)
|
||||
|
|
|
@ -91,6 +91,7 @@ class PurchaseController extends Controller
|
|||
|
||||
Cart::instance('purchase')->destroy();
|
||||
|
||||
if ($purchase->paid_amount > 0) {
|
||||
PurchasePayment::create([
|
||||
'date' => $request->date,
|
||||
'reference' => 'INV/'.$purchase->reference,
|
||||
|
@ -98,6 +99,7 @@ class PurchaseController extends Controller
|
|||
'purchase_id' => $purchase->id,
|
||||
'payment_method' => $request->payment_method
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
toast('Purchase Created!', 'success');
|
||||
|
|
|
@ -57,7 +57,6 @@
|
|||
<tr>
|
||||
<th class="align-middle">Product</th>
|
||||
<th class="align-middle">Net Unit Price</th>
|
||||
<th class="align-middle">Stock</th>
|
||||
<th class="align-middle">Quantity</th>
|
||||
<th class="align-middle">Discount</th>
|
||||
<th class="align-middle">Tax</th>
|
||||
|
@ -76,10 +75,6 @@
|
|||
|
||||
<td class="align-middle">{{ format_currency($item->unit_price) }}</td>
|
||||
|
||||
<td class="align-middle">
|
||||
<span class="badge badge-info">{{ $item->product->product_quantity }}</span>
|
||||
</td>
|
||||
|
||||
<td class="align-middle">
|
||||
{{ $item->quantity }}
|
||||
</td>
|
||||
|
@ -126,7 +121,7 @@
|
|||
</div>
|
||||
<div class="row" style="margin-top: 25px;">
|
||||
<div class="col-xs-12">
|
||||
<p style="font-style: italic;text-align: center">Computer generated invoice. {{ settings()->company_name }} © {{ date('Y') }}.</p>
|
||||
<p style="font-style: italic;text-align: center">{{ settings()->company_name }} © {{ date('Y') }}.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -64,7 +64,6 @@
|
|||
<tr>
|
||||
<th class="align-middle">Product</th>
|
||||
<th class="align-middle">Net Unit Price</th>
|
||||
<th class="align-middle">Stock</th>
|
||||
<th class="align-middle">Quantity</th>
|
||||
<th class="align-middle">Discount</th>
|
||||
<th class="align-middle">Tax</th>
|
||||
|
@ -83,10 +82,6 @@
|
|||
|
||||
<td class="align-middle">{{ format_currency($item->unit_price) }}</td>
|
||||
|
||||
<td class="align-middle">
|
||||
<span class="badge badge-info">{{ $item->product->product_quantity }}</span>
|
||||
</td>
|
||||
|
||||
<td class="align-middle">
|
||||
{{ $item->quantity }}
|
||||
</td>
|
||||
|
|
|
@ -92,6 +92,7 @@ class PurchasesReturnController extends Controller
|
|||
|
||||
Cart::instance('purchase_return')->destroy();
|
||||
|
||||
if ($purchase_return->paid_amount > 0) {
|
||||
PurchaseReturnPayment::create([
|
||||
'date' => $request->date,
|
||||
'reference' => 'INV/' . $purchase_return->reference,
|
||||
|
@ -99,6 +100,7 @@ class PurchasesReturnController extends Controller
|
|||
'purchase_return_id' => $purchase_return->id,
|
||||
'payment_method' => $request->payment_method
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
toast('Purchase Return Created!', 'success');
|
||||
|
|
|
@ -57,7 +57,6 @@
|
|||
<tr>
|
||||
<th class="align-middle">Product</th>
|
||||
<th class="align-middle">Net Unit Price</th>
|
||||
<th class="align-middle">Stock</th>
|
||||
<th class="align-middle">Quantity</th>
|
||||
<th class="align-middle">Discount</th>
|
||||
<th class="align-middle">Tax</th>
|
||||
|
@ -76,10 +75,6 @@
|
|||
|
||||
<td class="align-middle">{{ format_currency($item->unit_price) }}</td>
|
||||
|
||||
<td class="align-middle">
|
||||
<span class="badge badge-info">{{ $item->product->product_quantity }}</span>
|
||||
</td>
|
||||
|
||||
<td class="align-middle">
|
||||
{{ $item->quantity }}
|
||||
</td>
|
||||
|
@ -126,7 +121,7 @@
|
|||
</div>
|
||||
<div class="row" style="margin-top: 25px;">
|
||||
<div class="col-xs-12">
|
||||
<p style="font-style: italic;text-align: center">Computer generated invoice. {{ settings()->company_name }} © {{ date('Y') }}.</p>
|
||||
<p style="font-style: italic;text-align: center">{{ settings()->company_name }} © {{ date('Y') }}.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -64,7 +64,6 @@
|
|||
<tr>
|
||||
<th class="align-middle">Product</th>
|
||||
<th class="align-middle">Net Unit Price</th>
|
||||
<th class="align-middle">Stock</th>
|
||||
<th class="align-middle">Quantity</th>
|
||||
<th class="align-middle">Discount</th>
|
||||
<th class="align-middle">Tax</th>
|
||||
|
@ -83,10 +82,6 @@
|
|||
|
||||
<td class="align-middle">{{ format_currency($item->unit_price) }}</td>
|
||||
|
||||
<td class="align-middle">
|
||||
<span class="badge badge-info">{{ $item->product->product_quantity }}</span>
|
||||
</td>
|
||||
|
||||
<td class="align-middle">
|
||||
{{ $item->quantity }}
|
||||
</td>
|
||||
|
|
|
@ -82,6 +82,7 @@ class PosController extends Controller
|
|||
|
||||
Cart::instance('sale')->destroy();
|
||||
|
||||
if ($sale->paid_amount > 0) {
|
||||
SalePayment::create([
|
||||
'date' => now()->format('Y-m-d'),
|
||||
'reference' => 'INV/'.$sale->reference,
|
||||
|
@ -89,6 +90,7 @@ class PosController extends Controller
|
|||
'sale_id' => $sale->id,
|
||||
'payment_method' => $request->payment_method
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
toast('POS Sale Created!', 'success');
|
||||
|
|
|
@ -92,6 +92,7 @@ class SaleController extends Controller
|
|||
|
||||
Cart::instance('sale')->destroy();
|
||||
|
||||
if ($sale->paid_amount > 0) {
|
||||
SalePayment::create([
|
||||
'date' => $request->date,
|
||||
'reference' => 'INV/'.$sale->reference,
|
||||
|
@ -99,6 +100,7 @@ class SaleController extends Controller
|
|||
'sale_id' => $sale->id,
|
||||
'payment_method' => $request->payment_method
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
toast('Sale Created!', 'success');
|
||||
|
|
|
@ -57,7 +57,6 @@
|
|||
<tr>
|
||||
<th class="align-middle">Product</th>
|
||||
<th class="align-middle">Net Unit Price</th>
|
||||
<th class="align-middle">Stock</th>
|
||||
<th class="align-middle">Quantity</th>
|
||||
<th class="align-middle">Discount</th>
|
||||
<th class="align-middle">Tax</th>
|
||||
|
@ -76,10 +75,6 @@
|
|||
|
||||
<td class="align-middle">{{ format_currency($item->unit_price) }}</td>
|
||||
|
||||
<td class="align-middle">
|
||||
<span class="badge badge-info">{{ $item->product->product_quantity }}</span>
|
||||
</td>
|
||||
|
||||
<td class="align-middle">
|
||||
{{ $item->quantity }}
|
||||
</td>
|
||||
|
@ -126,7 +121,7 @@
|
|||
</div>
|
||||
<div class="row" style="margin-top: 25px;">
|
||||
<div class="col-xs-12">
|
||||
<p style="font-style: italic;text-align: center">Computer generated invoice. {{ settings()->company_name }} © {{ date('Y') }}.</p>
|
||||
<p style="font-style: italic;text-align: center">{{ settings()->company_name }} © {{ date('Y') }}.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -64,7 +64,6 @@
|
|||
<tr>
|
||||
<th class="align-middle">Product</th>
|
||||
<th class="align-middle">Net Unit Price</th>
|
||||
<th class="align-middle">Stock</th>
|
||||
<th class="align-middle">Quantity</th>
|
||||
<th class="align-middle">Discount</th>
|
||||
<th class="align-middle">Tax</th>
|
||||
|
@ -83,10 +82,6 @@
|
|||
|
||||
<td class="align-middle">{{ format_currency($item->unit_price) }}</td>
|
||||
|
||||
<td class="align-middle">
|
||||
<span class="badge badge-info">{{ $item->product->product_quantity }}</span>
|
||||
</td>
|
||||
|
||||
<td class="align-middle">
|
||||
{{ $item->quantity }}
|
||||
</td>
|
||||
|
|
|
@ -92,6 +92,7 @@ class SalesReturnController extends Controller
|
|||
|
||||
Cart::instance('sale_return')->destroy();
|
||||
|
||||
if ($sale_return->paid_amount > 0) {
|
||||
SaleReturnPayment::create([
|
||||
'date' => $request->date,
|
||||
'reference' => 'INV/'.$sale_return->reference,
|
||||
|
@ -99,6 +100,7 @@ class SalesReturnController extends Controller
|
|||
'sale_return_id' => $sale_return->id,
|
||||
'payment_method' => $request->payment_method
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
toast('Sale Return Created!', 'success');
|
||||
|
|
|
@ -57,7 +57,6 @@
|
|||
<tr>
|
||||
<th class="align-middle">Product</th>
|
||||
<th class="align-middle">Net Unit Price</th>
|
||||
<th class="align-middle">Stock</th>
|
||||
<th class="align-middle">Quantity</th>
|
||||
<th class="align-middle">Discount</th>
|
||||
<th class="align-middle">Tax</th>
|
||||
|
@ -76,10 +75,6 @@
|
|||
|
||||
<td class="align-middle">{{ format_currency($item->unit_price) }}</td>
|
||||
|
||||
<td class="align-middle">
|
||||
<span class="badge badge-info">{{ $item->product->product_quantity }}</span>
|
||||
</td>
|
||||
|
||||
<td class="align-middle">
|
||||
{{ $item->quantity }}
|
||||
</td>
|
||||
|
@ -126,7 +121,7 @@
|
|||
</div>
|
||||
<div class="row" style="margin-top: 25px;">
|
||||
<div class="col-xs-12">
|
||||
<p style="font-style: italic;text-align: center">Computer generated invoice. {{ settings()->company_name }} © {{ date('Y') }}.</p>
|
||||
<p style="font-style: italic;text-align: center">{{ settings()->company_name }} © {{ date('Y') }}.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -64,7 +64,6 @@
|
|||
<tr>
|
||||
<th class="align-middle">Product</th>
|
||||
<th class="align-middle">Net Unit Price</th>
|
||||
<th class="align-middle">Stock</th>
|
||||
<th class="align-middle">Quantity</th>
|
||||
<th class="align-middle">Discount</th>
|
||||
<th class="align-middle">Tax</th>
|
||||
|
@ -83,10 +82,6 @@
|
|||
|
||||
<td class="align-middle">{{ format_currency($item->unit_price) }}</td>
|
||||
|
||||
<td class="align-middle">
|
||||
<span class="badge badge-info">{{ $item->product->product_quantity }}</span>
|
||||
</td>
|
||||
|
||||
<td class="align-middle">
|
||||
{{ $item->quantity }}
|
||||
</td>
|
||||
|
|
|
@ -5,8 +5,11 @@ namespace Modules\Setting\Http\Controllers;
|
|||
use Illuminate\Contracts\Support\Renderable;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Modules\Setting\Entities\Setting;
|
||||
use Modules\Setting\Http\Requests\StoreSettingsRequest;
|
||||
|
||||
class SettingController extends Controller
|
||||
{
|
||||
|
@ -20,20 +23,7 @@ class SettingController extends Controller
|
|||
}
|
||||
|
||||
|
||||
public function update(Request $request) {
|
||||
abort_if(Gate::denies('access_settings'), 403);
|
||||
|
||||
$request->validate([
|
||||
'company_name' => 'required|string|max:255',
|
||||
'company_email' => 'required|email|max:255',
|
||||
'company_phone' => 'required|string|max:255',
|
||||
'notification_email' => 'required|email|max:255',
|
||||
'company_address' => 'required|string|max:500',
|
||||
'default_currency_id' => 'required|numeric',
|
||||
'default_currency_position' => 'required|string|max:255',
|
||||
'footer_text' => 'required|string|max:255'
|
||||
]);
|
||||
|
||||
public function update(StoreSettingsRequest $request) {
|
||||
Setting::firstOrFail()->update([
|
||||
'company_name' => $request->company_name,
|
||||
'company_email' => $request->company_email,
|
||||
|
@ -51,4 +41,40 @@ class SettingController extends Controller
|
|||
|
||||
return redirect()->route('settings.index');
|
||||
}
|
||||
|
||||
|
||||
public function updateSmtp(Request $request) {
|
||||
$toReplace = array(
|
||||
'MAIL_MAILER='.env('MAIL_HOST'),
|
||||
'MAIL_HOST="'.env('MAIL_HOST').'"',
|
||||
'MAIL_PORT='.env('MAIL_PORT'),
|
||||
'MAIL_FROM_ADDRESS="'.env('MAIL_FROM_ADDRESS').'"',
|
||||
'MAIL_FROM_NAME="'.env('MAIL_FROM_NAME').'"',
|
||||
'MAIL_USERNAME="'.env('MAIL_USERNAME').'"',
|
||||
'MAIL_PASSWORD="'.env('MAIL_PASSWORD').'"',
|
||||
'MAIL_ENCRYPTION="'.env('MAIL_ENCRYPTION').'"'
|
||||
);
|
||||
|
||||
$replaceWith = array(
|
||||
'MAIL_MAILER='.$request->mail_mailer,
|
||||
'MAIL_HOST="'.$request->mail_host.'"',
|
||||
'MAIL_PORT='.$request->mail_port,
|
||||
'MAIL_FROM_ADDRESS="'.$request->mail_from_address.'"',
|
||||
'MAIL_FROM_NAME="'.$request->mail_from_name.'"',
|
||||
'MAIL_USERNAME="'.$request->mail_username.'"',
|
||||
'MAIL_PASSWORD="'.$request->mail_password.'"',
|
||||
'MAIL_ENCRYPTION="'.$request->mail_encryption.'"');
|
||||
|
||||
try {
|
||||
file_put_contents(base_path('.env'), str_replace($toReplace, $replaceWith, file_get_contents(base_path('.env'))));
|
||||
Artisan::call('cache:clear');
|
||||
|
||||
toast('Mail Settings Updated!', 'info');
|
||||
} catch (\Exception $exception) {
|
||||
Log::error($exception);
|
||||
session()->flash('settings_smtp_message', 'Something Went Wrong!');
|
||||
}
|
||||
|
||||
return redirect()->route('settings.index');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Setting\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
||||
class StoreSettingsRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'company_name' => 'required|string|max:255',
|
||||
'company_email' => 'required|email|max:255',
|
||||
'company_phone' => 'required|string|max:255',
|
||||
'notification_email' => 'required|email|max:255',
|
||||
'company_address' => 'required|string|max:500',
|
||||
'default_currency_id' => 'required|numeric',
|
||||
'default_currency_position' => 'required|string|max:255',
|
||||
'footer_text' => 'required|string|max:255'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return Gate::allows('access_settings');
|
||||
}
|
||||
}
|
|
@ -86,7 +86,97 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group mb-0">
|
||||
<button type="submit" class="btn btn-primary"><i class="bi bi-check"></i> Save Changes</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-12">
|
||||
@if (session()->has('settings_smtp_message'))
|
||||
<div class="alert alert-warning alert-dismissible fade show" role="alert">
|
||||
<div class="alert-body">
|
||||
<span>{{ session('settings_smtp_message') }}</span>
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h5 class="mb-0">Mail Settings</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form action="{{ route('settings.smtp.update') }}" method="POST">
|
||||
@csrf
|
||||
@method('patch')
|
||||
<div class="form-row">
|
||||
<div class="col-lg-4">
|
||||
<div class="form-group">
|
||||
<label for="mail_mailer">MAIL_MAILER <span class="text-danger">*</span></label>
|
||||
<input type="text" class="form-control" name="mail_mailer" value="{{ env('MAIL_MAILER') }}" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="form-group">
|
||||
<label for="mail_host">MAIL_HOST <span class="text-danger">*</span></label>
|
||||
<input type="text" class="form-control" name="mail_host" value="{{ env('MAIL_HOST') }}" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="form-group">
|
||||
<label for="mail_port">MAIL_PORT <span class="text-danger">*</span></label>
|
||||
<input type="number" class="form-control" name="mail_port" value="{{ env('MAIL_PORT') }}" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="col-lg-4">
|
||||
<div class="form-group">
|
||||
<label for="mail_mailer">MAIL_MAILER</label>
|
||||
<input type="text" class="form-control" name="mail_mailer" value="{{ env('MAIL_MAILER') }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="form-group">
|
||||
<label for="mail_username">MAIL_USERNAME</label>
|
||||
<input type="text" class="form-control" name="mail_username" value="{{ env('MAIL_USERNAME') }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="form-group">
|
||||
<label for="mail_password">MAIL_PASSWORD</label>
|
||||
<input type="password" class="form-control" name="mail_password" value="{{ env('MAIL_PASSWORD') }}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="col-lg-2">
|
||||
<div class="form-group">
|
||||
<label for="mail_encryption">MAIL_ENCRYPTION</label>
|
||||
<input type="text" class="form-control" name="mail_encryption" value="{{ env('MAIL_ENCRYPTION') }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-5">
|
||||
<div class="form-group">
|
||||
<label for="mail_from_address">MAIL_FROM_ADDRESS</label>
|
||||
<input type="email" class="form-control" name="mail_from_address" value="{{ env('MAIL_FROM_ADDRESS') }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-5">
|
||||
<div class="form-group">
|
||||
<label for="mail_from_name">MAIL_FROM_NAME <span class="text-danger">*</span></label>
|
||||
<input type="text" class="form-control" name="mail_from_name" value="{{ env('MAIL_FROM_NAME') }}" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group mb-0">
|
||||
<button type="submit" class="btn btn-primary"><i class="bi bi-check"></i> Save Changes</button>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
|
||||
Route::group(['middleware' => 'auth'], function () {
|
||||
|
||||
//Mail Settings
|
||||
Route::patch('/settings/smtp', 'SettingController@updateSmtp')->name('settings.smtp.update');
|
||||
//General Settings
|
||||
Route::get('/settings', 'SettingController@index')->name('settings.index');
|
||||
Route::patch('/settings', 'SettingController@update')->name('settings.update');
|
||||
|
||||
|
|
|
@ -49,21 +49,21 @@ class UploadController extends Controller
|
|||
|
||||
|
||||
public function dropzoneUpload(Request $request) {
|
||||
$path = storage_path('temp/dropzone');
|
||||
|
||||
if (!file_exists($path)) {
|
||||
mkdir($path, 0777, true);
|
||||
}
|
||||
|
||||
$file = $request->file('file');
|
||||
|
||||
$name = now()->timestamp . '.' . trim($file->getClientOriginalExtension());
|
||||
$filename = now()->timestamp . '.' . trim($file->getClientOriginalExtension());
|
||||
|
||||
$file->move($path, $name);
|
||||
Storage::putFileAs('temp/dropzone/', $file, $filename);
|
||||
|
||||
return response()->json([
|
||||
'name' => $name,
|
||||
'name' => $filename,
|
||||
'original_name' => $file->getClientOriginalName(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function dropzoneDelete(Request $request) {
|
||||
Storage::delete('temp/dropzone/' . $request->file_name);
|
||||
|
||||
return response()->json($request->file_name, 200);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ Route::group(['middleware' => 'auth'], function () {
|
|||
|
||||
//Dropzone
|
||||
Route::post('/dropzone/upload', 'UploadController@dropzoneUpload')->name('dropzone.upload');
|
||||
Route::post('/dropzone/delete', 'UploadController@dropzoneDelete')->name('dropzone.delete');
|
||||
//Filepond
|
||||
Route::post('/filepond/upload', 'UploadController@filepondUpload')->name('filepond.upload');
|
||||
Route::delete('/filepond/delete', 'UploadController@filepondDelete')->name('filepond.delete');
|
||||
|
|
|
@ -20,12 +20,15 @@ class ProductDataTable extends DataTable
|
|||
return view('product::products.partials.actions', compact('data'));
|
||||
})
|
||||
->addColumn('product_image', function ($data) {
|
||||
$url = $data->getFirstMediaUrl('images');
|
||||
$url = $data->getFirstMediaUrl('images', 'thumb');
|
||||
return '<img src="'.$url.'" border="0" width="50" class="img-thumbnail" align="center"/>';
|
||||
})
|
||||
->addColumn('product_price', function ($data) {
|
||||
return format_currency($data->product_price);
|
||||
})
|
||||
->addColumn('product_quantity', function ($data) {
|
||||
return $data->product_quantity . ' ' . $data->product_unit;
|
||||
})
|
||||
->rawColumns(['product_image']);
|
||||
}
|
||||
|
||||
|
@ -75,7 +78,7 @@ class ProductDataTable extends DataTable
|
|||
->title('Price')
|
||||
->className('text-center align-middle'),
|
||||
|
||||
Column::make('product_quantity')
|
||||
Column::computed('product_quantity')
|
||||
->title('Quantity')
|
||||
->className('text-center align-middle'),
|
||||
|
||||
|
|
|
@ -90,6 +90,7 @@ class Checkout extends Component
|
|||
'sub_total' => $this->calculate($product)['sub_total'],
|
||||
'code' => $product['product_code'],
|
||||
'stock' => $product['product_quantity'],
|
||||
'unit' => $product['product_unit'],
|
||||
'product_tax' => $this->calculate($product)['product_tax'],
|
||||
'unit_price' => $this->calculate($product)['unit_price']
|
||||
]
|
||||
|
@ -130,6 +131,7 @@ class Checkout extends Component
|
|||
'sub_total' => $cart_item->price * $cart_item->qty,
|
||||
'code' => $cart_item->options->code,
|
||||
'stock' => $cart_item->options->stock,
|
||||
'unit' => $cart_item->options->unit,
|
||||
'product_tax' => $cart_item->options->product_tax,
|
||||
'unit_price' => $cart_item->options->unit_price,
|
||||
'product_discount' => $cart_item->options->product_discount,
|
||||
|
@ -159,11 +161,11 @@ class Checkout extends Component
|
|||
|
||||
$this->updateCartOptions($row_id, $product_id, $cart_item, $discount_amount);
|
||||
} elseif ($this->discount_type[$product_id] == 'percentage') {
|
||||
$discount_amount = $cart_item->price * ($this->item_discount[$product_id] / 100);
|
||||
$discount_amount = ($cart_item->price + $cart_item->options->product_discount) * ($this->item_discount[$product_id] / 100);
|
||||
|
||||
Cart::instance($this->cart_instance)
|
||||
->update($row_id, [
|
||||
'price' => ($cart_item->price + $cart_item->options->product_discount) - (($cart_item->price * $this->item_discount[$product_id] / 100))
|
||||
'price' => ($cart_item->price + $cart_item->options->product_discount) - $discount_amount
|
||||
]);
|
||||
|
||||
$this->updateCartOptions($row_id, $product_id, $cart_item, $discount_amount);
|
||||
|
@ -203,6 +205,7 @@ class Checkout extends Component
|
|||
'sub_total' => $cart_item->price * $cart_item->qty,
|
||||
'code' => $cart_item->options->code,
|
||||
'stock' => $cart_item->options->stock,
|
||||
'unit' => $cart_item->options->unit,
|
||||
'product_tax' => $cart_item->options->product_tax,
|
||||
'unit_price' => $cart_item->options->unit_price,
|
||||
'product_discount' => $discount_amount,
|
||||
|
|
|
@ -74,6 +74,7 @@ class ProductCart extends Component
|
|||
|
||||
if ($exists->isNotEmpty()) {
|
||||
session()->flash('message', 'Product exists in the cart!');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -89,6 +90,7 @@ class ProductCart extends Component
|
|||
'sub_total' => $this->calculate($product)['sub_total'],
|
||||
'code' => $product['product_code'],
|
||||
'stock' => $product['product_quantity'],
|
||||
'unit' => $product['product_unit'],
|
||||
'product_tax' => $this->calculate($product)['product_tax'],
|
||||
'unit_price' => $this->calculate($product)['unit_price']
|
||||
]
|
||||
|
@ -127,6 +129,7 @@ class ProductCart extends Component
|
|||
'sub_total' => $cart_item->price * $cart_item->qty,
|
||||
'code' => $cart_item->options->code,
|
||||
'stock' => $cart_item->options->stock,
|
||||
'unit' => $cart_item->options->unit,
|
||||
'product_tax' => $cart_item->options->product_tax,
|
||||
'unit_price' => $cart_item->options->unit_price,
|
||||
'product_discount' => $cart_item->options->product_discount,
|
||||
|
@ -155,13 +158,12 @@ class ProductCart extends Component
|
|||
$discount_amount = $this->item_discount[$product_id];
|
||||
|
||||
$this->updateCartOptions($row_id, $product_id, $cart_item, $discount_amount);
|
||||
}
|
||||
elseif ($this->discount_type[$product_id] == 'percentage') {
|
||||
$discount_amount = $cart_item->price * ($this->item_discount[$product_id] / 100);
|
||||
} elseif ($this->discount_type[$product_id] == 'percentage') {
|
||||
$discount_amount = ($cart_item->price + $cart_item->options->product_discount) * ($this->item_discount[$product_id] / 100);
|
||||
|
||||
Cart::instance($this->cart_instance)
|
||||
->update($row_id, [
|
||||
'price' => ($cart_item->price + $cart_item->options->product_discount) - (($cart_item->price * $this->item_discount[$product_id] / 100))
|
||||
'price' => ($cart_item->price + $cart_item->options->product_discount) - $discount_amount
|
||||
]);
|
||||
|
||||
$this->updateCartOptions($row_id, $product_id, $cart_item, $discount_amount);
|
||||
|
@ -181,14 +183,12 @@ class ProductCart extends Component
|
|||
$unit_price = $product['product_price'];
|
||||
$product_tax = $product['product_price'] * ($product['product_order_tax'] / 100);
|
||||
$sub_total = $product['product_price'] + ($product['product_price'] * ($product['product_order_tax'] / 100));
|
||||
}
|
||||
elseif ($product['product_tax_type'] == 2) {
|
||||
} elseif ($product['product_tax_type'] == 2) {
|
||||
$price = $product['product_price'];
|
||||
$unit_price = $product['product_price'] - ($product['product_price'] * ($product['product_order_tax'] / 100));
|
||||
$product_tax = $product['product_price'] * ($product['product_order_tax'] / 100);
|
||||
$sub_total = $product['product_price'];
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$price = $product['product_price'];
|
||||
$unit_price = $product['product_price'];
|
||||
$product_tax = 0.00;
|
||||
|
@ -203,6 +203,7 @@ class ProductCart extends Component
|
|||
'sub_total' => $cart_item->price * $cart_item->qty,
|
||||
'code' => $cart_item->options->code,
|
||||
'stock' => $cart_item->options->stock,
|
||||
'unit' => $cart_item->options->unit,
|
||||
'product_tax' => $cart_item->options->product_tax,
|
||||
'unit_price' => $cart_item->options->unit_price,
|
||||
'product_discount' => $discount_amount,
|
||||
|
|
|
@ -52,7 +52,7 @@ class User extends Authenticatable implements HasMedia
|
|||
public function registerMediaCollections(): void
|
||||
{
|
||||
$this->addMediaCollection('avatars')
|
||||
->useFallbackUrl('/images/fallback_profile_image.png');
|
||||
->useFallbackUrl('https://www.gravatar.com/avatar/' . md5($this->attributes['email']));
|
||||
}
|
||||
|
||||
public function scopeIsActive(Builder $builder) {
|
||||
|
|
|
@ -18,7 +18,7 @@ class SuperUserSeeder extends Seeder
|
|||
{
|
||||
$user = User::create([
|
||||
'name' => 'Administrator',
|
||||
'email' => 'admin@gmail.com',
|
||||
'email' => 'admin@test.com',
|
||||
'password' => Hash::make(12345678),
|
||||
'is_active' => 1
|
||||
]);
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<div wire:click.prevent="selectProduct({{ $product }})" class="col-lg-4 col-md-6" style="cursor: pointer;">
|
||||
<div class="card border-0 shadow">
|
||||
<div class="position-relative">
|
||||
<img height="140" src="{{ $product->getFirstMediaUrl('images') }}" class="card-img-top" alt="Product Image">
|
||||
<img src="{{ $product->getFirstMediaUrl('images') }}" class="card-img-top" alt="Product Image">
|
||||
<div class="badge badge-info mb-3 position-absolute" style="left:10px;top: 10px;">Stock: {{ $product->product_quantity }}</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
<td class="align-middle">{{ format_currency($cart_item->options->unit_price) }}</td>
|
||||
|
||||
<td class="align-middle text-center">
|
||||
<span class="badge badge-info">{{ $cart_item->options->stock }}</span>
|
||||
<span class="badge badge-info">{{ $cart_item->options->stock . ' ' . $cart_item->options->unit }}</span>
|
||||
</td>
|
||||
|
||||
<td class="align-middle">
|
||||
|
@ -64,9 +64,9 @@
|
|||
</td>
|
||||
|
||||
<td class="align-middle text-center">
|
||||
<button wire:click.prevent="removeItem('{{ $cart_item->rowId }}')" type="button" class="btn btn-danger">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
<a href="#" wire:click.prevent="removeItem('{{ $cart_item->rowId }}')">
|
||||
<i class="bi bi-x-circle font-2xl text-danger"></i>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
|
|
Before Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB |