Compare commits

...

2 Commits

Author SHA1 Message Date
4a396e6f98 Merge branch 'omis_dharma' of ssh://bibgit.com:22022/dharmaraj/New-OMIS 2024-04-16 10:57:27 +05:45
442822e472 taxation module 2024-04-16 10:54:23 +05:45
15 changed files with 433 additions and 46 deletions

View File

@ -10,7 +10,7 @@ class Employee extends Model
protected $table = 'tbl_employees';
protected $primaryKey = 'id';
protected $guarded = [];
protected $appends = (['full_name']);
protected $appends = ['full_name'];
protected function getFullNameAttribute()
{

View File

@ -2,6 +2,7 @@
namespace Modules\Employee\Repositories;
use Illuminate\Support\Facades\DB;
use Modules\Employee\Models\Employee;
class EmployeeRepository implements EmployeeInterface
@ -38,7 +39,7 @@ class EmployeeRepository implements EmployeeInterface
public function pluck()
{
return Employee::pluck('first_name', 'id');
return Employee::pluck(DB::raw('CONCAT(first_name," ", middle_name , " ",last_name) AS full_name'), 'id');
}
// public function uploadImage($file)

View File

@ -0,0 +1,91 @@
<?php
namespace Modules\Taxation\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Models\Companies;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Modules\Employee\Repositories\EmployeeInterface;
class InvoiceController extends Controller
{
private $employeeRepository;
public function __construct(EmployeeInterface $employeeRepository)
{
$this->employeeRepository = $employeeRepository;
}
/**
* Display a listing of the resource.
*/
public function index()
{
$data['title'] = 'Invoice List';
$data['invoices'] = [];
return view('taxation::invoice.index', $data);
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
$data['title'] = 'Create Invoice';
$data['companyList'] = Companies::pluck('title', 'company_id');
$data['employeeList'] = $this->employeeRepository->pluck();
return view('taxation::invoice.create', $data);
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request): RedirectResponse
{
//
}
/**
* Show the specified resource.
*/
public function show($id)
{
return view('taxation::invoice.show');
}
/**
* Show the form for editing the specified resource.
*/
public function edit($id)
{
return view('taxation::invoice.edit');
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, $id): RedirectResponse
{
//
}
/**
* Remove the specified resource from storage.
*/
public function destroy($id)
{
//
}
public function cloneProduct(Request $request)
{
$data = [];
$numInc = $request->numberInc;
$script = true;
return response()->json([
'view' => view('taxation::invoice.clone-product', compact('data', 'numInc', 'script'))->render(),
]);
}
}

View File

@ -0,0 +1,39 @@
<div class="card card-body product-card card-border-secondary mb-2 border">
<div class="row gy-2 mb-2">
<div class="col-md-4">
{{ html()->label('Product')->class('form-label') }}
{{ html()->text('product_id')->class('form-control')->placeholder('Enter Product Name')->required() }}
</div>
<div class="col-md-2">
{{ html()->label('Unit')->class('form-label') }}
{{ html()->text('unit')->class('form-control')->placeholder('Enter Unit')->required() }}
</div>
<div class="col-md-2">
{{ html()->label('Rate')->class('form-label') }}
{{ html()->text('rate')->class('form-control product-price cleave-numeral')->placeholder('Enter Rate')->attributes(['id' => 'cleave-numeral']) }}
</div>
<div class="col-md-2">
{{ html()->label('Quantity')->class('form-label') }}
{{ html()->text('qty')->class('form-control product-quantity cleave-numeral')->placeholder('Enter QTY')->attributes(['id' => 'cleave-numeral']) }}
</div>
<div class="col-md-2">
{{ html()->label('Amount')->class('form-label') }}
{{ html()->text('amt')->class('form-control product-line-price bg-light')->placeholder('Enter Amount')->isReadOnly() }}
</div>
<div class="col-md-6">
{{ html()->label('Description')->class('form-label') }}
{{ html()->text('desc')->class('form-control')->placeholder('Enter Description') }}
</div>
<div class="col-md-6 d-flex justify-content-end align-items-end">
<button type="button" class="btn btn-danger btn-icon waves-effect btn-remove waves-light"><i
class="ri-delete-bin-5-line"></i></button>
</div>
</div>
</div>

View File

@ -6,19 +6,16 @@
<!-- start page title -->
@include('layouts.partials.breadcrumb', ['title' => $title])
<!-- end page title -->
<div class="row">
<div class="col-lg-8">
<div class="card">
<div class="card-body">
<form action="{{ route('leaveType.store') }}" class="needs-validation" novalidate method="post">
@csrf
@include('leave::leave.partials.action')
</form>
</div>
</div>
<div class="card">
<div class="card-body">
<form action="{{ route('invoice.store') }}" class="needs-validation" novalidate method="post">
@csrf
@include('taxation::invoice.partials.action')
</form>
</div>
</div>
<!--end row-->
</div>
<!-- container-fluid -->

View File

@ -9,9 +9,9 @@
<div class="col-lg-12">
<div class="card">
<div class="card-header align-items-center d-flex">
<h5 class="card-title flex-grow-1 mb-0">Leave Lists</h5>
<h5 class="card-title flex-grow-1 mb-0">{{ $title }}</h5>
<div class="flex-shrink-0">
<a href="{{ route('leaveType.create') }}" class="btn btn-success waves-effect waves-light"><i
<a href="{{ route('invoice.create') }}" class="btn btn-success waves-effect waves-light"><i
class="ri-add-fill me-1 align-bottom"></i> Add</a>
</div>
</div>
@ -22,14 +22,14 @@
<thead>
<tr>
<th>S.N</th>
<th>Leave Type</th>
<th>Id</th>
<th>Created By</th>
<th>Status</th>
<th>Action</th>
</tr>
</thead>
<tbody>
@forelse ($leaveTypes as $key => $leaveType)
@forelse ($invoices as $key => $leaveType)
<tr>
<td>{{ $key + 1 }}</td>
<td>{{ $leaveType->employee_id }}</td>

View File

@ -0,0 +1,207 @@
<div class="row gy-1">
<h5 class="text-primary text-center">Invoice Details</h5>
<div class="border border-dashed"></div>
<div class="col-md-4">
{{ html()->label('Company')->class('form-label') }}
{{ html()->select('company_id', $companyList)->class('form-control')->placeholder('Select Company')->required() }}
{{ html()->div('Please select company')->class('invalid-feedback') }}
</div>
<div class="col-md-4">
{{ html()->label('Invoice No.')->class('form-label') }}
{{ html()->text('invoice_no')->class('form-control')->placeholder('Enter Invoice No')->attributes(['id' => 'cleave-prefix']) }}
</div>
<div class="col-md-4">
{{ html()->label('VAT No.')->class('form-label') }}
{{ html()->text('vat_no')->class('form-control')->placeholder('Enter VAT No') }}
</div>
<div class="col-md-4">
{{ html()->label('Sales Date')->class('form-label') }}
{{ html()->date('sale_date')->class('form-control')->placeholder('Choose Sales Date')->required() }}
{{ html()->div('Please choose invoice date')->class('invalid-feedback') }}
</div>
<div class="col-md-4">
{{ html()->label('Bill Issue Date')->class('form-label') }}
{{ html()->date('isse_date')->class('form-control')->placeholder('Choose Bill Issue Date')->required() }}
{{ html()->div('Please choose invoice date')->class('invalid-feedback') }}
</div>
</div>
<div class="row gy-1 my-2">
<h5 class="text-primary text-center">Buyer Details</h5>
<div class="border border-dashed"></div>
<div class="col-md-4">
{{ html()->label('Buyer')->class('form-label') }}
{{ html()->select('buyer_id', $employeeList)->class('form-control')->placeholder('Select Buyer') }}
</div>
<div class="col-md-4">
{{ html()->label('Address No.')->class('form-label') }}
{{ html()->text('buyer_address')->class('form-control')->placeholder('Enter Address') }}
</div>
<div class="col-md-4">
{{ html()->label('VAT No.')->class('form-label') }}
{{ html()->text('vat_no')->class('form-control')->placeholder('Enter Buyer VAT No') }}
</div>
<div class="col-md-4">
{{ html()->label('Contact No')->class('form-label') }}
{{ html()->date('sale_date')->class('form-control')->placeholder('Enter Contact No') }}
</div>
<div class="col-md-4">
{{ html()->label('Mode of Payment')->class('form-label') }}
{{ html()->select('buyer_id', [1 => 'Cash', 2 => 'Bank', 3 => 'Credit'])->class('form-control')->placeholder('Select Payment Mode') }}
</div>
</div>
{{-- <div class="row mt-2">
<p class="text-primary">Shipping Details</p>
<div class="border border-dashed"></div>
<div class="col-md-4">
{{ html()->label('Address')->class('form-label') }}
{{ html()->text('address')->class('form-control')->placeholder('Enter Address') }}
</div>
<div class="col-md-4">
{{ html()->label('Shipping Date')->class('form-label') }}
{{ html()->date('shiiping_date')->class('form-control')->placeholder('Enter Temporary Address') }}
</div>
</div> --}}
<div class="row gy-1 gx-2 mt-1">
<div class="d-flex justify-content-end">
<button type="button" class="btn btn-info btn-icon add-btn text-end"><i class="ri-add-line"></i></button>
</div>
@include('taxation::invoice.clone-product')
<div class="appendProductCard"></div>
</div>
<div class="d-flex justify-content-end w-30 mb-2">
<table class="table-borderless align-middle">
<tbody>
<tr>
<th scope="row">Sub Total</th>
<td style="width:150px;">
<input type="text" class="form-control bg-light border-0" id="subtotal" placeholder="$0.00"
readonly="">
</td>
</tr>
<tr>
<th scope="row">Estimated Tax (11%)</th>
<td>
<input type="text" class="form-control bg-light border-0" id="tax" placeholder="$0.00"
readonly="">
</td>
</tr>
<tr>
<th scope="row">Discount</th>
<td>
<input type="text" class="form-control bg-light border-0" id="discount" placeholder="$0.00"
readonly="">
</td>
</tr>
<tr class="border-top border-top-dashed">
<th scope="row">Total Amount</th>
<td>
<input type="text" class="form-control bg-light border-0" id="total" placeholder="$0.00"
readonly="">
</td>
</tr>
</tbody>
</table>
</div>
<div class="mb-4 text-end">
<button type="submit" class="btn btn-success w-sm">Save</button>
</div>
@push('js')
<script src="{{ asset('assets/libs/cleave.js/cleave.min.js') }}"></script>
<script src="{{ asset('assets/js/pages/form-masks.init.js') }}"></script>
<script>
$("body").on('click', '.add-btn', function(e) {
e.preventDefault();
numberInc = $('.product-card').length
$.ajax({
type: 'get',
url: '{{ route('cloneProduct') }}',
data: {
numberInc: numberInc
},
success: function(response) {
$('.appendProductCard').append(response.view)
// $('#invoice-container').html(response.view).fadeIn()
},
error: function(xhr) {
},
});
});
$("body").on('click', '.btn-remove', function() {
if ($('.product-card').length > 1) {
$(this).parents(".product-card").remove();
}
recalculate();
});
function amountKeyup() {
$("body").on('keyup', '.product-price', function() {
var priceInput = $(this);
var qtyInput = priceInput.closest(".row").find(".product-quantity");
var linePrice = priceInput.closest(".row").find(".product-line-price");
updateQuantity(priceInput.val(), qtyInput.val(), linePrice);
});
$("body").on('keyup', '.product-quantity', function() {
var priceInput = $(this);
var qtyInput = priceInput.closest(".row").find(".product-price");
var linePrice = priceInput.closest(".row").find(".product-line-price");
updateQuantity(priceInput.val(), qtyInput.val(), linePrice);
});
}
amountKeyup()
function updateQuantity(rate, qty, linePriceInput) {
var amount = (rate * qty).toFixed(2);
linePriceInput.val(amount);
recalculate();
}
function recalculate() {
var subtotal = 0;
$(".product-line-price").each(function() {
if ($(this).val()) {
subtotal += parseFloat($(this).val());
}
});
var tax = subtotal * 0.125;
var discount = subtotal * 0.15;
var shipping = subtotal > 0 ? 65 : 0;
var total = subtotal + tax + shipping - discount;
$("#subtotal").val(subtotal.toFixed(2));
$("#tax").val(tax.toFixed(2));
$("#discount").val(discount.toFixed(2));
$("#shipping").val(shipping.toFixed(2));
$("#total").val(total.toFixed(2));
// $("#totalamountInput").val(total.toFixed(2));
// $("#amountTotalPay").val(total.toFixed(2));
}
</script>
@endpush

View File

@ -1,25 +0,0 @@
<div class="mb-3">
<label for="employee_id" class="form-label">Employee Name</label>
{{ html()->select('employee_id', $employeeList)->class('form-select')->placeholder('Select Employee') }}
</div>
<div class="mb-3">
<label for="start_date" class="form-label">Start Leave Date</label>
<input type="date" class="form-control" id="start_date" name="start_date"
value="{{ old('start_date', $leave->start_date ?? '') }}">
</div>
<div class="mb-3">
<label for="end_date" class="form-label">End Leave Date</label>
<input type="date" class="form-control" id="end_date" name="end_date"
value="{{ old('end_date', $leave->end_date ?? '') }}">
</div>
<div class="text-end">
<button type="submit" class="btn btn-primary">{{ isset($leave) ? 'Update' : 'Add Leave' }}</button>
</div>
@push('js')
<script src="{{ asset('assets/js/pages/form-validation.init.js') }}"></script>
@endpush

View File

@ -1,6 +1,7 @@
<?php
use Illuminate\Support\Facades\Route;
use Modules\Taxation\Http\Controllers\InvoiceController;
use Modules\Taxation\Http\Controllers\TaxationController;
/*
@ -12,8 +13,11 @@ use Modules\Taxation\Http\Controllers\TaxationController;
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
*/
Route::group([], function () {
Route::resource('taxation', TaxationController::class)->names('taxation');
Route::resource('invoice', InvoiceController::class)->names('invoice');
Route::get('clone-product', [InvoiceController::class, 'cloneProduct'])->name('cloneProduct');
});

View File

@ -1 +1,74 @@
var cleaveDate,cleaveDateFormat,cleaveTime,cleaveTimeFormat,cleaveNumeral,cleaveDelimiter,cleaveDelimiters,cleavePrefix,cleaveBlocks;document.querySelector("#cleave-date")&&(cleaveDate=new Cleave("#cleave-date",{date:!0,delimiter:"-",datePattern:["d","m","Y"]})),document.querySelector("#cleave-date-format")&&(cleaveDateFormat=new Cleave("#cleave-date-format",{date:!0,datePattern:["m","y"]})),document.querySelector("#cleave-time")&&(cleaveTime=new Cleave("#cleave-time",{time:!0,timePattern:["h","m","s"]})),document.querySelector("#cleave-time-format")&&(cleaveTimeFormat=new Cleave("#cleave-time-format",{time:!0,timePattern:["h","m"]})),document.querySelector("#cleave-numeral")&&(cleaveNumeral=new Cleave("#cleave-numeral",{numeral:!0,numeralThousandsGroupStyle:"thousand"})),document.querySelector("#cleave-ccard")&&(cleaveBlocks=new Cleave("#cleave-ccard",{blocks:[4,4,4,4],uppercase:!0})),document.querySelector("#cleave-delimiter")&&(cleaveDelimiter=new Cleave("#cleave-delimiter",{delimiter:"·",blocks:[3,3,3],uppercase:!0})),document.querySelector("#cleave-delimiters")&&(cleaveDelimiters=new Cleave("#cleave-delimiters",{delimiters:[".",".","-"],blocks:[3,3,3,2],uppercase:!0})),document.querySelector("#cleave-prefix")&&(cleavePrefix=new Cleave("#cleave-prefix",{prefix:"PREFIX",delimiter:"-",blocks:[6,4,4,4],uppercase:!0})),document.querySelector("#cleave-phone")&&(cleaveBlocks=new Cleave("#cleave-phone",{delimiters:["(",")","-"],blocks:[0,3,3,4]}));
var cleaveDate,
cleaveDateFormat,
cleaveTime,
cleaveTimeFormat,
cleaveNumeral,
cleaveDelimiter,
cleaveDelimiters,
cleavePrefix,
cleaveBlocks;
document.querySelector("#cleave-date") &&
(cleaveDate = new Cleave("#cleave-date", {
date: !0,
delimiter: "-",
datePattern: ["d", "m", "Y"],
})),
document.querySelector("#cleave-date-format") &&
(cleaveDateFormat = new Cleave("#cleave-date-format", {
date: !0,
datePattern: ["m", "y"],
})),
document.querySelector("#cleave-time") &&
(cleaveTime = new Cleave("#cleave-time", {
time: !0,
timePattern: ["h", "m", "s"],
})),
document.querySelector("#cleave-time-format") &&
(cleaveTimeFormat = new Cleave("#cleave-time-format", {
time: !0,
timePattern: ["h", "m"],
})),
document.querySelectorAll(".cleave-numeral").forEach(function (element) {
new Cleave(element, {
numeral: !0,
numeralThousandsGroupStyle: "thousand",
});
});
// document.querySelector("cleave-numeral") &&
// (cleaveNumeral = new Cleave(".cleave-numeral", {
// numeral: !0,
// numeralThousandsGroupStyle: "thousand",
// })),
document.querySelector("#cleave-ccard") &&
(cleaveBlocks = new Cleave("#cleave-ccard", {
blocks: [4, 4, 4, 4],
uppercase: !0,
})),
document.querySelector("#cleave-delimiter") &&
(cleaveDelimiter = new Cleave("#cleave-delimiter", {
delimiter: "·",
blocks: [3, 3, 3],
uppercase: !0,
})),
document.querySelector("#cleave-delimiters") &&
(cleaveDelimiters = new Cleave("#cleave-delimiters", {
delimiters: [".", ".", "-"],
blocks: [3, 3, 3, 2],
uppercase: !0,
})),
document.querySelector("#cleave-prefix") &&
(cleavePrefix = new Cleave("#cleave-prefix", {
prefix: "INV",
delimiter: "-",
blocks: [3, 4, 4, 4],
uppercase: !0,
})),
document.querySelector("#cleave-phone") &&
(cleaveBlocks = new Cleave("#cleave-phone", {
delimiters: ["(", ")", "-"],
blocks: [0, 3, 3, 4],
}));

View File

@ -124,7 +124,7 @@
<li class="nav-item">
<a href="{{ route('user.index') }}"
class="nav-link @if (\Request::is('user') || \Request::is('user/*')) active @endif">Users</a>
class="nav-link @if (\Request::is('user') || \Request::is('user/*')) active @endif">Create Invoice</a>
</li>
</ul>
</div>

View File

@ -19,7 +19,7 @@ Route::get('/', function () {
return view('welcome');
});
Route::get('/invoice', function () {
Route::get('/invoice-test', function () {
return view('invoice');
});