Added: Adjustment Module
This commit is contained in:
parent
7b7d0c9389
commit
b800ef883a
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'name' => 'Adjustment'
|
||||
];
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateAdjustmentsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('adjustments', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->date('date');
|
||||
$table->string('reference');
|
||||
$table->text('note')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('adjustments');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateAdjustedProductsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('adjusted_products', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('adjustment_id');
|
||||
$table->unsignedBigInteger('product_id');
|
||||
$table->integer('quantity');
|
||||
$table->string('type');
|
||||
$table->foreign('adjustment_id')->references('id')->on('adjustments')->onDelete('cascade');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('adjusted_products');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Adjustment\Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class AdjustmentDatabaseSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
Model::unguard();
|
||||
|
||||
// $this->call("OthersTableSeeder");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Adjustment\Entities;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Modules\Product\Entities\Product;
|
||||
|
||||
class AdjustedProduct extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
protected $with = ['product'];
|
||||
|
||||
public function adjustment() {
|
||||
return $this->belongsTo(Adjustment::class, 'adjustment_id', 'id');
|
||||
}
|
||||
|
||||
public function product() {
|
||||
return $this->belongsTo(Product::class, 'product_id', 'id');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Adjustment\Entities;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
class Adjustment extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
public function getDateAttribute($value) {
|
||||
return Carbon::parse($value)->format('M d, Y');
|
||||
}
|
||||
|
||||
public function adjustedProducts() {
|
||||
return $this->hasMany(AdjustedProduct::class, 'adjustment_id', 'id');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Adjustment\Http\Controllers;
|
||||
|
||||
use App\DataTables\AdjustmentsDataTable;
|
||||
use Illuminate\Contracts\Support\Renderable;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Modules\Adjustment\Entities\AdjustedProduct;
|
||||
use Modules\Adjustment\Entities\Adjustment;
|
||||
use Modules\Product\Entities\Product;
|
||||
|
||||
class AdjustmentController extends Controller
|
||||
{
|
||||
|
||||
public function index(AdjustmentsDataTable $dataTable) {
|
||||
abort_if(Gate::denies('access_adjustments'), 403);
|
||||
|
||||
return $dataTable->render('adjustment::index');
|
||||
}
|
||||
|
||||
|
||||
public function create() {
|
||||
abort_if(Gate::denies('create_adjustments'), 403);
|
||||
|
||||
return view('adjustment::create');
|
||||
}
|
||||
|
||||
|
||||
public function store(Request $request) {
|
||||
abort_if(Gate::denies('create_adjustments'), 403);
|
||||
|
||||
$request->validate([
|
||||
'reference' => 'required|string|max:255',
|
||||
'date' => 'required|date',
|
||||
'note' => 'nullable|string|max:1000',
|
||||
'product_ids' => 'required',
|
||||
'quantities' => 'required',
|
||||
'types' => 'required'
|
||||
]);
|
||||
|
||||
DB::transaction(function () use ($request) {
|
||||
$adjustment = Adjustment::create([
|
||||
'reference' => $request->reference,
|
||||
'date' => $request->date,
|
||||
'note' => $request->note
|
||||
]);
|
||||
|
||||
foreach ($request->product_ids as $key => $id) {
|
||||
AdjustedProduct::create([
|
||||
'adjustment_id' => $adjustment->id,
|
||||
'product_id' => $id,
|
||||
'quantity' => $request->quantities[$key],
|
||||
'type' => $request->types[$key]
|
||||
]);
|
||||
|
||||
$product = Product::findOrFail($id);
|
||||
|
||||
if ($request->types[$key] == 'add') {
|
||||
$product->update([
|
||||
'product_quantity' => $product->product_quantity + $request->quantities[$key]
|
||||
]);
|
||||
} elseif ($request->types[$key] == 'sub') {
|
||||
$product->update([
|
||||
'product_quantity' => $product->product_quantity - $request->quantities[$key]
|
||||
]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
toast('Adjustment Created!', 'success');
|
||||
|
||||
return redirect()->route('adjustments.index');
|
||||
}
|
||||
|
||||
|
||||
public function show(Adjustment $adjustment) {
|
||||
abort_if(Gate::denies('show_adjustments'), 403);
|
||||
|
||||
return view('adjustment::show', compact('adjustment'));
|
||||
}
|
||||
|
||||
|
||||
public function edit(Adjustment $adjustment) {
|
||||
abort_if(Gate::denies('edit_adjustments'), 403);
|
||||
|
||||
return view('adjustment::edit', compact('adjustment'));
|
||||
}
|
||||
|
||||
|
||||
public function update(Request $request, Adjustment $adjustment) {
|
||||
abort_if(Gate::denies('edit_adjustments'), 403);
|
||||
|
||||
$request->validate([
|
||||
'reference' => 'required|string|max:255',
|
||||
'date' => 'required|date',
|
||||
'note' => 'nullable|string|max:1000',
|
||||
'product_ids' => 'required',
|
||||
'quantities' => 'required',
|
||||
'types' => 'required'
|
||||
]);
|
||||
|
||||
DB::transaction(function () use ($request, $adjustment) {
|
||||
$adjustment->update([
|
||||
'reference' => $request->reference,
|
||||
'date' => $request->date,
|
||||
'note' => $request->note
|
||||
]);
|
||||
|
||||
foreach ($adjustment->adjustedProducts as $adjustedProduct) {
|
||||
$product = Product::findOrFail($adjustedProduct->product->id);
|
||||
|
||||
if ($adjustedProduct->type == 'add') {
|
||||
$product->update([
|
||||
'product_quantity' => $product->product_quantity - $adjustedProduct->quantity
|
||||
]);
|
||||
} elseif ($adjustedProduct->type == 'sub') {
|
||||
$product->update([
|
||||
'product_quantity' => $product->product_quantity + $adjustedProduct->quantity
|
||||
]);
|
||||
}
|
||||
|
||||
$adjustedProduct->delete();
|
||||
}
|
||||
|
||||
foreach ($request->product_ids as $key => $id) {
|
||||
AdjustedProduct::create([
|
||||
'adjustment_id' => $adjustment->id,
|
||||
'product_id' => $id,
|
||||
'quantity' => $request->quantities[$key],
|
||||
'type' => $request->types[$key]
|
||||
]);
|
||||
|
||||
$product = Product::findOrFail($id);
|
||||
|
||||
if ($request->types[$key] == 'add')
|
||||
{
|
||||
$product->update([
|
||||
'product_quantity' => $product->product_quantity + $request->quantities[$key]
|
||||
]);
|
||||
} elseif ($request->types[$key] == 'sub') {
|
||||
$product->update([
|
||||
'product_quantity' => $product->product_quantity - $request->quantities[$key]
|
||||
]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
toast('Adjustment Updated!', 'info');
|
||||
|
||||
return redirect()->route('adjustments.index');
|
||||
}
|
||||
|
||||
|
||||
public function destroy(Adjustment $adjustment) {
|
||||
abort_if(Gate::denies('delete_adjustments'), 403);
|
||||
|
||||
$adjustment->delete();
|
||||
|
||||
toast('Adjustment Deleted!', 'warning');
|
||||
|
||||
return redirect()->route('adjustments.index');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Adjustment\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Database\Eloquent\Factory;
|
||||
|
||||
class AdjustmentServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* @var string $moduleName
|
||||
*/
|
||||
protected $moduleName = 'Adjustment';
|
||||
|
||||
/**
|
||||
* @var string $moduleNameLower
|
||||
*/
|
||||
protected $moduleNameLower = 'adjustment';
|
||||
|
||||
/**
|
||||
* Boot the application events.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->registerTranslations();
|
||||
$this->registerConfig();
|
||||
$this->registerViews();
|
||||
$this->loadMigrationsFrom(module_path($this->moduleName, 'Database/Migrations'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the service provider.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
$this->app->register(RouteServiceProvider::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register config.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function registerConfig()
|
||||
{
|
||||
$this->publishes([
|
||||
module_path($this->moduleName, 'Config/config.php') => config_path($this->moduleNameLower . '.php'),
|
||||
], 'config');
|
||||
$this->mergeConfigFrom(
|
||||
module_path($this->moduleName, 'Config/config.php'), $this->moduleNameLower
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register views.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function registerViews()
|
||||
{
|
||||
$viewPath = resource_path('views/modules/' . $this->moduleNameLower);
|
||||
|
||||
$sourcePath = module_path($this->moduleName, 'Resources/views');
|
||||
|
||||
$this->publishes([
|
||||
$sourcePath => $viewPath
|
||||
], ['views', $this->moduleNameLower . '-module-views']);
|
||||
|
||||
$this->loadViewsFrom(array_merge($this->getPublishableViewPaths(), [$sourcePath]), $this->moduleNameLower);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register translations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function registerTranslations()
|
||||
{
|
||||
$langPath = resource_path('lang/modules/' . $this->moduleNameLower);
|
||||
|
||||
if (is_dir($langPath)) {
|
||||
$this->loadTranslationsFrom($langPath, $this->moduleNameLower);
|
||||
} else {
|
||||
$this->loadTranslationsFrom(module_path($this->moduleName, 'Resources/lang'), $this->moduleNameLower);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the services provided by the provider.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function provides()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
private function getPublishableViewPaths(): array
|
||||
{
|
||||
$paths = [];
|
||||
foreach (\Config::get('view.paths') as $path) {
|
||||
if (is_dir($path . '/modules/' . $this->moduleNameLower)) {
|
||||
$paths[] = $path . '/modules/' . $this->moduleNameLower;
|
||||
}
|
||||
}
|
||||
return $paths;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Adjustment\Providers;
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
|
||||
class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The module namespace to assume when generating URLs to actions.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $moduleNamespace = 'Modules\Adjustment\Http\Controllers';
|
||||
|
||||
/**
|
||||
* Called before routes are registered.
|
||||
*
|
||||
* Register any model bindings or pattern based filters.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
parent::boot();
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the routes for the application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function map()
|
||||
{
|
||||
$this->mapApiRoutes();
|
||||
|
||||
$this->mapWebRoutes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the "web" routes for the application.
|
||||
*
|
||||
* These routes all receive session state, CSRF protection, etc.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function mapWebRoutes()
|
||||
{
|
||||
Route::middleware('web')
|
||||
->namespace($this->moduleNamespace)
|
||||
->group(module_path('Adjustment', '/Routes/web.php'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the "api" routes for the application.
|
||||
*
|
||||
* These routes are typically stateless.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function mapApiRoutes()
|
||||
{
|
||||
Route::prefix('api')
|
||||
->middleware('api')
|
||||
->namespace($this->moduleNamespace)
|
||||
->group(module_path('Adjustment', '/Routes/api.php'));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Create Adjustment')
|
||||
|
||||
@push('page_css')
|
||||
@livewireStyles
|
||||
@endpush
|
||||
|
||||
@section('breadcrumb')
|
||||
<ol class="breadcrumb border-0 m-0">
|
||||
<li class="breadcrumb-item"><a href="{{ route('home') }}">Home</a></li>
|
||||
<li class="breadcrumb-item"><a href="{{ route('adjustments.index') }}">Adjustments</a></li>
|
||||
<li class="breadcrumb-item active">Add</li>
|
||||
</ol>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="container-fluid mb-4">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<livewire:search-product/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mt-4">
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
@include('utils.alerts')
|
||||
<form action="{{ route('adjustments.store') }}" method="POST">
|
||||
@csrf
|
||||
<div class="form-row">
|
||||
<div class="col-lg-6">
|
||||
<div class="form-group">
|
||||
<label for="reference">Reference <span class="text-danger">*</span></label>
|
||||
<input type="text" class="form-control" name="reference" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="from-group">
|
||||
<div class="form-group">
|
||||
<label for="date">Date <span class="text-danger">*</span></label>
|
||||
<input type="date" class="form-control" name="date" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<livewire:adjustment.product-table/>
|
||||
<div class="form-group">
|
||||
<label for="note">Note (If Needed)</label>
|
||||
<textarea name="note" id="note" rows="5" class="form-control"></textarea>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
Create Adjustment <i class="bi bi-check"></i>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
|
@ -0,0 +1,67 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Edit Adjustment')
|
||||
|
||||
@push('page_css')
|
||||
@livewireStyles
|
||||
@endpush
|
||||
|
||||
@section('breadcrumb')
|
||||
<ol class="breadcrumb border-0 m-0">
|
||||
<li class="breadcrumb-item"><a href="{{ route('home') }}">Home</a></li>
|
||||
<li class="breadcrumb-item"><a href="{{ route('adjustments.index') }}">Adjustments</a></li>
|
||||
<li class="breadcrumb-item active">Edit</li>
|
||||
</ol>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="container-fluid mb-4">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<livewire:search-product/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mt-4">
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
@include('utils.alerts')
|
||||
<form action="{{ route('adjustments.update', $adjustment) }}" method="POST">
|
||||
@csrf
|
||||
@method('patch')
|
||||
<div class="form-row">
|
||||
<div class="col-lg-6">
|
||||
<div class="form-group">
|
||||
<label for="reference">Reference <span class="text-danger">*</span></label>
|
||||
<input type="text" class="form-control" name="reference" required value="{{ $adjustment->reference }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="from-group">
|
||||
<div class="form-group">
|
||||
<label for="date">Date <span class="text-danger">*</span></label>
|
||||
<input type="date" class="form-control" name="date" required value="{{ $adjustment->getAttributes()['date'] }}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<livewire:adjustment.product-table :adjustedProducts="$adjustment->adjustedProducts->toArray()"/>
|
||||
<div class="form-group">
|
||||
<label for="note">Note (If Needed)</label>
|
||||
<textarea name="note" id="note" rows="5" class="form-control">
|
||||
{{ $adjustment->note }}
|
||||
</textarea>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
Update Adjustment <i class="bi bi-check"></i>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
|
@ -0,0 +1,40 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Adjustments')
|
||||
|
||||
@section('third_party_stylesheets')
|
||||
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.25/css/dataTables.bootstrap4.min.css">
|
||||
@endsection
|
||||
|
||||
@section('breadcrumb')
|
||||
<ol class="breadcrumb border-0 m-0">
|
||||
<li class="breadcrumb-item"><a href="{{ route('home') }}">Home</a></li>
|
||||
<li class="breadcrumb-item active">Adjustments</li>
|
||||
</ol>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<a href="{{ route('adjustments.create') }}" class="btn btn-primary">
|
||||
Add Adjustment <i class="bi bi-plus"></i>
|
||||
</a>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="table-responsive">
|
||||
{!! $dataTable->table() !!}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('page_scripts')
|
||||
{!! $dataTable->scripts() !!}
|
||||
@endpush
|
|
@ -0,0 +1,24 @@
|
|||
@can('edit_adjustments')
|
||||
<a href="{{ route('adjustments.edit', $data->id) }}" class="btn btn-info btn-sm">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</a>
|
||||
@endcan
|
||||
@can('show_adjustments')
|
||||
<a href="{{ route('adjustments.show', $data->id) }}" class="btn btn-primary btn-sm">
|
||||
<i class="bi bi-eye"></i>
|
||||
</a>
|
||||
@endcan
|
||||
@can('delete_adjustments')
|
||||
<button id="delete" class="btn btn-danger btn-sm" onclick="
|
||||
event.preventDefault();
|
||||
if (confirm('Are you sure? It will delete the data permanently!')) {
|
||||
document.getElementById('destroy{{ $data->id }}').submit()
|
||||
}
|
||||
">
|
||||
<i class="bi bi-trash"></i>
|
||||
<form id="destroy{{ $data->id }}" class="d-none" action="{{ route('adjustments.destroy', $data->id) }}" method="POST">
|
||||
@csrf
|
||||
@method('delete')
|
||||
</form>
|
||||
</button>
|
||||
@endcan
|
|
@ -0,0 +1,70 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Adjustment Details')
|
||||
|
||||
@push('page_css')
|
||||
@livewireStyles
|
||||
@endpush
|
||||
|
||||
@section('breadcrumb')
|
||||
<ol class="breadcrumb border-0 m-0">
|
||||
<li class="breadcrumb-item"><a href="{{ route('home') }}">Home</a></li>
|
||||
<li class="breadcrumb-item"><a href="{{ route('adjustments.index') }}">Adjustments</a></li>
|
||||
<li class="breadcrumb-item active">Details</li>
|
||||
</ol>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered">
|
||||
<tr>
|
||||
<th colspan="2">
|
||||
Date
|
||||
</th>
|
||||
<th colspan="2">
|
||||
Reference
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
{{ $adjustment->date }}
|
||||
</td>
|
||||
<td colspan="2">
|
||||
{{ $adjustment->reference }}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Product Name</th>
|
||||
<th>Code</th>
|
||||
<th>Quantity</th>
|
||||
<th>Type</th>
|
||||
</tr>
|
||||
|
||||
@foreach($adjustment->adjustedProducts as $adjustedProduct)
|
||||
<tr>
|
||||
<td>{{ $adjustedProduct->product->product_name }}</td>
|
||||
<td>{{ $adjustedProduct->product->product_code }}</td>
|
||||
<td>{{ $adjustedProduct->quantity }}</td>
|
||||
<td>
|
||||
@if($adjustedProduct->type == 'add')
|
||||
(+) Addition
|
||||
@else
|
||||
(-) Subtraction
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| API Routes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you can register API routes for your application. These
|
||||
| routes are loaded by the RouteServiceProvider within a group which
|
||||
| is assigned the "api" middleware group. Enjoy building your API!
|
||||
|
|
||||
*/
|
||||
|
||||
Route::middleware('auth:api')->get('/adjustment', function (Request $request) {
|
||||
return $request->user();
|
||||
});
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Web Routes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you can register web routes for your application. These
|
||||
| routes are loaded by the RouteServiceProvider within a group which
|
||||
| contains the "web" middleware group. Now create something great!
|
||||
|
|
||||
*/
|
||||
|
||||
Route::group(['middleware' => 'auth'], function () {
|
||||
//Product Adjustment
|
||||
Route::resource('adjustments', 'AdjustmentController');
|
||||
});
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"name": "nwidart/adjustment",
|
||||
"description": "",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Widart",
|
||||
"email": "n.widart@gmail.com"
|
||||
}
|
||||
],
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [],
|
||||
"aliases": {
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Modules\\Adjustment\\": ""
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "Adjustment",
|
||||
"alias": "adjustment",
|
||||
"description": "",
|
||||
"keywords": [],
|
||||
"priority": 0,
|
||||
"providers": [
|
||||
"Modules\\Adjustment\\Providers\\AdjustmentServiceProvider"
|
||||
],
|
||||
"aliases": {},
|
||||
"files": [],
|
||||
"requires": []
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "npm run development",
|
||||
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||
"watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||
"watch-poll": "npm run watch -- --watch-poll",
|
||||
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||
"prod": "npm run production",
|
||||
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"cross-env": "^7.0",
|
||||
"laravel-mix": "^5.0.1",
|
||||
"laravel-mix-merge-manifest": "^0.1.2"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
const dotenvExpand = require('dotenv-expand');
|
||||
dotenvExpand(require('dotenv').config({ path: '../../.env'/*, debug: true*/}));
|
||||
|
||||
const mix = require('laravel-mix');
|
||||
require('laravel-mix-merge-manifest');
|
||||
|
||||
mix.setPublicPath('../../public').mergeManifest();
|
||||
|
||||
mix.js(__dirname + '/Resources/assets/js/app.js', 'js/adjustment.js')
|
||||
.sass( __dirname + '/Resources/assets/sass/app.scss', 'css/adjustment.css');
|
||||
|
||||
if (mix.inProduction()) {
|
||||
mix.version();
|
||||
}
|
|
@ -17,7 +17,7 @@
|
|||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<livewire:barcode.search-product/>
|
||||
<livewire:search-product/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
<div class="form-row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label for="product_quantity">Staring Quantity <span class="text-danger">*</span></label>
|
||||
<label for="product_quantity">Quantity <span class="text-danger">*</span></label>
|
||||
<input type="number" class="form-control" name="product_quantity" required value="{{ old('product_quantity') }}" min="1">
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
<div class="form-row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label for="product_quantity">Staring Quantity <span class="text-danger">*</span></label>
|
||||
<label for="product_quantity">Quantity <span class="text-danger">*</span></label>
|
||||
<input type="number" class="form-control" name="product_quantity" required value="{{ $product->product_quantity }}" min="1">
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
<?php
|
||||
|
||||
namespace App\DataTables;
|
||||
|
||||
use Modules\Adjustment\Entities\Adjustment;
|
||||
use Yajra\DataTables\Html\Button;
|
||||
use Yajra\DataTables\Html\Column;
|
||||
use Yajra\DataTables\Html\Editor\Editor;
|
||||
use Yajra\DataTables\Html\Editor\Fields;
|
||||
use Yajra\DataTables\Services\DataTable;
|
||||
|
||||
class AdjustmentsDataTable extends DataTable
|
||||
{
|
||||
/**
|
||||
* Build DataTable class.
|
||||
*
|
||||
* @param mixed $query Results from query() method.
|
||||
* @return \Yajra\DataTables\DataTableAbstract
|
||||
*/
|
||||
public function dataTable($query)
|
||||
{
|
||||
return datatables()
|
||||
->eloquent($query)
|
||||
->addColumn('action', function ($data) {
|
||||
return view('adjustment::partials.actions', compact('data'));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get query source of dataTable.
|
||||
*
|
||||
* @param \Modules\Adjustment\Entities\Adjustment $model
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function query(Adjustment $model)
|
||||
{
|
||||
return $model->newQuery()->withCount('adjustedProducts');
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional method if you want to use html builder.
|
||||
*
|
||||
* @return \Yajra\DataTables\Html\Builder
|
||||
*/
|
||||
public function html()
|
||||
{
|
||||
return $this->builder()
|
||||
->setTableId('adjustments-table')
|
||||
->columns($this->getColumns())
|
||||
->minifiedAjax()
|
||||
->dom("<'row'<'col-md-3'l><'col-md-5 mb-2'B><'col-md-4'f>> .
|
||||
'tr' .
|
||||
<'row'<'col-md-5'i><'col-md-7 mt-2'p>>")
|
||||
->orderBy(0)
|
||||
->buttons(
|
||||
Button::make('excel')
|
||||
->text('<i class="bi bi-file-earmark-excel-fill"></i> Excel'),
|
||||
Button::make('print')
|
||||
->text('<i class="bi bi-printer-fill"></i> Print'),
|
||||
Button::make('reset')
|
||||
->text('<i class="bi bi-x-circle"></i> Reset'),
|
||||
Button::make('reload')
|
||||
->text('<i class="bi bi-arrow-repeat"></i> Reload')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get columns.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getColumns()
|
||||
{
|
||||
return [
|
||||
Column::make('date')
|
||||
->className('text-center align-middle'),
|
||||
|
||||
Column::make('reference')
|
||||
->className('text-center align-middle'),
|
||||
|
||||
Column::make('adjusted_products_count')
|
||||
->title('Products')
|
||||
->className('text-center align-middle'),
|
||||
|
||||
Column::computed('action')
|
||||
->exportable(false)
|
||||
->printable(false)
|
||||
->className('text-center align-middle')
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get filename for export.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function filename()
|
||||
{
|
||||
return 'Adjustments_' . date('YmdHis');
|
||||
}
|
||||
}
|
|
@ -80,39 +80,32 @@ class ProductDataTable extends DataTable
|
|||
return [
|
||||
Column::computed('product_image')
|
||||
->title('Image')
|
||||
->addClass('text-center')
|
||||
->addClass('align-middle'),
|
||||
->className('text-center align-middle'),
|
||||
|
||||
Column::make('product_name')
|
||||
->title('Name')
|
||||
->addClass('text-center')
|
||||
->addClass('align-middle'),
|
||||
->className('text-center align-middle'),
|
||||
|
||||
Column::make('product_code')
|
||||
->title('Code')
|
||||
->addClass('text-center')
|
||||
->addClass('align-middle'),
|
||||
->className('text-center align-middle'),
|
||||
|
||||
Column::make('product_price')
|
||||
->title('Price')
|
||||
->addClass('text-center')
|
||||
->addClass('align-middle'),
|
||||
->className('text-center align-middle'),
|
||||
|
||||
Column::make('product_quantity')
|
||||
->title('Quantity')
|
||||
->addClass('text-center')
|
||||
->addClass('align-middle'),
|
||||
->className('text-center align-middle'),
|
||||
|
||||
Column::make('category.category_name')
|
||||
->title('Category')
|
||||
->addClass('text-center')
|
||||
->addClass('align-middle'),
|
||||
->className('text-center align-middle'),
|
||||
|
||||
Column::computed('action')
|
||||
->exportable(false)
|
||||
->printable(false)
|
||||
->addClass('text-center')
|
||||
->addClass('align-middle'),
|
||||
->className('text-center align-middle')
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Adjustment;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use Livewire\Component;
|
||||
use Modules\Product\Entities\Product;
|
||||
|
||||
class ProductTable extends Component
|
||||
{
|
||||
|
||||
protected $listeners = ['productSelected'];
|
||||
|
||||
public $products;
|
||||
public $hasAdjustments;
|
||||
|
||||
public function mount($adjustedProducts = null) {
|
||||
$this->products = [];
|
||||
|
||||
if ($adjustedProducts) {
|
||||
$this->hasAdjustments = true;
|
||||
$this->products = $adjustedProducts;
|
||||
} else {
|
||||
$this->hasAdjustments = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function render() {
|
||||
return view('livewire.adjustment.product-table');
|
||||
}
|
||||
|
||||
public function productSelected($product) {
|
||||
switch ($this->hasAdjustments) {
|
||||
case true:
|
||||
if (in_array($product, array_map(function ($adjustment) {
|
||||
return $adjustment['product'];
|
||||
}, $this->products))) {
|
||||
return session()->flash('message', 'Already exists in the product table!');
|
||||
}
|
||||
break;
|
||||
case false:
|
||||
if (in_array($product, $this->products)) {
|
||||
return session()->flash('message', 'Already exists in the product table!');
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return session()->flash('message', 'Something went wrong!');;
|
||||
}
|
||||
|
||||
array_push($this->products, $product);
|
||||
}
|
||||
|
||||
public function removeProduct($key) {
|
||||
unset($this->products[$key]);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Barcode;
|
||||
namespace App\Http\Livewire;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use Livewire\Component;
|
||||
|
@ -18,7 +18,7 @@ class SearchProduct extends Component
|
|||
}
|
||||
|
||||
public function render() {
|
||||
return view('livewire.barcode.search-product');
|
||||
return view('livewire.search-product');
|
||||
}
|
||||
|
||||
public function updatedQuery() {
|
|
@ -7,9 +7,11 @@
|
|||
"require": {
|
||||
"php": "^7.3|^8.0",
|
||||
"barryvdh/laravel-snappy": "^0.4.8",
|
||||
"bumbummen99/shoppingcart": "^4.0",
|
||||
"fideloper/proxy": "^4.4",
|
||||
"fruitcake/laravel-cors": "^2.0",
|
||||
"guzzlehttp/guzzle": "^7.0.1",
|
||||
"h4cc/wkhtmltopdf-amd64": "^0.12.4",
|
||||
"infyomlabs/laravel-ui-coreui": "^3.0",
|
||||
"laravel/framework": "^8.40",
|
||||
"laravel/tinker": "^2.5",
|
||||
|
@ -62,7 +64,10 @@
|
|||
"config": {
|
||||
"optimize-autoloader": true,
|
||||
"preferred-install": "dist",
|
||||
"sort-packages": true
|
||||
"sort-packages": true,
|
||||
"platform": {
|
||||
"php": "7.4"
|
||||
}
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "53badb2a324d9caf89ceed410177f49b",
|
||||
"content-hash": "81cce1ef2defb71f07fb109dda14cc2c",
|
||||
"packages": [
|
||||
{
|
||||
"name": "asm89/stack-cors",
|
||||
|
@ -183,6 +183,77 @@
|
|||
],
|
||||
"time": "2021-01-20T22:51:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "bumbummen99/shoppingcart",
|
||||
"version": "4.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/bumbummen99/LaravelShoppingcart.git",
|
||||
"reference": "f2c763e311b0fc58b2dfdfa2c41c6318a7c884e1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/bumbummen99/LaravelShoppingcart/zipball/f2c763e311b0fc58b2dfdfa2c41c6318a7c884e1",
|
||||
"reference": "f2c763e311b0fc58b2dfdfa2c41c6318a7c884e1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/events": "5.4.*||5.5.*||5.6.*||5.7.*||5.8.*||^6.0||^7.0||^8.0",
|
||||
"illuminate/session": "5.4.*||5.5.*||5.6.*||5.7.*||5.8.*||^6.0||^7.0||^8.0",
|
||||
"illuminate/support": "5.4.*||5.5.*||5.6.*||5.7.*||5.8.*||^6.0||^7.0||^8.0",
|
||||
"nesbot/carbon": "~1.20||^1.26.3||^2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^1.0",
|
||||
"orchestra/testbench": "^3.4|^4.0|^5.0|^6.0",
|
||||
"phpunit/phpunit": "~5.0||~6.0||~7.0||~8.0||~9.0"
|
||||
},
|
||||
"suggest": {
|
||||
"gloudemans/notify": "Simple flash notifications for Laravel"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Gloudemans\\Shoppingcart\\ShoppingcartServiceProvider"
|
||||
],
|
||||
"aliases": {
|
||||
"Cart": "Gloudemans\\Shoppingcart\\Facades\\Cart"
|
||||
}
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Gloudemans\\Shoppingcart\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Rob Gloudemans",
|
||||
"email": "info@robgloudemans.nl",
|
||||
"homepage": "http://robgloudemans.nl/"
|
||||
},
|
||||
{
|
||||
"name": "Patrick Henninger",
|
||||
"email": "privat@skyraptor.eu",
|
||||
"homepage": "https://skyraptor.eu/"
|
||||
}
|
||||
],
|
||||
"description": "Laravel Shoppingcart",
|
||||
"keywords": [
|
||||
"laravel",
|
||||
"shoppingcart"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/bumbummen99/LaravelShoppingcart/issues",
|
||||
"source": "https://github.com/bumbummen99/LaravelShoppingcart/tree/4.0.0"
|
||||
},
|
||||
"time": "2021-01-18T23:55:30+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/inflector",
|
||||
"version": "2.0.3",
|
||||
|
@ -980,6 +1051,55 @@
|
|||
},
|
||||
"time": "2021-06-30T20:03:07+00:00"
|
||||
},
|
||||
{
|
||||
"name": "h4cc/wkhtmltopdf-amd64",
|
||||
"version": "0.12.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/h4cc/wkhtmltopdf-amd64.git",
|
||||
"reference": "4e2ab2d032a5d7fbe2a741de8b10b8989523c95b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/h4cc/wkhtmltopdf-amd64/zipball/4e2ab2d032a5d7fbe2a741de8b10b8989523c95b",
|
||||
"reference": "4e2ab2d032a5d7fbe2a741de8b10b8989523c95b",
|
||||
"shasum": ""
|
||||
},
|
||||
"bin": [
|
||||
"bin/wkhtmltopdf-amd64"
|
||||
],
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"h4cc\\WKHTMLToPDF\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"LGPL Version 3"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Julius Beckmann",
|
||||
"email": "github@h4cc.de"
|
||||
}
|
||||
],
|
||||
"description": "Convert html to pdf using webkit (qtwebkit). Static linked linux binary for amd64 systems.",
|
||||
"homepage": "http://wkhtmltopdf.org/",
|
||||
"keywords": [
|
||||
"binary",
|
||||
"convert",
|
||||
"pdf",
|
||||
"snapshot",
|
||||
"thumbnail",
|
||||
"wkhtmltopdf"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/h4cc/wkhtmltopdf-amd64/issues",
|
||||
"source": "https://github.com/h4cc/wkhtmltopdf-amd64/tree/master"
|
||||
},
|
||||
"time": "2018-01-15T06:57:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "infyomlabs/laravel-generator-helpers",
|
||||
"version": "v3.0.0",
|
||||
|
@ -9611,5 +9731,8 @@
|
|||
"php": "^7.3|^8.0"
|
||||
},
|
||||
"platform-dev": [],
|
||||
"plugin-api-version": "2.0.0"
|
||||
"platform-overrides": {
|
||||
"php": "7.4"
|
||||
},
|
||||
"plugin-api-version": "2.1.0"
|
||||
}
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Gross price as base price
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This default value is used to select the method to calculate prices and taxes
|
||||
| If true the item price is managed as a gross price, so taxes will be calculated by separation/exclusion
|
||||
|
|
||||
*/
|
||||
|
||||
'calculator' => \Gloudemans\Shoppingcart\Calculation\DefaultCalculator::class,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Default tax rate
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This default tax rate will be used when you make a class implement the
|
||||
| Taxable interface and use the HasTax trait.
|
||||
|
|
||||
*/
|
||||
|
||||
'tax' => 0,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Shoppingcart database settings
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you can set the connection that the shoppingcart should use when
|
||||
| storing and restoring a cart.
|
||||
|
|
||||
*/
|
||||
|
||||
'database' => [
|
||||
|
||||
'connection' => null,
|
||||
|
||||
'table' => 'shoppingcart',
|
||||
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Destroy the cart on user logout
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| When this option is set to 'true' the cart will automatically
|
||||
| destroy all cart instances when the user logs out.
|
||||
|
|
||||
*/
|
||||
|
||||
'destroy_on_logout' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Default number format
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This defaults will be used for the formatted numbers if you don't
|
||||
| set them in the method call.
|
||||
|
|
||||
*/
|
||||
|
||||
'format' => [
|
||||
|
||||
'decimals' => 2,
|
||||
|
||||
'decimal_point' => '.',
|
||||
|
||||
'thousand_separator' => ',',
|
||||
|
||||
],
|
||||
|
||||
];
|
|
@ -35,10 +35,11 @@ return [
|
|||
|
||||
'pdf' => [
|
||||
'enabled' => true,
|
||||
'binary' => env('WKHTML_PDF_BINARY', '"C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe"'),
|
||||
'binary' => env('WKHTML_PDF_BINARY', base_path('vendor/h4cc/wkhtmltopdf-amd64/bin/wkhtmltopdf-amd64'),),
|
||||
'timeout' => false,
|
||||
'options' => [
|
||||
'enable-local-file-access' => true
|
||||
'enable-local-file-access' => true,
|
||||
'print-media-type' => true
|
||||
],
|
||||
'env' => [],
|
||||
],
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"Product": true,
|
||||
"Upload": true,
|
||||
"User": true
|
||||
"User": true,
|
||||
"Adjustment": true
|
||||
}
|
|
@ -18781,5 +18781,12 @@ h3 {
|
|||
}
|
||||
|
||||
table {
|
||||
width: 100% !important;
|
||||
width: 990px !important;
|
||||
}
|
||||
|
||||
/* Large devices (desktops, 992px and up) */
|
||||
@media (min-width: 992px) {
|
||||
table {
|
||||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,5 +8,12 @@
|
|||
}
|
||||
|
||||
table {
|
||||
width: 100% !important;
|
||||
width: 990px !important;
|
||||
}
|
||||
|
||||
/* Large devices (desktops, 992px and up) */
|
||||
@media (min-width: 992px) {
|
||||
table {
|
||||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,28 @@
|
|||
</li>
|
||||
@endcan
|
||||
|
||||
@can('access_adjustments')
|
||||
<li class="c-sidebar-nav-item c-sidebar-nav-dropdown {{ request()->routeIs('adjustments.*') ? 'c-show' : '' }}">
|
||||
<a class="c-sidebar-nav-link c-sidebar-nav-dropdown-toggle" href="#">
|
||||
<i class="c-sidebar-nav-icon bi bi-pencil-square" style="line-height: 1;"></i> Adjustments
|
||||
</a>
|
||||
<ul class="c-sidebar-nav-dropdown-items">
|
||||
@can('create_adjustments')
|
||||
<li class="c-sidebar-nav-item">
|
||||
<a class="c-sidebar-nav-link {{ request()->routeIs('adjustments.create') ? 'c-active' : '' }}" href="{{ route('adjustments.create') }}">
|
||||
<i class="c-sidebar-nav-icon bi bi-journal-plus" style="line-height: 1;"></i> Create Adjustment
|
||||
</a>
|
||||
</li>
|
||||
@endcan
|
||||
<li class="c-sidebar-nav-item">
|
||||
<a class="c-sidebar-nav-link {{ request()->routeIs('adjustments.index') ? 'c-active' : '' }}" href="{{ route('adjustments.index') }}">
|
||||
<i class="c-sidebar-nav-icon bi bi-journals" style="line-height: 1;"></i> All Adjustments
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
@endcan
|
||||
|
||||
@can('access_user_management')
|
||||
<li class="c-sidebar-nav-item c-sidebar-nav-dropdown {{ request()->routeIs('roles*') ? 'c-show' : '' }}">
|
||||
<a class="c-sidebar-nav-link c-sidebar-nav-dropdown-toggle" href="#">
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
<div>
|
||||
@if (session()->has('message'))
|
||||
<div class="alert alert-warning alert-dismissible fade show" role="alert">
|
||||
<div class="alert-body">
|
||||
<span>{{ session('message') }}</span>
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
<div class="table-responsive-md">
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr class="align-middle">
|
||||
<th class="align-middle">#</th>
|
||||
<th class="align-middle">Product Name</th>
|
||||
<th class="align-middle">Code</th>
|
||||
<th class="align-middle">Stock</th>
|
||||
<th class="align-middle">Quantity</th>
|
||||
<th class="align-middle">Type</th>
|
||||
<th class="align-middle">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@if(!empty($products))
|
||||
@foreach($products as $key => $product)
|
||||
<tr>
|
||||
<td class="align-middle">{{ $key + 1 }}</td>
|
||||
<td class="align-middle">{{ $product['product_name'] ?? $product['product']['product_name'] }}</td>
|
||||
<td class="align-middle">{{ $product['product_code'] ?? $product['product']['product_code'] }}</td>
|
||||
<td class="align-middle text-center">
|
||||
<span class="badge badge-info">
|
||||
{{ $product['product_quantity'] ?? $product['product']['product_quantity'] }}
|
||||
</span>
|
||||
</td>
|
||||
<input type="hidden" name="product_ids[]" value="{{ $product['product']['id'] ?? $product['id'] }}">
|
||||
<td class="align-middle">
|
||||
<input type="number" name="quantities[]" min="1" class="form-control" value="{{ $product['quantity'] ?? 1 }}">
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
@if(isset($product['type']))
|
||||
@if($product['type'] == 'add')
|
||||
<select name="types[]" class="form-control">
|
||||
<option value="add">(+) Addition</option>
|
||||
</select>
|
||||
@elseif($product['type'] == 'sub')
|
||||
<select name="types[]" class="form-control">
|
||||
<option value="sub">(-) Subtraction</option>
|
||||
</select>
|
||||
@endif
|
||||
@else
|
||||
<select name="types[]" class="form-control">
|
||||
<option value="add">(+) Addition</option>
|
||||
<option value="sub">(-) Subtraction</option>
|
||||
</select>
|
||||
@endif
|
||||
</td>
|
||||
<td class="align-middle text-center">
|
||||
<button type="button" class="btn btn-danger" wire:click="removeProduct({{ $key }})">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
@else
|
||||
<tr>
|
||||
<td colspan="7" class="text-center">
|
||||
<span class="text-danger">
|
||||
Please search & select products!
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
@endif
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
|
@ -48,7 +48,7 @@
|
|||
<div class="card-body">
|
||||
<div class="row justify-content-center">
|
||||
@foreach($barcodes as $barcode)
|
||||
<div class="col-lg-3 col-md-4 col-6" style="border: 1px solid #ffffff;border-style: dashed;background-color: #48FCFE;">
|
||||
<div class="col-lg-3 col-md-4 col-sm-6" style="border: 1px solid #ffffff;border-style: dashed;background-color: #48FCFE;">
|
||||
<p class="mt-3 mb-1" style="font-size: 15px;color: #000;">
|
||||
{{ $product->product_name }}
|
||||
</p>
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
<ul class="list-group list-group-flush">
|
||||
@foreach($searchResults as $result)
|
||||
<li class="list-group-item list-group-item-action">
|
||||
<a wire:click="resetQuery" wire:click.prevent="selectProduct({{$result}})" href="#">
|
||||
<a wire:click="resetQuery" wire:click.prevent="selectProduct({{ $result }})" href="#">
|
||||
{{ $result->product_name }} | {{ $result->product_code }}
|
||||
</a>
|
||||
</li>
|
Loading…
Reference in New Issue