CasperSecurity
<?php
namespace App\Http\Livewire\Projects;
use App\Models\Billing;
use App\Models\Client;
use App\Models\ManageProject;
use App\Models\Organisation;
use App\Models\ProjectInvoiceItem;
use App\Models\SettingsCity;
use App\Models\SettingsCountry;
use App\Models\SettingsState;
use App\Models\TenderVeriety;
use App\Models\WorkOrders;
use App\Models\WorkOrdersBilling;
use Livewire\Component;
use Livewire\WithPagination;
class InvoiceLivewire extends Component
{
use WithPagination;
protected $paginationTheme = 'bootstrap';
public $page_name = "Project Invoice";
public $search;
public $perPage = 10;
public $orderBy = 'id';
public $orderAsc = '1';
public $project_id, $invoice_no, $invoice_date, $invoice_month, $invoice_cycle, $client_id, $total_quantity, $gross_amount, $net_amount, $status;
public $modelId, $project_type_id, $work_order_no, $totalWorkorderItem, $itemCount = 0, $clientGstNo, $itemCountMessage;
public $showmodal = false;
public $billingCycleType = 'MONTHLY', $clients = [], $projectTypes = [], $workOrderItems = [];
public $workOrderItemId = [], $itemQuantity = [], $itemTax = [], $itemRate = [];
public $successmsg = "The project invoice has been saved successfully.";
public $updatemsg = "The project invoice has been updated successfully.";
public $deletemsg = "The project invoice has been deleted successfully.";
public $errormsg = "Sorry !!! Something went wrong. Please Try Again.";
protected $listeners = ['sendMail'];
public function updatingSearch()
{
$this->resetPage();
}
public function showmodalclick()
{
$this->resetValidation();
$this->showmodal = true;
}
public function closemodalclick()
{
$this->resetValidation();
$this->showmodal = false;
}
public function mailClick($id)
{
$this->modelId = $id;
$this->dispatchBrowserEvent('confirmdelete', [
'message' => 'Are you sure want to send mail to client ?',
'funcname' => 'sendMail'
]);
}
public function viewInvoice($id)
{
if(Organisation::find(1)!=null){
$projectBillingInfo = Billing::find($id)->toArray();
$projectDetail = ManageProject::find($projectBillingInfo['project_id'])->toArray();
$clientDetail = Client::find($projectBillingInfo['client_id'])->toArray();
$projectInvoiceItem = ProjectInvoiceItem::where('project_invoice_id', $id)->get()->toArray();
$organisationDetail = Organisation::find(1)->toArray();
$organisationCity = SettingsCity::select('city_name')->find($organisationDetail['registered_city_name']);
$organisationState = SettingsState::select('settings_country_id', 'state_name')->find($organisationDetail['registered_state_name']);
$organisationCountry = SettingsCountry::select('country_name')->find($organisationState->settings_country_id);
$data = [
"organisationDetail" => $organisationDetail,
"clientDetail" => $clientDetail,
"projectDetail" => $projectDetail,
"projectBillingInfo" => $projectBillingInfo,
"projectInvoiceItem" => $projectInvoiceItem,
"amount_inword" => $this->getIndianCurrency($projectBillingInfo['net_amount']),
];
$data['projectBillingInfo']['tcs'] = "0.00";
$data['tax_amount_inword'] = $this->getIndianCurrency($data['projectBillingInfo']['net_amount'] - $data['projectBillingInfo']['gross_amount']);
$data['organisationDetail']['organisationCity'] = $organisationCity->city_name;
$data['organisationDetail']['organisationState'] = $organisationState->state_name;
$data['organisationDetail']['organisationCountry'] = $organisationCountry->country_name;
if (substr($data['clientDetail']['gst_no'], 0, 2) === '21') {
$data['clientDetail']['isOtherState'] = false;
} else {
$data['clientDetail']['isOtherState'] = true;
}
foreach($data['projectInvoiceItem'] as $key=>$item){
$workOrderItem = WorkOrdersBilling::select('item_name')->find($item['work_order_item_id']);
$data['projectInvoiceItem'][$key]['item_name'] = $workOrderItem ? $workOrderItem->item_name : 'N/A';
}
session([
'session_invoiceData' => $data,
]);
$this->dispatchBrowserEvent('newtab_redirect');
}
else{
$this->dispatchBrowserEvent('showsuccessmsg', [
'type' => 'error',
'message' => 'Fill Organisation details first'
]);
}
}
public function getIndianCurrency($number)
{
$decimal = round($number - ($no = floor($number)), 2) * 100;
$hundred = null;
$digits_length = strlen($no);
$i = 0;
$str = array();
$words = array(
0 => '',
1 => 'One',
2 => 'Two',
3 => 'Three',
4 => 'Four',
5 => 'Five',
6 => 'Six',
7 => 'Seven',
8 => 'Eight',
9 => 'Nine',
10 => 'Ten',
11 => 'Eleven',
12 => 'Twelve',
13 => 'Thirteen',
14 => 'Fourteen',
15 => 'Fifteen',
16 => 'Sixteen',
17 => 'Seventeen',
18 => 'Eighteen',
19 => 'Nineteen',
20 => 'Twenty',
30 => 'Thirty',
40 => 'Forty',
50 => 'Fifty',
60 => 'Sixty',
70 => 'Seventy',
80 => 'Eighty',
90 => 'Ninety'
);
$digits = array('', 'Hundred', 'Thousand', 'Lakh', 'Crore');
while ($i < $digits_length) {
$divider = ($i == 2) ? 10 : 100;
$number = floor($no % $divider);
$no = floor($no / $divider);
$i += $divider == 10 ? 1 : 2;
if ($number) {
$plural = (($counter = count($str)) && $number > 9) ? 's' : null;
// $hundred = ($counter == 1 && $str[0]) ? ' and ' : null;
$str[] = ($number < 21) ? $words[$number] . ' ' . $digits[$counter] . $plural . ' ' . $hundred : $words[floor($number / 10) * 10] . ' ' . $words[$number % 10] . ' ' . $digits[$counter] . $plural . ' ' . $hundred;
} else
$str[] = null;
}
$Rupees = implode('', array_reverse($str));
$paise = ($decimal > 0) ? "." . ($words[$decimal / 10] . " " . $words[$decimal % 10]) . ' Paise' : '';
return 'Rupees ' . ($Rupees ? $Rupees . 'Only ' : '') . $paise;
}
public function cleanVar()
{
$this->modelId = null;
$this->project_id = null;
$this->work_order_no = null;
$this->client_id = null;
$this->invoice_no = null;
$this->invoice_date = null;
$this->invoice_month = null;
$this->invoice_cycle = null;
$this->total_quantity = null;
$this->gross_amount = null;
$this->net_amount = null;
$this->workOrderItemId = [];
$this->itemQuantity = [];
$this->itemRate = [];
$this->itemTax = [];
$this->status = null;
$this->showmodal = false;
}
public function setItem($keyVal)
{
foreach ($this->workOrderItems as $item) {
if ($item['id'] == $this->workOrderItemId[$keyVal]) {
$this->itemRate[$keyVal] = $item['item_rate'];
$this->itemTax[$keyVal] = $item['item_tax'];
break;
}
}
}
public function updatedProjectId($val)
{
if ($val != "") {
$clients = ManageProject::select('id', 'client_id', 'project_variety_id', 'work_order_no')->find($val);
$this->client_id = $clients ? $clients->client_id : null;
$clientGst = Client::select('gst_no')->find($this->client_id);
$this->clientGstNo = $clientGst ? $clientGst->gst_no : null;
$this->project_type_id = $clients ? $clients->project_variety_id : null;
$this->work_order_no = $clients ? $clients->work_order_no : null;
if ($this->client_id) {
$billingCycleType = WorkOrders::select('id', 'billing_cycle')->where('client_id', $this->client_id)->latest()->first();
$this->billingCycleType = $billingCycleType ? $billingCycleType->billing_cycle : null;
if ($billingCycleType) {
$this->workOrderItems = WorkOrdersBilling::where('work_order_id', $billingCycleType->id)->get();
$this->totalWorkorderItem = $this->workOrderItems->count();
}
}
} else {
$this->client_id = null;
$this->work_order_no = null;
$this->project_type_id = null;
$this->workOrderItemId = [];
$this->itemQuantity = [];
$this->itemRate = [];
$this->itemTax = [];
}
}
public function updatedInvoiceMonth($val)
{
if ($val && $this->billingCycleType == 'MONTHLY') {
$this->invoice_cycle = $this->invoice_month;
}
}
public function modelData()
{
$createdBy = $modifiedBy = null;
if ($this->modelId) {
$modifiedBy = auth()->id();
} else {
$createdBy = auth()->id();
}
$data = [
'project_id' => $this->project_id,
'invoice_no' => $this->invoiceNo(),
'invoice_date' => $this->invoice_date,
'invoice_month' => $this->invoice_month,
'invoice_cycle' => $this->invoice_cycle,
'client_id' => $this->client_id,
'created_by' => $createdBy,
'modified_by' => $modifiedBy,
'status' => '1',
];
return $data;
}
public function addItem()
{
$prevrules = [];
$prevmessages = [];
for ($i = 0; $i <= $this->itemCount; $i++) {
$prevrules["workOrderItemId.$i"] = 'required';
$prevrules["itemQuantity.$i"] = 'required|numeric';
$prevmessages += [
"workOrderItemId.$i.required" => 'This field is required.',
"itemQuantity.$i.required" => 'This field is required.',
"itemQuantity.$i.numeric" => 'The quantity must be a number.',
];
}
$this->validate($prevrules, $prevmessages);
if ($this->itemCount < $this->totalWorkorderItem - 1) {
$this->itemCount++;
} else {
$this->itemCountMessage = 'You have reached the item limit.';
}
}
public function removeItem($key)
{
unset($this->workOrderItemId[$key], $this->itemQuantity[$key], $this->itemRate[$key], $this->itemTax[$key]);
$this->reorderArray($this->workOrderItemId, $this->itemQuantity, $this->itemRate, $this->itemTax);
$this->itemCount--;
$this->itemCountMessage = null;
}
private function reorderArray(&...$arrays)
{
foreach ($arrays as &$array) {
$array = array_values($array);
}
}
public function validateFields()
{
$rules = [
'project_id' => 'required',
'invoice_date' => 'required|date',
'invoice_month' => 'required',
'invoice_cycle' => 'required',
'client_id' => 'required',
];
$messages = [
'project_id.required' => 'The project is required.',
'invoice_date.required' => 'The invoice date is required.',
'invoice_date.date' => 'The invoice date must be a valid date.',
'invoice_month.required' => 'The invoice month is required.',
'invoice_cycle.required' => 'The invoice cycle is required.',
'client_id.required' => 'The client is required.',
];
if (!empty($this->workOrderItemId)) {
foreach ($this->workOrderItemId as $i => $document) {
$rules["workOrderItemId.$i"] = 'required';
$rules["itemQuantity.$i"] = 'required|numeric';
$rules["itemRate.$i"] = 'required';
$messages["workOrderItemId.$i.required"] = 'This field is mandatory';
$messages["itemQuantity.$i.required"] = 'This field is mandatory';
$messages["itemQuantity.$i.numeric"] = 'This field should be numeric';
$messages["itemRate.$i.required"] = 'This field is mandatory';
}
}
$this->validate($rules, $messages);
}
public function save()
{
$this->validateFields();
if (sizeof($this->workOrderItemId) > 0) {
$response = Billing::create($this->modelData());
$firstTwoChars = substr($this->clientGstNo, 0, 2);
$this->total_quantity = $this->gross_amount = $this->net_amount = 0;
foreach ($this->workOrderItemId as $key => $id) {
$gst_amount = $cgst_percentage = $sgst_percentage = $igst_percentage = $cgst_amount = $sgst_amount = $igst_amount = null;
if ($firstTwoChars === '21') {
$cgst_percentage = $sgst_percentage = $this->itemTax[$key] / 2;
$cgst_amount = $sgst_amount = (($this->itemRate[$key] * $this->itemQuantity[$key]) * (($this->itemTax[$key] / 2) / 100));
$gst_amount = $cgst_amount + $sgst_amount;
} else {
$igst_percentage = $this->itemTax[$key];
$igst_amount = $this->itemRate[$key] * ($this->itemTax[$key] / 100);
$gst_amount = $igst_amount;
}
$taxable_amount = $this->itemRate[$key] * $this->itemQuantity[$key];
$net_amount = $taxable_amount + $gst_amount;
$this->gross_amount += $taxable_amount;
$this->total_quantity += $this->itemQuantity[$key];
$this->net_amount += $net_amount;
$billingItem[] = [
'project_invoice_id' => $response->id,
'work_order_item_id' => $this->workOrderItemId[$key],
'item_rate' => $this->itemRate[$key],
'item_quantity' => $this->itemQuantity[$key],
'taxable_amount' => $taxable_amount,
'cgst_percentage' => $cgst_percentage != null ? $cgst_percentage : 0.00,
'sgst_percentage' => $sgst_percentage != null ? $sgst_percentage : 0.00,
'igst_percentage' => $igst_percentage != null ? $igst_percentage : 0.00,
'cgst_amount' => $cgst_amount != null ? $cgst_amount : 0.00,
'sgst_amount' => $sgst_amount != null ? $sgst_amount : 0.00,
'igst_amount' => $igst_amount != null ? $igst_amount : 0.00,
'gst_amount' => $gst_amount != null ? $gst_amount : 0.00,
'net_amount' => $net_amount,
];
}
//dd($billingItem);
$insertItem = ProjectInvoiceItem::insert($billingItem);
if ($insertItem) {
$response->update([
'total_quantity' => $this->total_quantity,
'gross_amount' => $this->gross_amount,
'net_amount' => $this->net_amount,
]);
if ($response) {
$this->cleanVar();
$this->dispatchBrowserEvent('closeOffCanvas');
$this->dispatchBrowserEvent('showsuccessmsg', [
'type' => 'success',
'message' => $this->successmsg
]);
} else {
$this->dispatchBrowserEvent('showsuccessmsg', [
'type' => 'error',
'message' => $this->errormsg
]);
}
}
} else {
$this->dispatchBrowserEvent('showsuccessmsg', [
'type' => 'error',
'message' => 'Please add atleast one item.'
]);
}
}
public function sendMail()
{
$response = Billing::find($this->modelId);
if ($response) {
$this->cleanVar();
$this->dispatchBrowserEvent('showsuccessmsg', [
'type' => 'error',
'message' => 'Development Pending'
]);
} else {
$this->dispatchBrowserEvent('showsuccessmsg', [
'type' => 'error',
'message' => $this->errormsg
]);
}
}
public function invoiceNo()
{
$lastId = Billing::latest('id')->value('id');
$lastId = $lastId ? $lastId + 1 : 1;
$currentYear = date('Y');
$startYear = date('n') >= 4 ? $currentYear : $currentYear - 1;
$endYear = $startYear + 1;
$financialYear = substr($startYear, -2) . substr($endYear, -2);
$invoiceNo = 'INV/' . $financialYear . '/' . sprintf("%05d", $lastId);
return $invoiceNo;
}
public function read()
{
$projectInvoice = Billing::search($this->search)->orderBy($this->orderBy, $this->orderAsc ? 'asc' : 'desc')->paginate($this->perPage);
return $projectInvoice;
}
public function mount()
{
$this->clients = Client::select('id', 'client_name')->get();
$this->projectTypes = TenderVeriety::select('id', 'variety_name')->where('status', '1')->get();
}
public function render()
{
$billingCycleType = null;
$dataTables = [];
$dataTables = $this->read();
foreach ($dataTables as $key => $data) {
$client = Client::select('client_name')->find($data->client_id);
$dataTables[$key]['client_name'] = $client ? $client->client_name : 'N/A';
$project = ManageProject::select('project_name')->find($data->project_id);
$dataTables[$key]['project_name'] = $project ? $project->project_name : 'N/A';
}
$projects = ManageProject::select('id', 'project_name')->get();
return view('livewire.projects.invoice-livewire', compact('dataTables', 'projects'));
}
}