![]() Server : Apache/2.4.62 (Unix) OpenSSL/1.0.2k-fips System : Linux server1.richineiserver.com 3.10.0-1160.119.1.el7.x86_64 #1 SMP Tue Jun 4 14:43:51 UTC 2024 x86_64 User : fdshops ( 1003) PHP Version : 8.2.21 Disable Function : NONE Directory : /home/fdshops/public_html/app/Http/Controllers/ |
<?php namespace App\Http\Controllers; use App\Brands; use App\BusinessLocation; use App\CashRegister; use App\Category; use App\Charts\CommonChart; use App\Contact; use App\CustomerGroup; use App\ExpenseCategory; use App\Product; use App\PurchaseLine; use App\Restaurant\ResTable; use App\SellingPriceGroup; use App\TaxRate; use App\Transaction; use App\TransactionPayment; use App\TransactionSellLine; use App\TransactionSellLinesPurchaseLines; use App\Unit; use App\User; use App\Utils\BusinessUtil; use App\Utils\ModuleUtil; use App\Utils\ProductUtil; use App\Utils\TransactionUtil; use App\Variation; use Datatables; use DB; use Illuminate\Http\Request; use Spatie\Activitylog\Models\Activity; class ReportController extends Controller { /** * All Utils instance. */ protected $transactionUtil; protected $productUtil; protected $moduleUtil; protected $businessUtil; /** * Create a new controller instance. * * @return void */ public function __construct(TransactionUtil $transactionUtil, ProductUtil $productUtil, ModuleUtil $moduleUtil, BusinessUtil $businessUtil) { $this->transactionUtil = $transactionUtil; $this->productUtil = $productUtil; $this->moduleUtil = $moduleUtil; $this->businessUtil = $businessUtil; } public function getStockBySellingPrice(Request $request) { $business_id = $request->session()->get('user.business_id'); $start_date = $request->get('start_date'); $end_date = $request->get('end_date'); $location_id = $request->get('location_id'); $day_before_start_date = \Carbon::createFromFormat('Y-m-d', $start_date)->subDay()->format('Y-m-d'); $permitted_locations = auth()->user()->permitted_locations(); $opening_stock_by_sp = $this->transactionUtil->getOpeningClosingStock($business_id, $day_before_start_date, $location_id, true, true, $permitted_locations); $closing_stock_by_sp = $this->transactionUtil->getOpeningClosingStock($business_id, $end_date, $location_id, false, true, $permitted_locations); return [ 'opening_stock_by_sp' => $opening_stock_by_sp, 'closing_stock_by_sp' => $closing_stock_by_sp, ]; } /** * Shows profit\loss of a business * * @return \Illuminate\Http\Response */ public function getProfitLoss(Request $request) { if (! auth()->user()->can('profit_loss_report.view')) { abort(403, 'Unauthorized action.'); } $business_id = $request->session()->get('user.business_id'); //Return the details in ajax call if ($request->ajax()) { $start_date = $request->get('start_date'); $end_date = $request->get('end_date'); $location_id = $request->get('location_id'); $fy = $this->businessUtil->getCurrentFinancialYear($business_id); $location_id = ! empty(request()->input('location_id')) ? request()->input('location_id') : null; $start_date = ! empty(request()->input('start_date')) ? request()->input('start_date') : $fy['start']; $end_date = ! empty(request()->input('end_date')) ? request()->input('end_date') : $fy['end']; $user_id = request()->input('user_id') ?? null; $permitted_locations = auth()->user()->permitted_locations(); $data = $this->transactionUtil->getProfitLossDetails($business_id, $location_id, $start_date, $end_date, $user_id, $permitted_locations); // $data['closing_stock'] = $data['closing_stock'] - $data['total_sell_return']; return view('report.partials.profit_loss_details', compact('data'))->render(); } $business_locations = BusinessLocation::forDropdown($business_id, true); return view('report.profit_loss', compact('business_locations')); } /** * Shows product report of a business * * @return \Illuminate\Http\Response */ public function getPurchaseSell(Request $request) { if (! auth()->user()->can('purchase_n_sell_report.view')) { abort(403, 'Unauthorized action.'); } $business_id = $request->session()->get('user.business_id'); //Return the details in ajax call if ($request->ajax()) { $start_date = $request->get('start_date'); $end_date = $request->get('end_date'); $location_id = $request->get('location_id'); $purchase_details = $this->transactionUtil->getPurchaseTotals($business_id, $start_date, $end_date, $location_id); $sell_details = $this->transactionUtil->getSellTotals( $business_id, $start_date, $end_date, $location_id ); $transaction_types = [ 'purchase_return', 'sell_return', ]; $transaction_totals = $this->transactionUtil->getTransactionTotals( $business_id, $transaction_types, $start_date, $end_date, $location_id ); $total_purchase_return_inc_tax = $transaction_totals['total_purchase_return_inc_tax']; $total_sell_return_inc_tax = $transaction_totals['total_sell_return_inc_tax']; $difference = [ 'total' => $sell_details['total_sell_inc_tax'] - $total_sell_return_inc_tax - ($purchase_details['total_purchase_inc_tax'] - $total_purchase_return_inc_tax), 'due' => $sell_details['invoice_due'] - $purchase_details['purchase_due'], ]; return ['purchase' => $purchase_details, 'sell' => $sell_details, 'total_purchase_return' => $total_purchase_return_inc_tax, 'total_sell_return' => $total_sell_return_inc_tax, 'difference' => $difference, ]; } $business_locations = BusinessLocation::forDropdown($business_id, true); return view('report.purchase_sell') ->with(compact('business_locations')); } /** * Shows report for Supplier * * @return \Illuminate\Http\Response */ public function getCustomerSuppliers(Request $request) { if (! auth()->user()->can('contacts_report.view')) { abort(403, 'Unauthorized action.'); } $business_id = $request->session()->get('user.business_id'); //Return the details in ajax call if ($request->ajax()) { $contacts = Contact::where('contacts.business_id', $business_id) ->join('transactions AS t', 'contacts.id', '=', 't.contact_id') ->active() ->groupBy('contacts.id') ->select( DB::raw("SUM(IF(t.type = 'purchase', final_total, 0)) as total_purchase"), DB::raw("SUM(IF(t.type = 'purchase_return', final_total, 0)) as total_purchase_return"), DB::raw("SUM(IF(t.type = 'sell' AND t.status = 'final', final_total, 0)) as total_invoice"), DB::raw("SUM(IF(t.type = 'purchase', (SELECT SUM(amount) FROM transaction_payments WHERE transaction_payments.transaction_id=t.id), 0)) as purchase_paid"), DB::raw("SUM(IF(t.type = 'sell' AND t.status = 'final', (SELECT SUM(IF(is_return = 1,-1*amount,amount)) FROM transaction_payments WHERE transaction_payments.transaction_id=t.id), 0)) as invoice_received"), DB::raw("SUM(IF(t.type = 'sell_return', (SELECT SUM(amount) FROM transaction_payments WHERE transaction_payments.transaction_id=t.id), 0)) as sell_return_paid"), DB::raw("SUM(IF(t.type = 'purchase_return', (SELECT SUM(amount) FROM transaction_payments WHERE transaction_payments.transaction_id=t.id), 0)) as purchase_return_received"), DB::raw("SUM(IF(t.type = 'sell_return', final_total, 0)) as total_sell_return"), DB::raw("SUM(IF(t.type = 'opening_balance', final_total, 0)) as opening_balance"), DB::raw("SUM(IF(t.type = 'opening_balance', (SELECT SUM(IF(is_return = 1,-1*amount,amount)) FROM transaction_payments WHERE transaction_payments.transaction_id=t.id), 0)) as opening_balance_paid"), DB::raw("SUM(IF(t.type = 'ledger_discount' AND sub_type='sell_discount', final_total, 0)) as total_ledger_discount_sell"), DB::raw("SUM(IF(t.type = 'ledger_discount' AND sub_type='purchase_discount', final_total, 0)) as total_ledger_discount_purchase"), 'contacts.supplier_business_name', 'contacts.name', 'contacts.id', 'contacts.type as contact_type' ); $permitted_locations = auth()->user()->permitted_locations(); if ($permitted_locations != 'all') { $contacts->whereIn('t.location_id', $permitted_locations); } if (! empty($request->input('customer_group_id'))) { $contacts->where('contacts.customer_group_id', $request->input('customer_group_id')); } if (! empty($request->input('location_id'))) { $contacts->where('t.location_id', $request->input('location_id')); } if (! empty($request->input('contact_id'))) { $contacts->where('t.contact_id', $request->input('contact_id')); } if (! empty($request->input('contact_type'))) { $contacts->whereIn('contacts.type', [$request->input('contact_type'), 'both']); } $start_date = $request->get('start_date'); $end_date = $request->get('end_date'); if (! empty($start_date) && ! empty($end_date)) { $contacts->where('t.transaction_date', '>=', $start_date) ->where('t.transaction_date', '<=', $end_date); } return Datatables::of($contacts) ->editColumn('name', function ($row) { $name = $row->name; if (! empty($row->supplier_business_name)) { $name .= ', '.$row->supplier_business_name; } return '<a href="'.action([\App\Http\Controllers\ContactController::class, 'show'], [$row->id]).'" target="_blank" class="no-print">'. $name. '</a>'; }) ->editColumn( 'total_purchase', '<span class="total_purchase" data-orig-value="{{$total_purchase}}">@format_currency($total_purchase)</span>' ) ->editColumn( 'total_purchase_return', '<span class="total_purchase_return" data-orig-value="{{$total_purchase_return}}">@format_currency($total_purchase_return)</span>' ) ->editColumn( 'total_sell_return', '<span class="total_sell_return" data-orig-value="{{$total_sell_return}}">@format_currency($total_sell_return)</span>' ) ->editColumn( 'total_invoice', '<span class="total_invoice" data-orig-value="{{$total_invoice}}">@format_currency($total_invoice)</span>' ) ->addColumn('due', function ($row) { $total_ledger_discount_purchase = $row->total_ledger_discount_purchase ?? 0; $total_ledger_discount_sell = $total_ledger_discount_sell ?? 0; $due = ($row->total_invoice - $row->invoice_received - $total_ledger_discount_sell) - ($row->total_purchase - $row->purchase_paid - $total_ledger_discount_purchase) - ($row->total_sell_return - $row->sell_return_paid) + ($row->total_purchase_return - $row->purchase_return_received); if ($row->contact_type == 'supplier') { $due -= $row->opening_balance - $row->opening_balance_paid; } else { $due += $row->opening_balance - $row->opening_balance_paid; } $due_formatted = $this->transactionUtil->num_f($due, true); return '<span class="total_due" data-orig-value="'.$due.'">'.$due_formatted.'</span>'; }) ->addColumn( 'opening_balance_due', '<span class="opening_balance_due" data-orig-value="{{$opening_balance - $opening_balance_paid}}">@format_currency($opening_balance - $opening_balance_paid)</span>' ) ->removeColumn('supplier_business_name') ->removeColumn('invoice_received') ->removeColumn('purchase_paid') ->removeColumn('id') ->filterColumn('name', function ($query, $keyword) { $query->where(function ($q) use ($keyword) { $q->where('contacts.name', 'like', "%{$keyword}%") ->orWhere('contacts.supplier_business_name', 'like', "%{$keyword}%"); }); }) ->rawColumns(['total_purchase', 'total_invoice', 'due', 'name', 'total_purchase_return', 'total_sell_return', 'opening_balance_due']) ->make(true); } $customer_group = CustomerGroup::forDropdown($business_id, false, true); $types = [ '' => __('lang_v1.all'), 'customer' => __('report.customer'), 'supplier' => __('report.supplier'), ]; $business_locations = BusinessLocation::forDropdown($business_id, true); $contact_dropdown = Contact::contactDropdown($business_id, false, false); return view('report.contact') ->with(compact('customer_group', 'types', 'business_locations', 'contact_dropdown')); } /** * Shows product stock report * * @return \Illuminate\Http\Response */ public function getStockReport(Request $request) { if (! auth()->user()->can('stock_report.view')) { abort(403, 'Unauthorized action.'); } $business_id = $request->session()->get('user.business_id'); $selling_price_groups = SellingPriceGroup::where('business_id', $business_id) ->get(); $allowed_selling_price_group = false; foreach ($selling_price_groups as $selling_price_group) { if (auth()->user()->can('selling_price_group.'.$selling_price_group->id)) { $allowed_selling_price_group = true; break; } } if ($this->moduleUtil->isModuleInstalled('Manufacturing') && (auth()->user()->can('superadmin') || $this->moduleUtil->hasThePermissionInSubscription($business_id, 'manufacturing_module'))) { $show_manufacturing_data = 1; } else { $show_manufacturing_data = 0; } if ($request->ajax()) { $filters = request()->only(['location_id', 'category_id', 'sub_category_id', 'brand_id', 'unit_id', 'tax_id', 'type', 'only_mfg_products', 'active_state', 'not_for_selling', 'repair_model_id', 'product_id', 'active_state', ]); $filters['not_for_selling'] = isset($filters['not_for_selling']) && $filters['not_for_selling'] == 'true' ? 1 : 0; $filters['show_manufacturing_data'] = $show_manufacturing_data; //Return the details in ajax call $for = request()->input('for') == 'view_product' ? 'view_product' : 'datatables'; $products = $this->productUtil->getProductStockDetails($business_id, $filters, $for); //To show stock details on view product modal if ($for == 'view_product' && ! empty(request()->input('product_id'))) { $product_stock_details = $products; return view('product.partials.product_stock_details')->with(compact('product_stock_details')); } $datatable = Datatables::of($products) ->editColumn('stock', function ($row) { if ($row->enable_stock) { $stock = $row->stock ? $row->stock : 0; return '<span class="current_stock" data-orig-value="'.(float) $stock.'" data-unit="'.$row->unit.'"> '.$this->transactionUtil->num_f($stock, false, null, true).'</span>'.' '.$row->unit; } else { return '--'; } }) ->editColumn('product', function ($row) { $name = $row->product; return $name; }) ->addColumn('action', function ($row) { return '<a class="tw-dw-btn tw-dw-btn-xs tw-dw-btn-outline tw-dw-btn-info tw-w-max " href="'.action([\App\Http\Controllers\ProductController::class, 'productStockHistory'], [$row->product_id]). '?location_id='.$row->location_id.'&variation_id='.$row->variation_id. '"><i class="fas fa-history"></i> '.__('lang_v1.product_stock_history').'</a>'; }) ->addColumn('variation', function ($row) { $variation = ''; if ($row->type == 'variable') { $variation .= $row->product_variation.'-'.$row->variation_name; } return $variation; }) ->editColumn('total_sold', function ($row) { $total_sold = 0; if ($row->total_sold) { $total_sold = (float) $row->total_sold; } return '<span data-is_quantity="true" class="total_sold" data-orig-value="'.$total_sold.'" data-unit="'.$row->unit.'" >'.$this->transactionUtil->num_f($total_sold, false, null, true).'</span> '.$row->unit; }) ->editColumn('total_transfered', function ($row) { $total_transfered = 0; if ($row->total_transfered) { $total_transfered = (float) $row->total_transfered; } return '<span class="total_transfered" data-orig-value="'.$total_transfered.'" data-unit="'.$row->unit.'" >'.$this->transactionUtil->num_f($total_transfered, false, null, true).'</span> '.$row->unit; }) ->editColumn('total_adjusted', function ($row) { $total_adjusted = 0; if ($row->total_adjusted) { $total_adjusted = (float) $row->total_adjusted; } return '<span class="total_adjusted" data-orig-value="'.$total_adjusted.'" data-unit="'.$row->unit.'" >'.$this->transactionUtil->num_f($total_adjusted, false, null, true).'</span> '.$row->unit; }) ->editColumn('unit_price', function ($row) use ($allowed_selling_price_group) { $html = ''; if (auth()->user()->can('access_default_selling_price')) { $html .= $this->transactionUtil->num_f($row->unit_price, true); } if ($allowed_selling_price_group) { $html .= ' <button type="button" class="tw-dw-btn tw-dw-btn-xs tw-dw-btn-outline tw-dw-btn-primary tw-w-max btn-modal no-print" data-container=".view_modal" data-href="'.action([\App\Http\Controllers\ProductController::class, 'viewGroupPrice'], [$row->product_id]).'">'.__('lang_v1.view_group_prices').'</button>'; } return $html; }) ->editColumn('stock_price', function ($row) { $html = '<span class="total_stock_price" data-orig-value="' .$row->stock_price.'">'. $this->transactionUtil->num_f($row->stock_price, true).'</span>'; return $html; }) ->editColumn('stock_value_by_sale_price', function ($row) { $stock = $row->stock ? $row->stock : 0; $unit_selling_price = (float) $row->group_price > 0 ? $row->group_price : $row->unit_price; $stock_price = $stock * $unit_selling_price; return '<span class="stock_value_by_sale_price" data-orig-value="'.(float) $stock_price.'" > '.$this->transactionUtil->num_f($stock_price, true).'</span>'; }) ->addColumn('potential_profit', function ($row) { $stock = $row->stock ? $row->stock : 0; $unit_selling_price = (float) $row->group_price > 0 ? $row->group_price : $row->unit_price; $stock_price_by_sp = $stock * $unit_selling_price; $potential_profit = (float) $stock_price_by_sp - (float) $row->stock_price; return '<span class="potential_profit" data-orig-value="'.(float) $potential_profit.'" > '.$this->transactionUtil->num_f($potential_profit, true).'</span>'; }) ->setRowClass(function ($row) { return $row->enable_stock && $row->stock <= $row->alert_quantity ? 'bg-danger' : ''; }) ->filterColumn('variation', function ($query, $keyword) { $query->whereRaw("CONCAT(COALESCE(pv.name, ''), '-', COALESCE(variations.name, '')) like ?", ["%{$keyword}%"]); }) ->removeColumn('enable_stock') ->removeColumn('unit') ->removeColumn('id'); $raw_columns = ['unit_price', 'total_transfered', 'total_sold', 'total_adjusted', 'stock', 'stock_price', 'stock_value_by_sale_price', 'potential_profit', 'action', ]; if ($show_manufacturing_data) { $datatable->editColumn('total_mfg_stock', function ($row) { $total_mfg_stock = 0; if ($row->total_mfg_stock) { $total_mfg_stock = (float) $row->total_mfg_stock; } return '<span data-is_quantity="true" class="total_mfg_stock" data-orig-value="'.$total_mfg_stock.'" data-unit="'.$row->unit.'" >'.$this->transactionUtil->num_f($total_mfg_stock, false, null, true).'</span> '.$row->unit; }); $raw_columns[] = 'total_mfg_stock'; } return $datatable->rawColumns($raw_columns)->make(true); } $categories = Category::forDropdown($business_id, 'product'); $brands = Brands::forDropdown($business_id); $units = Unit::where('business_id', $business_id) ->pluck('short_name', 'id'); $business_locations = BusinessLocation::forDropdown($business_id, true); return view('report.stock_report') ->with(compact('categories', 'brands', 'units', 'business_locations', 'show_manufacturing_data')); } // // this function copy of above get route becouse of large size parameter // public function postStockReport(Request $request){ // if ($request->ajax()) { // $filters = request()->only(['location_id', 'category_id', 'sub_category_id', 'brand_id', 'unit_id', 'tax_id', 'type', // 'only_mfg_products', 'active_state', 'not_for_selling', 'repair_model_id', 'product_id', 'active_state', ]); // $filters['not_for_selling'] = isset($filters['not_for_selling']) && $filters['not_for_selling'] == 'true' ? 1 : 0; // $filters['show_manufacturing_data'] = $show_manufacturing_data; // //Return the details in ajax call // $for = request()->input('for') == 'view_product' ? 'view_product' : 'datatables'; // $products = $this->productUtil->getProductStockDetails($business_id, $filters, $for); // //To show stock details on view product modal // if ($for == 'view_product' && ! empty(request()->input('product_id'))) { // $product_stock_details = $products; // return view('product.partials.product_stock_details')->with(compact('product_stock_details')); // } // $datatable = Datatables::of($products) // ->editColumn('stock', function ($row) { // if ($row->enable_stock) { // $stock = $row->stock ? $row->stock : 0; // return '<span class="current_stock" data-orig-value="'.(float) $stock.'" data-unit="'.$row->unit.'"> '.$this->transactionUtil->num_f($stock, false, null, true).'</span>'.' '.$row->unit; // } else { // return '--'; // } // }) // ->editColumn('product', function ($row) { // $name = $row->product; // return $name; // }) // ->addColumn('action', function ($row) { // return '<a class="tw-dw-btn tw-dw-btn-xs tw-dw-btn-outline tw-dw-btn-info" href="'.action([\App\Http\Controllers\ProductController::class, 'productStockHistory'], [$row->product_id]). // '?location_id='.$row->location_id.'&variation_id='.$row->variation_id. // '"><i class="fas fa-history"></i> '.__('lang_v1.product_stock_history').'</a>'; // }) // ->addColumn('variation', function ($row) { // $variation = ''; // if ($row->type == 'variable') { // $variation .= $row->product_variation.'-'.$row->variation_name; // } // return $variation; // }) // ->editColumn('total_sold', function ($row) { // $total_sold = 0; // if ($row->total_sold) { // $total_sold = (float) $row->total_sold; // } // return '<span data-is_quantity="true" class="total_sold" data-orig-value="'.$total_sold.'" data-unit="'.$row->unit.'" >'.$this->transactionUtil->num_f($total_sold, false, null, true).'</span> '.$row->unit; // }) // ->editColumn('total_transfered', function ($row) { // $total_transfered = 0; // if ($row->total_transfered) { // $total_transfered = (float) $row->total_transfered; // } // return '<span class="total_transfered" data-orig-value="'.$total_transfered.'" data-unit="'.$row->unit.'" >'.$this->transactionUtil->num_f($total_transfered, false, null, true).'</span> '.$row->unit; // }) // ->editColumn('total_adjusted', function ($row) { // $total_adjusted = 0; // if ($row->total_adjusted) { // $total_adjusted = (float) $row->total_adjusted; // } // return '<span class="total_adjusted" data-orig-value="'.$total_adjusted.'" data-unit="'.$row->unit.'" >'.$this->transactionUtil->num_f($total_adjusted, false, null, true).'</span> '.$row->unit; // }) // ->editColumn('unit_price', function ($row) use ($allowed_selling_price_group) { // $html = ''; // if (auth()->user()->can('access_default_selling_price')) { // $html .= $this->transactionUtil->num_f($row->unit_price, true); // } // if ($allowed_selling_price_group) { // $html .= ' <button type="button" class="tw-dw-btn tw-dw-btn-xs tw-dw-btn-outline tw-dw-btn-primary btn-modal no-print" data-container=".view_modal" data-href="'.action([\App\Http\Controllers\ProductController::class, 'viewGroupPrice'], [$row->product_id]).'">'.__('lang_v1.view_group_prices').'</button>'; // } // return $html; // }) // ->editColumn('stock_price', function ($row) { // $html = '<span class="total_stock_price" data-orig-value="' // .$row->stock_price.'">'. // $this->transactionUtil->num_f($row->stock_price, true).'</span>'; // return $html; // }) // ->editColumn('stock_value_by_sale_price', function ($row) { // $stock = $row->stock ? $row->stock : 0; // $unit_selling_price = (float) $row->group_price > 0 ? $row->group_price : $row->unit_price; // $stock_price = $stock * $unit_selling_price; // return '<span class="stock_value_by_sale_price" data-orig-value="'.(float) $stock_price.'" > '.$this->transactionUtil->num_f($stock_price, true).'</span>'; // }) // ->addColumn('potential_profit', function ($row) { // $stock = $row->stock ? $row->stock : 0; // $unit_selling_price = (float) $row->group_price > 0 ? $row->group_price : $row->unit_price; // $stock_price_by_sp = $stock * $unit_selling_price; // $potential_profit = (float) $stock_price_by_sp - (float) $row->stock_price; // return '<span class="potential_profit" data-orig-value="'.(float) $potential_profit.'" > '.$this->transactionUtil->num_f($potential_profit, true).'</span>'; // }) // ->setRowClass(function ($row) { // return $row->enable_stock && $row->stock <= $row->alert_quantity ? 'bg-danger' : ''; // }) // ->filterColumn('variation', function ($query, $keyword) { // $query->whereRaw("CONCAT(COALESCE(pv.name, ''), '-', COALESCE(variations.name, '')) like ?", ["%{$keyword}%"]); // }) // ->removeColumn('enable_stock') // ->removeColumn('unit') // ->removeColumn('id'); // $raw_columns = ['unit_price', 'total_transfered', 'total_sold', // 'total_adjusted', 'stock', 'stock_price', 'stock_value_by_sale_price', // 'potential_profit', 'action', ]; // if ($show_manufacturing_data) { // $datatable->editColumn('total_mfg_stock', function ($row) { // $total_mfg_stock = 0; // if ($row->total_mfg_stock) { // $total_mfg_stock = (float) $row->total_mfg_stock; // } // return '<span data-is_quantity="true" class="total_mfg_stock" data-orig-value="'.$total_mfg_stock.'" data-unit="'.$row->unit.'" >'.$this->transactionUtil->num_f($total_mfg_stock, false, null, true).'</span> '.$row->unit; // }); // $raw_columns[] = 'total_mfg_stock'; // } // return $datatable->rawColumns($raw_columns)->make(true); // } // } /** * Shows product stock details * * @return \Illuminate\Http\Response */ public function getStockDetails(Request $request) { //Return the details in ajax call if ($request->ajax()) { $business_id = $request->session()->get('user.business_id'); $product_id = $request->input('product_id'); $query = Product::leftjoin('units as u', 'products.unit_id', '=', 'u.id') ->join('variations as v', 'products.id', '=', 'v.product_id') ->join('product_variations as pv', 'pv.id', '=', 'v.product_variation_id') ->leftjoin('variation_location_details as vld', 'v.id', '=', 'vld.variation_id') ->where('products.business_id', $business_id) ->where('products.id', $product_id) ->whereNull('v.deleted_at'); $permitted_locations = auth()->user()->permitted_locations(); $location_filter = ''; if ($permitted_locations != 'all') { $query->whereIn('vld.location_id', $permitted_locations); $locations_imploded = implode(', ', $permitted_locations); $location_filter .= "AND transactions.location_id IN ($locations_imploded) "; } if (! empty($request->input('location_id'))) { $location_id = $request->input('location_id'); $query->where('vld.location_id', $location_id); $location_filter .= "AND transactions.location_id=$location_id"; } $product_details = $query->select( 'products.name as product', 'u.short_name as unit', 'pv.name as product_variation', 'v.name as variation', 'v.sub_sku as sub_sku', 'v.sell_price_inc_tax', DB::raw('SUM(vld.qty_available) as stock'), DB::raw("(SELECT SUM(IF(transactions.type='sell', TSL.quantity - TSL.quantity_returned, -1* TPL.quantity) ) FROM transactions LEFT JOIN transaction_sell_lines AS TSL ON transactions.id=TSL.transaction_id LEFT JOIN purchase_lines AS TPL ON transactions.id=TPL.transaction_id WHERE transactions.status='final' AND transactions.type='sell' $location_filter AND (TSL.variation_id=v.id OR TPL.variation_id=v.id)) as total_sold"), DB::raw("(SELECT SUM(IF(transactions.type='sell_transfer', TSL.quantity, 0) ) FROM transactions LEFT JOIN transaction_sell_lines AS TSL ON transactions.id=TSL.transaction_id WHERE transactions.status='final' AND transactions.type='sell_transfer' $location_filter AND (TSL.variation_id=v.id)) as total_transfered"), DB::raw("(SELECT SUM(IF(transactions.type='stock_adjustment', SAL.quantity, 0) ) FROM transactions LEFT JOIN stock_adjustment_lines AS SAL ON transactions.id=SAL.transaction_id WHERE transactions.status='received' AND transactions.type='stock_adjustment' $location_filter AND (SAL.variation_id=v.id)) as total_adjusted") // DB::raw("(SELECT SUM(quantity) FROM transaction_sell_lines LEFT JOIN transactions ON transaction_sell_lines.transaction_id=transactions.id WHERE transactions.status='final' $location_filter AND // transaction_sell_lines.variation_id=v.id) as total_sold") ) ->groupBy('v.id') ->get(); return view('report.stock_details') ->with(compact('product_details')); } } /** * Shows tax report of a business * * @return \Illuminate\Http\Response */ public function getTaxDetails(Request $request) { if (! auth()->user()->can('tax_report.view')) { abort(403, 'Unauthorized action.'); } if ($request->ajax()) { $business_id = $request->session()->get('user.business_id'); $taxes = TaxRate::forBusiness($business_id); $type = $request->input('type'); $payment_types = $this->transactionUtil->payment_types(null, true, $business_id); $sells = Transaction::leftJoin('tax_rates as tr', 'transactions.tax_id', '=', 'tr.id') ->leftJoin('contacts as c', 'transactions.contact_id', '=', 'c.id') ->where('transactions.business_id', $business_id) ->with(['payment_lines']) ->select('c.name as contact_name', 'c.supplier_business_name', 'c.tax_number', 'transactions.ref_no', 'transactions.invoice_no', 'transactions.transaction_date', 'transactions.total_before_tax', 'transactions.tax_id', 'transactions.tax_amount', 'transactions.id', 'transactions.type', 'transactions.discount_type', 'transactions.discount_amount' ); if ($type == 'sell') { $sells->where('transactions.type', 'sell') ->where('transactions.status', 'final') ->where(function ($query) { $query->whereHas('sell_lines', function ($q) { $q->whereNotNull('transaction_sell_lines.tax_id'); })->orWhereNotNull('transactions.tax_id'); }) ->with(['sell_lines' => function ($q) { $q->whereNotNull('transaction_sell_lines.tax_id'); }, 'sell_lines.line_tax']); } if ($type == 'purchase') { $sells->where('transactions.type', 'purchase') ->where('transactions.status', 'received') ->where(function ($query) { $query->whereHas('purchase_lines', function ($q) { $q->whereNotNull('purchase_lines.tax_id'); })->orWhereNotNull('transactions.tax_id'); }) ->with(['purchase_lines' => function ($q) { $q->whereNotNull('purchase_lines.tax_id'); }, 'purchase_lines.line_tax']); } if ($type == 'expense') { $sells->where('transactions.type', 'expense') ->whereNotNull('transactions.tax_id'); } $permitted_locations = auth()->user()->permitted_locations(); if ($permitted_locations != 'all') { $sells->whereIn('transactions.location_id', $permitted_locations); } if (request()->has('location_id')) { $location_id = request()->get('location_id'); if (! empty($location_id)) { $sells->where('transactions.location_id', $location_id); } } if (request()->has('contact_id')) { $contact_id = request()->get('contact_id'); if (! empty($contact_id)) { $sells->where('transactions.contact_id', $contact_id); } } if (! empty(request()->start_date) && ! empty(request()->end_date)) { $start = request()->start_date; $end = request()->end_date; $sells->whereDate('transactions.transaction_date', '>=', $start) ->whereDate('transactions.transaction_date', '<=', $end); } $datatable = Datatables::of($sells); $raw_cols = ['total_before_tax', 'discount_amount', 'contact_name', 'payment_methods']; $group_taxes_array = TaxRate::groupTaxes($business_id); $group_taxes = []; foreach ($group_taxes_array as $group_tax) { foreach ($group_tax['sub_taxes'] as $sub_tax) { $group_taxes[$group_tax->id]['sub_taxes'][$sub_tax->id] = $sub_tax; } } foreach ($taxes as $tax) { $col = 'tax_'.$tax['id']; $raw_cols[] = $col; $datatable->addColumn($col, function ($row) use ($tax, $type, $col, $group_taxes) { $tax_amount = 0; if ($type == 'sell') { foreach ($row->sell_lines as $sell_line) { if ($sell_line->tax_id == $tax['id']) { $tax_amount += ($sell_line->item_tax * ($sell_line->quantity - $sell_line->quantity_returned)); } //break group tax if ($sell_line->line_tax->is_tax_group == 1 && array_key_exists($tax['id'], $group_taxes[$sell_line->tax_id]['sub_taxes'])) { $group_tax_details = $this->transactionUtil->groupTaxDetails($sell_line->line_tax, $sell_line->item_tax); $sub_tax_share = 0; foreach ($group_tax_details as $sub_tax_details) { if ($sub_tax_details['id'] == $tax['id']) { $sub_tax_share = $sub_tax_details['calculated_tax']; } } $tax_amount += ($sub_tax_share * ($sell_line->quantity - $sell_line->quantity_returned)); } } } elseif ($type == 'purchase') { foreach ($row->purchase_lines as $purchase_line) { if ($purchase_line->tax_id == $tax['id']) { $tax_amount += ($purchase_line->item_tax * ($purchase_line->quantity - $purchase_line->quantity_returned)); } //break group tax if ($purchase_line->line_tax->is_tax_group == 1 && array_key_exists($tax['id'], $group_taxes[$purchase_line->tax_id]['sub_taxes'])) { $group_tax_details = $this->transactionUtil->groupTaxDetails($purchase_line->line_tax, $purchase_line->item_tax); $sub_tax_share = 0; foreach ($group_tax_details as $sub_tax_details) { if ($sub_tax_details['id'] == $tax['id']) { $sub_tax_share = $sub_tax_details['calculated_tax']; } } $tax_amount += ($sub_tax_share * ($purchase_line->quantity - $purchase_line->quantity_returned)); } } } if ($row->tax_id == $tax['id']) { $tax_amount += $row->tax_amount; } //break group tax if (! empty($group_taxes[$row->tax_id]) && array_key_exists($tax['id'], $group_taxes[$row->tax_id]['sub_taxes'])) { $group_tax_details = $this->transactionUtil->groupTaxDetails($row->tax_id, $row->tax_amount); $sub_tax_share = 0; foreach ($group_tax_details as $sub_tax_details) { if ($sub_tax_details['id'] == $tax['id']) { $sub_tax_share = $sub_tax_details['calculated_tax']; } } $tax_amount += $sub_tax_share; } if ($tax_amount > 0) { return '<span class="display_currency '.$col.'" data-currency_symbol="true" data-orig-value="'.$tax_amount.'">'.$tax_amount.'</span>'; } else { return ''; } }); } $datatable->editColumn( 'total_before_tax', function ($row) { return '<span class="total_before_tax" data-orig-value="'.$row->total_before_tax.'">'. $this->transactionUtil->num_f($row->total_before_tax, true).'</span>'; } )->editColumn('discount_amount', function ($row) { $d = ''; if ($row->discount_amount !== 0) { $symbol = $row->discount_type != 'percentage'; $d .= $this->transactionUtil->num_f($row->discount_amount, $symbol); if ($row->discount_type == 'percentage') { $d .= '%'; } } return $d; }) ->editColumn('transaction_date', '{{@format_datetime($transaction_date)}}') ->editColumn('contact_name', '@if(!empty($supplier_business_name)) {{$supplier_business_name}},<br>@endif {{$contact_name}}') ->addColumn('payment_methods', function ($row) use ($payment_types) { $methods = array_unique($row->payment_lines->pluck('method')->toArray()); $count = count($methods); $payment_method = ''; if ($count == 1) { $payment_method = $payment_types[$methods[0]]; } elseif ($count > 1) { $payment_method = __('lang_v1.checkout_multi_pay'); } $html = ! empty($payment_method) ? '<span class="payment-method" data-orig-value="'.$payment_method.'" data-status-name="'.$payment_method.'">'.$payment_method.'</span>' : ''; return $html; }); return $datatable->rawColumns($raw_cols) ->make(true); } } /** * Shows tax report of a business * * @return \Illuminate\Http\Response */ public function getTaxReport(Request $request) { if (! auth()->user()->can('tax_report.view')) { abort(403, 'Unauthorized action.'); } $business_id = $request->session()->get('user.business_id'); //Return the details in ajax call if ($request->ajax()) { $start_date = $request->get('start_date'); $end_date = $request->get('end_date'); $location_id = $request->get('location_id'); $contact_id = $request->get('contact_id'); $input_tax_details = $this->transactionUtil->getInputTax($business_id, $start_date, $end_date, $location_id, $contact_id); $output_tax_details = $this->transactionUtil->getOutputTax($business_id, $start_date, $end_date, $location_id, $contact_id); $expense_tax_details = $this->transactionUtil->getExpenseTax($business_id, $start_date, $end_date, $location_id, $contact_id); $module_output_taxes = $this->moduleUtil->getModuleData('getModuleOutputTax', ['start_date' => $start_date, 'end_date' => $end_date]); $total_module_output_tax = 0; foreach ($module_output_taxes as $key => $module_output_tax) { $total_module_output_tax += $module_output_tax; } $total_output_tax = $output_tax_details['total_tax'] + $total_module_output_tax; $tax_diff = $total_output_tax - $input_tax_details['total_tax'] - $expense_tax_details['total_tax']; return [ 'tax_diff' => $tax_diff, ]; } $business_locations = BusinessLocation::forDropdown($business_id, true); $taxes = TaxRate::forBusiness($business_id); $tax_report_tabs = $this->moduleUtil->getModuleData('getTaxReportViewTabs'); $contact_dropdown = Contact::contactDropdown($business_id, false, false); return view('report.tax_report') ->with(compact('business_locations', 'taxes', 'tax_report_tabs', 'contact_dropdown')); } /** * Shows trending products * * @return \Illuminate\Http\Response */ public function getTrendingProducts(Request $request) { if (! auth()->user()->can('trending_product_report.view')) { abort(403, 'Unauthorized action.'); } $business_id = $request->session()->get('user.business_id'); $filters = request()->only(['category', 'sub_category', 'brand', 'unit', 'limit', 'location_id', 'product_type']); $date_range = request()->input('date_range'); if (! empty($date_range)) { $date_range_array = explode('~', $date_range); $filters['start_date'] = $this->transactionUtil->uf_date(trim($date_range_array[0])); $filters['end_date'] = $this->transactionUtil->uf_date(trim($date_range_array[1])); } $products = $this->productUtil->getTrendingProducts($business_id, $filters); $values = []; $labels = []; foreach ($products as $product) { $values[] = (float) $product->total_unit_sold; $labels[] = $product->product.' - '.$product->sku.' ('.$product->unit.')'; } $chart = new CommonChart; $chart->labels($labels) ->dataset(__('report.total_unit_sold'), 'column', $values); $categories = Category::forDropdown($business_id, 'product'); $brands = Brands::forDropdown($business_id); $units = Unit::where('business_id', $business_id) ->pluck('short_name', 'id'); $business_locations = BusinessLocation::forDropdown($business_id, true); return view('report.trending_products') ->with(compact('chart', 'categories', 'brands', 'units', 'business_locations')); } public function getTrendingProductsAjax() { $business_id = request()->session()->get('user.business_id'); } /** * Shows expense report of a business * * @return \Illuminate\Http\Response */ public function getExpenseReport(Request $request) { if (! auth()->user()->can('expense_report.view')) { abort(403, 'Unauthorized action.'); } $business_id = $request->session()->get('user.business_id'); $filters = $request->only(['category', 'location_id']); $date_range = $request->input('date_range'); if (! empty($date_range)) { $date_range_array = explode('~', $date_range); $filters['start_date'] = $this->transactionUtil->uf_date(trim($date_range_array[0])); $filters['end_date'] = $this->transactionUtil->uf_date(trim($date_range_array[1])); } else { $filters['start_date'] = \Carbon::now()->startOfMonth()->format('Y-m-d'); $filters['end_date'] = \Carbon::now()->endOfMonth()->format('Y-m-d'); } $expenses = $this->transactionUtil->getExpenseReport($business_id, $filters); $values = []; $labels = []; foreach ($expenses as $expense) { $values[] = (float) $expense->total_expense; $labels[] = ! empty($expense->category) ? $expense->category : __('report.others'); } $chart = new CommonChart; $chart->labels($labels) ->title(__('report.expense_report')) ->dataset(__('report.total_expense'), 'column', $values); $categories = ExpenseCategory::where('business_id', $business_id) ->pluck('name', 'id'); $business_locations = BusinessLocation::forDropdown($business_id, true); return view('report.expense_report') ->with(compact('chart', 'categories', 'business_locations', 'expenses')); } /** * Shows stock adjustment report * * @return \Illuminate\Http\Response */ public function getStockAdjustmentReport(Request $request) { if (! auth()->user()->can('stock_report.view')) { abort(403, 'Unauthorized action.'); } $business_id = $request->session()->get('user.business_id'); //Return the details in ajax call if ($request->ajax()) { $query = Transaction::where('business_id', $business_id) ->where('type', 'stock_adjustment'); //Check for permitted locations of a user $permitted_locations = auth()->user()->permitted_locations(); if ($permitted_locations != 'all') { $query->whereIn('location_id', $permitted_locations); } $start_date = $request->get('start_date'); $end_date = $request->get('end_date'); if (! empty($start_date) && ! empty($end_date)) { $query->whereBetween(DB::raw('date(transaction_date)'), [$start_date, $end_date]); } $location_id = $request->get('location_id'); if (! empty($location_id)) { $query->where('location_id', $location_id); } $stock_adjustment_details = $query->select( DB::raw('SUM(final_total) as total_amount'), DB::raw('SUM(total_amount_recovered) as total_recovered'), DB::raw("SUM(IF(adjustment_type = 'normal', final_total, 0)) as total_normal"), DB::raw("SUM(IF(adjustment_type = 'abnormal', final_total, 0)) as total_abnormal") )->first(); return $stock_adjustment_details; } $business_locations = BusinessLocation::forDropdown($business_id, true); return view('report.stock_adjustment_report') ->with(compact('business_locations')); } /** * Shows register report of a business * * @return \Illuminate\Http\Response */ public function getRegisterReport(Request $request) { if (! auth()->user()->can('register_report.view')) { abort(403, 'Unauthorized action.'); } $business_id = $request->session()->get('user.business_id'); //Return the details in ajax call if ($request->ajax()) { $start_date = request()->input('start_date'); $end_date = request()->input('end_date'); $user_id = request()->input('user_id'); $permitted_locations = auth()->user()->permitted_locations(); $registers = $this->transactionUtil->registerReport($business_id, $permitted_locations, $start_date, $end_date, $user_id); return Datatables::of($registers) ->editColumn('total_card_payment', function ($row) { return '<span data-orig-value="'.$row->total_card_payment.'" >'.$this->transactionUtil->num_f($row->total_card_payment, true).' ('.$row->total_card_slips.')</span>'; }) ->editColumn('total_cheque_payment', function ($row) { return '<span data-orig-value="'.$row->total_cheque_payment.'" >'.$this->transactionUtil->num_f($row->total_cheque_payment, true).' ('.$row->total_cheques.')</span>'; }) ->editColumn('total_cash_payment', function ($row) { return '<span data-orig-value="'.$row->total_cash_payment.'" >'.$this->transactionUtil->num_f($row->total_cash_payment, true).'</span>'; }) ->editColumn('total_bank_transfer_payment', function ($row) { return '<span data-orig-value="'.$row->total_bank_transfer_payment.'" >'.$this->transactionUtil->num_f($row->total_bank_transfer_payment, true).'</span>'; }) ->editColumn('total_other_payment', function ($row) { return '<span data-orig-value="'.$row->total_other_payment.'" >'.$this->transactionUtil->num_f($row->total_other_payment, true).'</span>'; }) ->editColumn('total_advance_payment', function ($row) { return '<span data-orig-value="'.$row->total_advance_payment.'" >'.$this->transactionUtil->num_f($row->total_advance_payment, true).'</span>'; }) ->editColumn('total_custom_pay_1', function ($row) { return '<span data-orig-value="'.$row->total_custom_pay_1.'" >'.$this->transactionUtil->num_f($row->total_custom_pay_1, true).'</span>'; }) ->editColumn('total_custom_pay_2', function ($row) { return '<span data-orig-value="'.$row->total_custom_pay_2.'" >'.$this->transactionUtil->num_f($row->total_custom_pay_2, true).'</span>'; }) ->editColumn('total_custom_pay_3', function ($row) { return '<span data-orig-value="'.$row->total_custom_pay_3.'" >'.$this->transactionUtil->num_f($row->total_custom_pay_3, true).'</span>'; }) ->editColumn('total_custom_pay_4', function ($row) { return '<span data-orig-value="'.$row->total_custom_pay_4.'" >'.$this->transactionUtil->num_f($row->total_custom_pay_4, true).'</span>'; }) ->editColumn('total_custom_pay_5', function ($row) { return '<span data-orig-value="'.$row->total_custom_pay_5.'" >'.$this->transactionUtil->num_f($row->total_custom_pay_5, true).'</span>'; }) ->editColumn('total_custom_pay_6', function ($row) { return '<span data-orig-value="'.$row->total_custom_pay_6.'" >'.$this->transactionUtil->num_f($row->total_custom_pay_6, true).'</span>'; }) ->editColumn('total_custom_pay_7', function ($row) { return '<span data-orig-value="'.$row->total_custom_pay_7.'" >'.$this->transactionUtil->num_f($row->total_custom_pay_7, true).'</span>'; }) ->editColumn('closed_at', function ($row) { if ($row->status == 'close') { return $this->productUtil->format_date($row->closed_at, true); } else { return ''; } }) ->editColumn('created_at', function ($row) { return $this->productUtil->format_date($row->created_at, true); }) ->addColumn('total', function ($row) { $total = $row->total_card_payment + $row->total_cheque_payment + $row->total_cash_payment + $row->total_bank_transfer_payment + $row->total_other_payment + $row->total_advance_payment + $row->total_custom_pay_1 + $row->total_custom_pay_2 + $row->total_custom_pay_3 + $row->total_custom_pay_4 + $row->total_custom_pay_5 + $row->total_custom_pay_6 + $row->total_custom_pay_7; return '<span data-orig-value="'.$total.'" >'.$this->transactionUtil->num_f($total, true).'</span>'; }) ->addColumn('action', '<button type="button" data-href="{{action(\'App\Http\Controllers\CashRegisterController@show\', [$id])}}" class="tw-dw-btn tw-dw-btn-xs tw-dw-btn-outline tw-dw-btn-info tw-w-max btn-modal" data-container=".view_register"><i class="fas fa-eye" aria-hidden="true"></i> @lang("messages.view")</button> @if($status != "close" && auth()->user()->can("close_cash_register"))<button type="button" data-href="{{action(\'App\Http\Controllers\CashRegisterController@getCloseRegister\', [$id])}}" class="tw-dw-btn tw-dw-btn-outline tw-dw-btn-xs tw-dw-btn-error tw-w-max btn-modal" data-container=".view_register"><i class="fas fa-window-close"></i> @lang("messages.close")</button> @endif') ->filterColumn('user_name', function ($query, $keyword) { $query->whereRaw("CONCAT(COALESCE(surname, ''), ' ', COALESCE(first_name, ''), ' ', COALESCE(last_name, ''), '<br>', COALESCE(u.email, '')) like ?", ["%{$keyword}%"]); }) ->rawColumns(['action', 'user_name', 'total_card_payment', 'total_cheque_payment', 'total_cash_payment', 'total_bank_transfer_payment', 'total_other_payment', 'total_advance_payment', 'total_custom_pay_1', 'total_custom_pay_2', 'total_custom_pay_3', 'total_custom_pay_4', 'total_custom_pay_5', 'total_custom_pay_6', 'total_custom_pay_7', 'total']) ->make(true); } $users = User::forDropdown($business_id, false); $payment_types = $this->transactionUtil->payment_types(null, true, $business_id); return view('report.register_report') ->with(compact('users', 'payment_types')); } /** * Shows sales representative report * * @return \Illuminate\Http\Response */ public function getSalesRepresentativeReport(Request $request) { if (! auth()->user()->can('sales_representative.view')) { abort(403, 'Unauthorized action.'); } $business_id = $request->session()->get('user.business_id'); $users = User::allUsersDropdown($business_id, false); $business_locations = BusinessLocation::forDropdown($business_id, true); $business_details = $this->businessUtil->getDetails($business_id); $pos_settings = empty($business_details->pos_settings) ? $this->businessUtil->defaultPosSettings() : json_decode($business_details->pos_settings, true); return view('report.sales_representative') ->with(compact('users', 'business_locations', 'pos_settings')); } /** * Shows sales representative total expense * * @return json */ public function getSalesRepresentativeTotalExpense(Request $request) { if (! auth()->user()->can('sales_representative.view')) { abort(403, 'Unauthorized action.'); } if ($request->ajax()) { $business_id = $request->session()->get('user.business_id'); $filters = $request->only(['expense_for', 'location_id', 'start_date', 'end_date']); $total_expense = $this->transactionUtil->getExpenseReport($business_id, $filters, 'total'); return $total_expense; } } /** * Shows sales representative total sales * * @return json */ public function getSalesRepresentativeTotalSell(Request $request) { if (! auth()->user()->can('sales_representative.view')) { abort(403, 'Unauthorized action.'); } $business_id = $request->session()->get('user.business_id'); //Return the details in ajax call if ($request->ajax()) { $start_date = $request->get('start_date'); $end_date = $request->get('end_date'); $location_id = $request->get('location_id'); $created_by = $request->get('created_by'); $sell_details = $this->transactionUtil->getSellTotals($business_id, $start_date, $end_date, $location_id, $created_by); //Get Sell Return details $transaction_types = [ 'sell_return', ]; $sell_return_details = $this->transactionUtil->getTransactionTotals( $business_id, $transaction_types, $start_date, $end_date, $location_id, $created_by ); $total_sell_return = ! empty($sell_return_details['total_sell_return_exc_tax']) ? $sell_return_details['total_sell_return_exc_tax'] : 0; $total_sell = $sell_details['total_sell_exc_tax'] - $total_sell_return; return [ 'total_sell_exc_tax' => $sell_details['total_sell_exc_tax'], 'total_sell_return_exc_tax' => $total_sell_return, 'total_sell' => $total_sell, ]; } } /** * Shows sales representative total commission * * @return json */ public function getSalesRepresentativeTotalCommission(Request $request) { if (! auth()->user()->can('sales_representative.view')) { abort(403, 'Unauthorized action.'); } $business_id = $request->session()->get('user.business_id'); //Return the details in ajax call if ($request->ajax()) { $start_date = $request->get('start_date'); $end_date = $request->get('end_date'); $location_id = $request->get('location_id'); $commission_agent = $request->get('commission_agent'); $business_details = $this->businessUtil->getDetails($business_id); $pos_settings = empty($business_details->pos_settings) ? $this->businessUtil->defaultPosSettings() : json_decode($business_details->pos_settings, true); $commsn_calculation_type = empty($pos_settings['cmmsn_calculation_type']) || $pos_settings['cmmsn_calculation_type'] == 'invoice_value' ? 'invoice_value' : $pos_settings['cmmsn_calculation_type']; $commission_percentage = User::find($commission_agent)->cmmsn_percent; if ($commsn_calculation_type == 'payment_received') { $payment_details = $this->transactionUtil->getTotalPaymentWithCommission($business_id, $start_date, $end_date, $location_id, $commission_agent); //Get Commision $total_commission = $commission_percentage * $payment_details['total_payment_with_commission'] / 100; return ['total_payment_with_commission' => $payment_details['total_payment_with_commission'] ?? 0, 'total_commission' => $total_commission, 'commission_percentage' => $commission_percentage, ]; } $sell_details = $this->transactionUtil->getTotalSellCommission($business_id, $start_date, $end_date, $location_id, $commission_agent); //Get Commision $total_commission = $commission_percentage * $sell_details['total_sales_with_commission'] / 100; return ['total_sales_with_commission' => $sell_details['total_sales_with_commission'], 'total_commission' => $total_commission, 'commission_percentage' => $commission_percentage, ]; } } /** * Shows product stock expiry report * * @return \Illuminate\Http\Response */ public function getStockExpiryReport(Request $request) { if (! auth()->user()->can('stock_report.view')) { abort(403, 'Unauthorized action.'); } $business_id = $request->session()->get('user.business_id'); //TODO:: Need to display reference number and edit expiry date button //Return the details in ajax call if ($request->ajax()) { $query = PurchaseLine::leftjoin( 'transactions as t', 'purchase_lines.transaction_id', '=', 't.id' ) ->leftjoin( 'products as p', 'purchase_lines.product_id', '=', 'p.id' ) ->leftjoin( 'variations as v', 'purchase_lines.variation_id', '=', 'v.id' ) ->leftjoin( 'product_variations as pv', 'v.product_variation_id', '=', 'pv.id' ) ->leftjoin('business_locations as l', 't.location_id', '=', 'l.id') ->leftjoin('units as u', 'p.unit_id', '=', 'u.id') ->where('t.business_id', $business_id) //->whereNotNull('p.expiry_period') //->whereNotNull('p.expiry_period_type') //->whereNotNull('exp_date') ->where('p.enable_stock', 1); // ->whereRaw('purchase_lines.quantity > purchase_lines.quantity_sold + quantity_adjusted + quantity_returned'); $permitted_locations = auth()->user()->permitted_locations(); if ($permitted_locations != 'all') { $query->whereIn('t.location_id', $permitted_locations); } if (! empty($request->input('location_id'))) { $location_id = $request->input('location_id'); $query->where('t.location_id', $location_id) //If filter by location then hide products not available in that location ->join('product_locations as pl', 'pl.product_id', '=', 'p.id') ->where(function ($q) use ($location_id) { $q->where('pl.location_id', $location_id); }); } if (! empty($request->input('category_id'))) { $query->where('p.category_id', $request->input('category_id')); } if (! empty($request->input('sub_category_id'))) { $query->where('p.sub_category_id', $request->input('sub_category_id')); } if (! empty($request->input('brand_id'))) { $query->where('p.brand_id', $request->input('brand_id')); } if (! empty($request->input('unit_id'))) { $query->where('p.unit_id', $request->input('unit_id')); } if (! empty($request->input('exp_date_filter'))) { $query->whereDate('exp_date', '<=', $request->input('exp_date_filter')); } $only_mfg_products = request()->get('only_mfg_products', 0); if (! empty($only_mfg_products)) { $query->where('t.type', 'production_purchase'); } $report = $query->select( 'p.name as product', 'p.sku', 'p.type as product_type', 'v.name as variation', 'v.sub_sku', 'pv.name as product_variation', 'l.name as location', 'mfg_date', 'exp_date', 'u.short_name as unit', DB::raw('SUM(COALESCE(quantity, 0) - COALESCE(quantity_sold, 0) - COALESCE(quantity_adjusted, 0) - COALESCE(quantity_returned, 0)) as stock_left'), 't.ref_no', 't.id as transaction_id', 'purchase_lines.id as purchase_line_id', 'purchase_lines.lot_number' ) ->having('stock_left', '>', 0) ->groupBy('purchase_lines.variation_id') ->groupBy('purchase_lines.exp_date') ->groupBy('purchase_lines.lot_number'); return Datatables::of($report) ->editColumn('product', function ($row) { if ($row->product_type == 'variable') { return $row->product.' - '. $row->product_variation.' - '.$row->variation.' ('.$row->sub_sku.')'; } else { return $row->product.' ('.$row->sku.')'; } }) ->editColumn('mfg_date', function ($row) { if (! empty($row->mfg_date)) { return $this->productUtil->format_date($row->mfg_date); } else { return '--'; } }) // ->editColumn('exp_date', function ($row) { // if (!empty($row->exp_date)) { // $carbon_exp = \Carbon::createFromFormat('Y-m-d', $row->exp_date); // $carbon_now = \Carbon::now(); // if ($carbon_now->diffInDays($carbon_exp, false) >= 0) { // return $this->productUtil->format_date($row->exp_date) . '<br><small>( <span class="time-to-now">' . $row->exp_date . '</span> )</small>'; // } else { // return $this->productUtil->format_date($row->exp_date) . ' <span class="label label-danger no-print">' . __('report.expired') . '</span><span class="print_section">' . __('report.expired') . '</span><br><small>( <span class="time-from-now">' . $row->exp_date . '</span> )</small>'; // } // } else { // return '--'; // } // }) ->editColumn('ref_no', function ($row) { return '<button type="button" data-href="'.action([\App\Http\Controllers\PurchaseController::class, 'show'], [$row->transaction_id]) .'" class="btn btn-link btn-modal" data-container=".view_modal" >'.$row->ref_no.'</button>'; }) ->editColumn('stock_left', function ($row) { return '<span data-is_quantity="true" class="display_currency stock_left" data-currency_symbol=false data-orig-value="'.$row->stock_left.'" data-unit="'.$row->unit.'" >'.$row->stock_left.'</span> '.$row->unit; }) ->addColumn('edit', function ($row) { $html = '<button type="button" class="tw-dw-btn tw-dw-btn-xs tw-dw-btn-outline tw-dw-btn-primary stock_expiry_edit_btn" data-transaction_id="'.$row->transaction_id.'" data-purchase_line_id="'.$row->purchase_line_id.'"> <i class="fa fa-edit"></i> '.__('messages.edit'). '</button>'; if (! empty($row->exp_date)) { $carbon_exp = \Carbon::createFromFormat('Y-m-d', $row->exp_date); $carbon_now = \Carbon::now(); if ($carbon_now->diffInDays($carbon_exp, false) < 0) { $html .= ' <button type="button" class="btn btn-warning btn-xs remove_from_stock_btn" data-href="'.action([\App\Http\Controllers\StockAdjustmentController::class, 'removeExpiredStock'], [$row->purchase_line_id]).'"> <i class="fa fa-trash"></i> '.__('lang_v1.remove_from_stock'). '</button>'; } } return $html; }) ->rawColumns(['exp_date', 'ref_no', 'edit', 'stock_left']) ->make(true); } $categories = Category::forDropdown($business_id, 'product'); $brands = Brands::forDropdown($business_id); $units = Unit::where('business_id', $business_id) ->pluck('short_name', 'id'); $business_locations = BusinessLocation::forDropdown($business_id, true); $view_stock_filter = [ \Carbon::now()->subDay()->format('Y-m-d') => __('report.expired'), \Carbon::now()->addWeek()->format('Y-m-d') => __('report.expiring_in_1_week'), \Carbon::now()->addDays(15)->format('Y-m-d') => __('report.expiring_in_15_days'), \Carbon::now()->addMonth()->format('Y-m-d') => __('report.expiring_in_1_month'), \Carbon::now()->addMonths(3)->format('Y-m-d') => __('report.expiring_in_3_months'), \Carbon::now()->addMonths(6)->format('Y-m-d') => __('report.expiring_in_6_months'), \Carbon::now()->addYear()->format('Y-m-d') => __('report.expiring_in_1_year'), ]; return view('report.stock_expiry_report') ->with(compact('categories', 'brands', 'units', 'business_locations', 'view_stock_filter')); } /** * Shows product stock expiry report * * @return \Illuminate\Http\Response */ public function getStockExpiryReportEditModal(Request $request, $purchase_line_id) { if (! auth()->user()->can('stock_report.view')) { abort(403, 'Unauthorized action.'); } $business_id = $request->session()->get('user.business_id'); //Return the details in ajax call if ($request->ajax()) { $purchase_line = PurchaseLine::join( 'transactions as t', 'purchase_lines.transaction_id', '=', 't.id' ) ->join( 'products as p', 'purchase_lines.product_id', '=', 'p.id' ) ->where('purchase_lines.id', $purchase_line_id) ->where('t.business_id', $business_id) ->select(['purchase_lines.*', 'p.name', 't.ref_no']) ->first(); if (! empty($purchase_line)) { if (! empty($purchase_line->exp_date)) { $purchase_line->exp_date = date('m/d/Y', strtotime($purchase_line->exp_date)); } } return view('report.partials.stock_expiry_edit_modal') ->with(compact('purchase_line')); } } /** * Update product stock expiry report * * @return \Illuminate\Http\Response */ public function updateStockExpiryReport(Request $request) { if (! auth()->user()->can('stock_report.view')) { abort(403, 'Unauthorized action.'); } try { $business_id = $request->session()->get('user.business_id'); //Return the details in ajax call if ($request->ajax()) { DB::beginTransaction(); $input = $request->only(['purchase_line_id', 'exp_date']); $purchase_line = PurchaseLine::join( 'transactions as t', 'purchase_lines.transaction_id', '=', 't.id' ) ->join( 'products as p', 'purchase_lines.product_id', '=', 'p.id' ) ->where('purchase_lines.id', $input['purchase_line_id']) ->where('t.business_id', $business_id) ->select(['purchase_lines.*', 'p.name', 't.ref_no']) ->first(); if (! empty($purchase_line) && ! empty($input['exp_date'])) { $purchase_line->exp_date = $this->productUtil->uf_date($input['exp_date']); $purchase_line->save(); } DB::commit(); $output = ['success' => 1, 'msg' => __('lang_v1.updated_succesfully'), ]; } } catch (\Exception $e) { DB::rollBack(); \Log::emergency('File:'.$e->getFile().'Line:'.$e->getLine().'Message:'.$e->getMessage()); $output = ['success' => 0, 'msg' => __('messages.something_went_wrong'), ]; } return $output; } /** * Shows product stock expiry report * * @return \Illuminate\Http\Response */ public function getCustomerGroup(Request $request) { if (! auth()->user()->can('contacts_report.view')) { abort(403, 'Unauthorized action.'); } $business_id = $request->session()->get('user.business_id'); if ($request->ajax()) { $query = Transaction::leftjoin('customer_groups AS CG', 'transactions.customer_group_id', '=', 'CG.id') ->where('transactions.business_id', $business_id) ->where('transactions.type', 'sell') ->where('transactions.status', 'final') ->groupBy('transactions.customer_group_id') ->select(DB::raw('SUM(final_total) as total_sell'), 'CG.name'); $group_id = $request->get('customer_group_id', null); if (! empty($group_id)) { $query->where('transactions.customer_group_id', $group_id); } $permitted_locations = auth()->user()->permitted_locations(); if ($permitted_locations != 'all') { $query->whereIn('transactions.location_id', $permitted_locations); } $location_id = $request->get('location_id', null); if (! empty($location_id)) { $query->where('transactions.location_id', $location_id); } $start_date = $request->get('start_date'); $end_date = $request->get('end_date'); if (! empty($start_date) && ! empty($end_date)) { $query->whereBetween(DB::raw('date(transaction_date)'), [$start_date, $end_date]); } return Datatables::of($query) ->editColumn('total_sell', function ($row) { return '<span class="display_currency" data-currency_symbol = true>'.$row->total_sell.'</span>'; }) ->rawColumns(['total_sell']) ->make(true); } $customer_group = CustomerGroup::forDropdown($business_id, false, true); $business_locations = BusinessLocation::forDropdown($business_id, true); return view('report.customer_group') ->with(compact('customer_group', 'business_locations')); } /** * Shows product purchase report * * @return \Illuminate\Http\Response */ public function getproductPurchaseReport(Request $request) { if (! auth()->user()->can('purchase_n_sell_report.view')) { abort(403, 'Unauthorized action.'); } $business_id = $request->session()->get('user.business_id'); if ($request->ajax()) { $variation_id = $request->get('variation_id', null); $query = PurchaseLine::join( 'transactions as t', 'purchase_lines.transaction_id', '=', 't.id' ) ->join( 'variations as v', 'purchase_lines.variation_id', '=', 'v.id' ) ->join('product_variations as pv', 'v.product_variation_id', '=', 'pv.id') ->join('contacts as c', 't.contact_id', '=', 'c.id') ->join('products as p', 'pv.product_id', '=', 'p.id') ->leftjoin('units as u', 'p.unit_id', '=', 'u.id') ->where('t.business_id', $business_id) ->where('t.type', 'purchase') ->select( 'p.name as product_name', 'p.type as product_type', 'pv.name as product_variation', 'v.name as variation_name', 'v.sub_sku', 'c.name as supplier', 'c.supplier_business_name', 't.id as transaction_id', 't.ref_no', 't.transaction_date as transaction_date', 'purchase_lines.purchase_price_inc_tax as unit_purchase_price', DB::raw('(purchase_lines.quantity - purchase_lines.quantity_returned) as purchase_qty'), 'purchase_lines.quantity_adjusted', 'u.short_name as unit', DB::raw('((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted) * purchase_lines.purchase_price_inc_tax) as subtotal') ) ->groupBy('purchase_lines.id'); if (! empty($variation_id)) { $query->where('purchase_lines.variation_id', $variation_id); } $start_date = $request->get('start_date'); $end_date = $request->get('end_date'); if (! empty($start_date) && ! empty($end_date)) { $query->whereBetween(DB::raw('date(transaction_date)'), [$start_date, $end_date]); } $permitted_locations = auth()->user()->permitted_locations(); if ($permitted_locations != 'all') { $query->whereIn('t.location_id', $permitted_locations); } $location_id = $request->get('location_id', null); if (! empty($location_id)) { $query->where('t.location_id', $location_id); } $supplier_id = $request->get('supplier_id', null); if (! empty($supplier_id)) { $query->where('t.contact_id', $supplier_id); } $brand_id = $request->get('brand_id', null); if (! empty($brand_id)) { $query->where('p.brand_id', $brand_id); } return Datatables::of($query) ->editColumn('product_name', function ($row) { $product_name = $row->product_name; if ($row->product_type == 'variable') { $product_name .= ' - '.$row->product_variation.' - '.$row->variation_name; } return $product_name; }) ->editColumn('ref_no', function ($row) { return '<a data-href="'.action([\App\Http\Controllers\PurchaseController::class, 'show'], [$row->transaction_id]) .'" href="#" data-container=".view_modal" class="btn-modal">'.$row->ref_no.'</a>'; }) ->editColumn('purchase_qty', function ($row) { return '<span data-is_quantity="true" class="display_currency purchase_qty" data-currency_symbol=false data-orig-value="'.(float) $row->purchase_qty.'" data-unit="'.$row->unit.'" >'.(float) $row->purchase_qty.'</span> '.$row->unit; }) ->editColumn('quantity_adjusted', function ($row) { return '<span data-is_quantity="true" class="display_currency quantity_adjusted" data-currency_symbol=false data-orig-value="'.(float) $row->quantity_adjusted.'" data-unit="'.$row->unit.'" >'.(float) $row->quantity_adjusted.'</span> '.$row->unit; }) ->editColumn('subtotal', function ($row) { return '<span class="row_subtotal" data-orig-value="'.$row->subtotal.'">'. $this->transactionUtil->num_f($row->subtotal, true).'</span>'; }) ->editColumn('transaction_date', '{{@format_date($transaction_date)}}') ->editColumn('unit_purchase_price', function ($row) { return $this->transactionUtil->num_f($row->unit_purchase_price, true); }) ->editColumn('supplier', '@if(!empty($supplier_business_name)) {{$supplier_business_name}},<br>@endif {{$supplier}}') ->rawColumns(['ref_no', 'unit_purchase_price', 'subtotal', 'purchase_qty', 'quantity_adjusted', 'supplier']) ->make(true); } $business_locations = BusinessLocation::forDropdown($business_id); $suppliers = Contact::suppliersDropdown($business_id); $brands = Brands::forDropdown($business_id); return view('report.product_purchase_report') ->with(compact('business_locations', 'suppliers', 'brands')); } /** * Shows product purchase report * * @return \Illuminate\Http\Response */ public function getproductSellReport(Request $request) { if (! auth()->user()->can('purchase_n_sell_report.view')) { abort(403, 'Unauthorized action.'); } $business_id = $request->session()->get('user.business_id'); $custom_labels = json_decode(session('business.custom_labels'), true); $product_custom_field1 = !empty($custom_labels['product']['custom_field_1']) ? $custom_labels['product']['custom_field_1'] : ''; $product_custom_field2 = !empty($custom_labels['product']['custom_field_2']) ? $custom_labels['product']['custom_field_2'] : ''; if ($request->ajax()) { $payment_types = $this->transactionUtil->payment_types(null, true, $business_id); $variation_id = $request->get('variation_id', null); $query = TransactionSellLine::join( 'transactions as t', 'transaction_sell_lines.transaction_id', '=', 't.id' ) ->join( 'variations as v', 'transaction_sell_lines.variation_id', '=', 'v.id' ) ->join('product_variations as pv', 'v.product_variation_id', '=', 'pv.id') ->join('contacts as c', 't.contact_id', '=', 'c.id') ->join('products as p', 'pv.product_id', '=', 'p.id') ->leftjoin('tax_rates', 'transaction_sell_lines.tax_id', '=', 'tax_rates.id') ->leftjoin('units as u', 'p.unit_id', '=', 'u.id') ->where('t.business_id', $business_id) ->where('t.type', 'sell') ->where('t.status', 'final') ->with('transaction.payment_lines') ->select( 'p.name as product_name', 'p.type as product_type', 'p.product_custom_field1 as product_custom_field1', 'p.product_custom_field2 as product_custom_field2', 'pv.name as product_variation', 'v.name as variation_name', 'v.sub_sku', 'c.name as customer', 'c.supplier_business_name', 'c.contact_id', 't.id as transaction_id', 't.invoice_no', 't.transaction_date as transaction_date', 'transaction_sell_lines.unit_price_before_discount as unit_price', 'transaction_sell_lines.unit_price_inc_tax as unit_sale_price', DB::raw('(transaction_sell_lines.quantity - transaction_sell_lines.quantity_returned) as sell_qty'), 'transaction_sell_lines.line_discount_type as discount_type', 'transaction_sell_lines.line_discount_amount as discount_amount', 'transaction_sell_lines.item_tax', 'tax_rates.name as tax', 'u.short_name as unit', 'transaction_sell_lines.parent_sell_line_id', DB::raw('((transaction_sell_lines.quantity - transaction_sell_lines.quantity_returned) * transaction_sell_lines.unit_price_inc_tax) as subtotal') ) ->groupBy('transaction_sell_lines.id'); if (! empty($variation_id)) { $query->where('transaction_sell_lines.variation_id', $variation_id); } $start_date = $request->get('start_date'); $end_date = $request->get('end_date'); if (! empty($start_date) && ! empty($end_date)) { $query->where('t.transaction_date', '>=', $start_date) ->where('t.transaction_date', '<=', $end_date); } $permitted_locations = auth()->user()->permitted_locations(); if ($permitted_locations != 'all') { $query->whereIn('t.location_id', $permitted_locations); } $location_id = $request->get('location_id', null); if (! empty($location_id)) { $query->where('t.location_id', $location_id); } $customer_id = $request->get('customer_id', null); if (! empty($customer_id)) { $query->where('t.contact_id', $customer_id); } $customer_group_id = $request->get('customer_group_id', null); if (! empty($customer_group_id)) { $query->leftjoin('customer_groups AS CG', 'c.customer_group_id', '=', 'CG.id') ->where('CG.id', $customer_group_id); } $category_id = $request->get('category_id', null); if (! empty($category_id)) { $query->where('p.category_id', $category_id); } $brand_id = $request->get('brand_id', null); if (! empty($brand_id)) { $query->where('p.brand_id', $brand_id); } return Datatables::of($query) ->editColumn('product_name', function ($row) { $product_name = $row->product_name; if ($row->product_type == 'variable') { $product_name .= ' - '.$row->product_variation.' - '.$row->variation_name; } return $product_name; }) ->editColumn('invoice_no', function ($row) { return '<a data-href="'.action([\App\Http\Controllers\SellController::class, 'show'], [$row->transaction_id]) .'" href="#" data-container=".view_modal" class="btn-modal">'.$row->invoice_no.'</a>'; }) ->editColumn('transaction_date', '{{@format_datetime($transaction_date)}}') ->editColumn('unit_sale_price', function ($row) { return '<span class="unit_sale_price" data-orig-value="'.$row->unit_sale_price.'">'. $this->transactionUtil->num_f($row->unit_sale_price, true).'</span>'; }) ->editColumn('sell_qty', function ($row) { //ignore child sell line of combo product $class = is_null($row->parent_sell_line_id) ? 'sell_qty' : ''; return '<span class="'.$class.'" data-orig-value="'.$row->sell_qty.'" data-unit="'.$row->unit.'" >'. $this->transactionUtil->num_f($row->sell_qty, false, null, true).'</span> '.$row->unit; }) ->editColumn('subtotal', function ($row) { //ignore child sell line of combo product $class = is_null($row->parent_sell_line_id) ? 'row_subtotal' : ''; return '<span class="'.$class.'" data-orig-value="'.$row->subtotal.'">'. $this->transactionUtil->num_f($row->subtotal, true).'</span>'; }) ->editColumn('unit_price', function ($row) { return '<span class="unit_price" data-orig-value="'.$row->unit_price.'">'. $this->transactionUtil->num_f($row->unit_price, true).'</span>'; }) ->editColumn('discount_amount', ' @if($discount_type == "percentage") {{@num_format($discount_amount)}} % @elseif($discount_type == "fixed") {{@num_format($discount_amount)}} @endif ') ->editColumn('tax', function ($row) { return $this->transactionUtil->num_f($row->item_tax, true) .'<br>'.'<span data-orig-value="'.$row->item_tax.'" class="tax" data-unit="'.$row->tax.'"><small>('.$row->tax.')</small></span>'; }) ->addColumn('payment_methods', function ($row) use ($payment_types) { $methods = array_unique($row->transaction->payment_lines->pluck('method')->toArray()); $count = count($methods); $payment_method = ''; if ($count == 1) { $payment_method = $payment_types[$methods[0]] ?? ''; } elseif ($count > 1) { $payment_method = __('lang_v1.checkout_multi_pay'); } $html = ! empty($payment_method) ? '<span class="payment-method" data-orig-value="'.$payment_method.'" data-status-name="'.$payment_method.'">'.$payment_method.'</span>' : ''; return $html; }) ->editColumn('customer', '@if(!empty($supplier_business_name)) {{$supplier_business_name}},<br>@endif {{$customer}}') ->rawColumns(['invoice_no', 'unit_sale_price', 'subtotal', 'sell_qty', 'discount_amount', 'unit_price', 'tax', 'customer', 'payment_methods']) ->make(true); } $business_locations = BusinessLocation::forDropdown($business_id); $customers = Contact::customersDropdown($business_id); $categories = Category::forDropdown($business_id, 'product'); $brands = Brands::forDropdown($business_id); $customer_group = CustomerGroup::forDropdown($business_id, false, true); return view('report.product_sell_report') ->with(compact('business_locations', 'customers', 'categories', 'brands', 'customer_group', 'product_custom_field1', 'product_custom_field2')); } /** * Shows product purchase report with purchase details * * @return \Illuminate\Http\Response */ public function getproductSellReportWithPurchase(Request $request) { if (! auth()->user()->can('purchase_n_sell_report.view')) { abort(403, 'Unauthorized action.'); } $business_id = $request->session()->get('user.business_id'); if ($request->ajax()) { $variation_id = $request->get('variation_id', null); $query = TransactionSellLine::join( 'transactions as t', 'transaction_sell_lines.transaction_id', '=', 't.id' ) ->join( 'transaction_sell_lines_purchase_lines as tspl', 'transaction_sell_lines.id', '=', 'tspl.sell_line_id' ) ->join( 'purchase_lines as pl', 'tspl.purchase_line_id', '=', 'pl.id' ) ->join( 'transactions as purchase', 'pl.transaction_id', '=', 'purchase.id' ) ->leftjoin('contacts as supplier', 'purchase.contact_id', '=', 'supplier.id') ->join( 'variations as v', 'transaction_sell_lines.variation_id', '=', 'v.id' ) ->join('product_variations as pv', 'v.product_variation_id', '=', 'pv.id') ->leftjoin('contacts as c', 't.contact_id', '=', 'c.id') ->join('products as p', 'pv.product_id', '=', 'p.id') ->leftjoin('units as u', 'p.unit_id', '=', 'u.id') ->where('t.business_id', $business_id) ->where('t.type', 'sell') ->where('t.status', 'final') ->select( 'p.name as product_name', 'p.type as product_type', 'pv.name as product_variation', 'v.name as variation_name', 'v.sub_sku', 'c.name as customer', 'c.supplier_business_name', 't.id as transaction_id', 't.invoice_no', 't.transaction_date as transaction_date', 'tspl.quantity as purchase_quantity', 'u.short_name as unit', 'supplier.name as supplier_name', 'purchase.ref_no as ref_no', 'purchase.type as purchase_type', 'pl.lot_number' ); if (! empty($variation_id)) { $query->where('transaction_sell_lines.variation_id', $variation_id); } $start_date = $request->get('start_date'); $end_date = $request->get('end_date'); if (! empty($start_date) && ! empty($end_date)) { $query->where('t.transaction_date', '>=', $start_date) ->where('t.transaction_date', '<=', $end_date); } $permitted_locations = auth()->user()->permitted_locations(); if ($permitted_locations != 'all') { $query->whereIn('t.location_id', $permitted_locations); } $location_id = $request->get('location_id', null); if (! empty($location_id)) { $query->where('t.location_id', $location_id); } $customer_id = $request->get('customer_id', null); if (! empty($customer_id)) { $query->where('t.contact_id', $customer_id); } $customer_group_id = $request->get('customer_group_id', null); if (! empty($customer_group_id)) { $query->leftjoin('customer_groups AS CG', 'c.customer_group_id', '=', 'CG.id') ->where('CG.id', $customer_group_id); } $category_id = $request->get('category_id', null); if (! empty($category_id)) { $query->where('p.category_id', $category_id); } $brand_id = $request->get('brand_id', null); if (! empty($brand_id)) { $query->where('p.brand_id', $brand_id); } return Datatables::of($query) ->editColumn('product_name', function ($row) { $product_name = $row->product_name; if ($row->product_type == 'variable') { $product_name .= ' - '.$row->product_variation.' - '.$row->variation_name; } return $product_name; }) ->editColumn('invoice_no', function ($row) { return '<a data-href="'.action([\App\Http\Controllers\SellController::class, 'show'], [$row->transaction_id]) .'" href="#" data-container=".view_modal" class="btn-modal">'.$row->invoice_no.'</a>'; }) ->editColumn('transaction_date', '{{@format_datetime($transaction_date)}}') ->editColumn('unit_sale_price', function ($row) { return '<span class="display_currency" data-currency_symbol = true>'.$row->unit_sale_price.'</span>'; }) ->editColumn('purchase_quantity', function ($row) { return '<span data-is_quantity="true" class="display_currency purchase_quantity" data-currency_symbol=false data-orig-value="'.(float) $row->purchase_quantity.'" data-unit="'.$row->unit.'" >'.(float) $row->purchase_quantity.'</span> '.$row->unit; }) ->editColumn('ref_no', ' @if($purchase_type == "opening_stock") <i><small class="help-block">(@lang("lang_v1.opening_stock"))</small></i> @else {{$ref_no}} @endif ') ->editColumn('customer', '@if(!empty($supplier_business_name)) {{$supplier_business_name}},<br>@endif {{$customer}}') ->rawColumns(['invoice_no', 'purchase_quantity', 'ref_no', 'customer']) ->make(true); } } /** * Shows product lot report * * @return \Illuminate\Http\Response */ public function getLotReport(Request $request) { if (! auth()->user()->can('stock_report.view')) { abort(403, 'Unauthorized action.'); } $business_id = $request->session()->get('user.business_id'); //Return the details in ajax call if ($request->ajax()) { $query = Product::where('products.business_id', $business_id) ->leftjoin('units', 'products.unit_id', '=', 'units.id') ->join('variations as v', 'products.id', '=', 'v.product_id') ->join('purchase_lines as pl', 'v.id', '=', 'pl.variation_id') ->leftjoin( 'transaction_sell_lines_purchase_lines as tspl', 'pl.id', '=', 'tspl.purchase_line_id' ) ->join('transactions as t', 'pl.transaction_id', '=', 't.id'); $permitted_locations = auth()->user()->permitted_locations(); $location_filter = 'WHERE '; if ($permitted_locations != 'all') { $query->whereIn('t.location_id', $permitted_locations); $locations_imploded = implode(', ', $permitted_locations); $location_filter = " LEFT JOIN transactions as t2 on pls.transaction_id=t2.id WHERE t2.location_id IN ($locations_imploded) AND "; } if (! empty($request->input('location_id'))) { $location_id = $request->input('location_id'); $query->where('t.location_id', $location_id) //If filter by location then hide products not available in that location ->ForLocation($location_id); $location_filter = "LEFT JOIN transactions as t2 on pls.transaction_id=t2.id WHERE t2.location_id=$location_id AND "; } if (! empty($request->input('category_id'))) { $query->where('products.category_id', $request->input('category_id')); } if (! empty($request->input('sub_category_id'))) { $query->where('products.sub_category_id', $request->input('sub_category_id')); } if (! empty($request->input('brand_id'))) { $query->where('products.brand_id', $request->input('brand_id')); } if (! empty($request->input('unit_id'))) { $query->where('products.unit_id', $request->input('unit_id')); } $only_mfg_products = request()->get('only_mfg_products', 0); if (! empty($only_mfg_products)) { $query->where('t.type', 'production_purchase'); } $products = $query->select( 'products.name as product', 'v.name as variation_name', 'sub_sku', 'pl.lot_number', 'pl.exp_date as exp_date', DB::raw("( COALESCE((SELECT SUM(quantity - quantity_returned) from purchase_lines as pls $location_filter variation_id = v.id AND lot_number = pl.lot_number), 0) - SUM(COALESCE((tspl.quantity - tspl.qty_returned), 0))) as stock"), // DB::raw("(SELECT SUM(IF(transactions.type='sell', TSL.quantity, -1* TPL.quantity) ) FROM transactions // LEFT JOIN transaction_sell_lines AS TSL ON transactions.id=TSL.transaction_id // LEFT JOIN purchase_lines AS TPL ON transactions.id=TPL.transaction_id // WHERE transactions.status='final' AND transactions.type IN ('sell', 'sell_return') $location_filter // AND (TSL.product_id=products.id OR TPL.product_id=products.id)) as total_sold"), DB::raw('COALESCE(SUM(IF(tspl.sell_line_id IS NULL, 0, (tspl.quantity - tspl.qty_returned)) ), 0) as total_sold'), DB::raw('COALESCE(SUM(IF(tspl.stock_adjustment_line_id IS NULL, 0, tspl.quantity ) ), 0) as total_adjusted'), 'products.type', 'units.short_name as unit' ) ->whereNotNull('pl.lot_number') ->groupBy('v.id') ->groupBy('pl.lot_number'); return Datatables::of($products) ->editColumn('stock', function ($row) { $stock = $row->stock ? $row->stock : 0; return '<span data-is_quantity="true" class="display_currency total_stock" data-currency_symbol=false data-orig-value="'.(float) $stock.'" data-unit="'.$row->unit.'" >'.(float) $stock.'</span> '.$row->unit; }) ->editColumn('product', function ($row) { if ($row->variation_name != 'DUMMY') { return $row->product.' ('.$row->variation_name.')'; } else { return $row->product; } }) ->editColumn('total_sold', function ($row) { if ($row->total_sold) { return '<span data-is_quantity="true" class="display_currency total_sold" data-currency_symbol=false data-orig-value="'.(float) $row->total_sold.'" data-unit="'.$row->unit.'" >'.(float) $row->total_sold.'</span> '.$row->unit; } else { return '0'.' '.$row->unit; } }) ->editColumn('total_adjusted', function ($row) { if ($row->total_adjusted) { return '<span data-is_quantity="true" class="display_currency total_adjusted" data-currency_symbol=false data-orig-value="'.(float) $row->total_adjusted.'" data-unit="'.$row->unit.'" >'.(float) $row->total_adjusted.'</span> '.$row->unit; } else { return '0'.' '.$row->unit; } }) ->editColumn('exp_date', function ($row) { if (! empty($row->exp_date)) { $carbon_exp = \Carbon::createFromFormat('Y-m-d', $row->exp_date); $carbon_now = \Carbon::now(); if ($carbon_now->diffInDays($carbon_exp, false) >= 0) { return $this->productUtil->format_date($row->exp_date).'<br><small>( <span class="time-to-now">'.$row->exp_date.'</span> )</small>'; } else { return $this->productUtil->format_date($row->exp_date).' <span class="label label-danger no-print">'.__('report.expired').'</span><span class="print_section">'.__('report.expired').'</span><br><small>( <span class="time-from-now">'.$row->exp_date.'</span> )</small>'; } } else { return '--'; } }) ->removeColumn('unit') ->removeColumn('id') ->removeColumn('variation_name') ->rawColumns(['exp_date', 'stock', 'total_sold', 'total_adjusted']) ->make(true); } $categories = Category::forDropdown($business_id, 'product'); $brands = Brands::forDropdown($business_id); $units = Unit::where('business_id', $business_id) ->pluck('short_name', 'id'); $business_locations = BusinessLocation::forDropdown($business_id, true); return view('report.lot_report') ->with(compact('categories', 'brands', 'units', 'business_locations')); } /** * Shows purchase payment report * * @return \Illuminate\Http\Response */ public function purchasePaymentReport(Request $request) { if (! auth()->user()->can('purchase_n_sell_report.view')) { abort(403, 'Unauthorized action.'); } $business_id = $request->session()->get('user.business_id'); if ($request->ajax()) { $supplier_id = $request->get('supplier_id', null); $contact_filter1 = ! empty($supplier_id) ? "AND t.contact_id=$supplier_id" : ''; $contact_filter2 = ! empty($supplier_id) ? "AND transactions.contact_id=$supplier_id" : ''; $location_id = $request->get('location_id', null); $parent_payment_query_part = empty($location_id) ? 'AND transaction_payments.parent_id IS NULL' : ''; $query = TransactionPayment::leftjoin('transactions as t', function ($join) use ($business_id) { $join->on('transaction_payments.transaction_id', '=', 't.id') ->where('t.business_id', $business_id) ->whereIn('t.type', ['purchase', 'opening_balance']); }) ->where('transaction_payments.business_id', $business_id) ->where(function ($q) use ($business_id, $contact_filter1, $contact_filter2, $parent_payment_query_part) { $q->whereRaw("(transaction_payments.transaction_id IS NOT NULL AND t.type IN ('purchase', 'opening_balance') $parent_payment_query_part $contact_filter1)") ->orWhereRaw("EXISTS(SELECT * FROM transaction_payments as tp JOIN transactions ON tp.transaction_id = transactions.id WHERE transactions.type IN ('purchase', 'opening_balance') AND transactions.business_id = $business_id AND tp.parent_id=transaction_payments.id $contact_filter2)"); }) ->select( DB::raw("IF(transaction_payments.transaction_id IS NULL, (SELECT c.name FROM transactions as ts JOIN contacts as c ON ts.contact_id=c.id WHERE ts.id=( SELECT tps.transaction_id FROM transaction_payments as tps WHERE tps.parent_id=transaction_payments.id LIMIT 1 ) ), (SELECT CONCAT(COALESCE(c.supplier_business_name, ''), '<br>', c.name) FROM transactions as ts JOIN contacts as c ON ts.contact_id=c.id WHERE ts.id=t.id ) ) as supplier"), 'transaction_payments.amount', 'method', 'paid_on', 'transaction_payments.payment_ref_no', 'transaction_payments.document', 't.ref_no', 't.id as transaction_id', 'cheque_number', 'card_transaction_number', 'bank_account_number', 'transaction_no', 'transaction_payments.id as DT_RowId' ) ->groupBy('transaction_payments.id'); $start_date = $request->get('start_date'); $end_date = $request->get('end_date'); if (! empty($start_date) && ! empty($end_date)) { $query->whereBetween(DB::raw('date(paid_on)'), [$start_date, $end_date]); } $permitted_locations = auth()->user()->permitted_locations(); if ($permitted_locations != 'all') { $query->whereIn('t.location_id', $permitted_locations); } if (! empty($location_id)) { $query->where('t.location_id', $location_id); } $payment_types = $this->transactionUtil->payment_types(null, true, $business_id); return Datatables::of($query) ->editColumn('ref_no', function ($row) { if (! empty($row->ref_no)) { return '<a data-href="'.action([\App\Http\Controllers\PurchaseController::class, 'show'], [$row->transaction_id]) .'" href="#" data-container=".view_modal" class="btn-modal">'.$row->ref_no.'</a>'; } else { return ''; } }) ->editColumn('paid_on', '{{@format_datetime($paid_on)}}') ->editColumn('method', function ($row) use ($payment_types) { $method = ! empty($payment_types[$row->method]) ? $payment_types[$row->method] : ''; if ($row->method == 'cheque') { $method .= '<br>('.__('lang_v1.cheque_no').': '.$row->cheque_number.')'; } elseif ($row->method == 'card') { $method .= '<br>('.__('lang_v1.card_transaction_no').': '.$row->card_transaction_number.')'; } elseif ($row->method == 'bank_transfer') { $method .= '<br>('.__('lang_v1.bank_account_no').': '.$row->bank_account_number.')'; } elseif ($row->method == 'custom_pay_1') { $method .= '<br>('.__('lang_v1.transaction_no').': '.$row->transaction_no.')'; } elseif ($row->method == 'custom_pay_2') { $method .= '<br>('.__('lang_v1.transaction_no').': '.$row->transaction_no.')'; } elseif ($row->method == 'custom_pay_3') { $method .= '<br>('.__('lang_v1.transaction_no').': '.$row->transaction_no.')'; } return $method; }) ->editColumn('amount', function ($row) { return '<span class="paid-amount" data-orig-value="'.$row->amount.'">'. $this->transactionUtil->num_f($row->amount, true).'</span>'; }) ->addColumn('action', '<button type="button" class="tw-dw-btn tw-dw-btn-xs tw-dw-btn-outline tw-dw-btn-primary view_payment" data-href="{{ action([\App\Http\Controllers\TransactionPaymentController::class, \'viewPayment\'], [$DT_RowId]) }}">@lang("messages.view") </button> @if(!empty($document))<a href="{{asset("/uploads/documents/" . $document)}}" class="tw-dw-btn tw-dw-btn-xs tw-dw-btn-outline tw-dw-btn-accent" download=""><i class="fa fa-download"></i> @lang("purchase.download_document")</a>@endif') ->rawColumns(['ref_no', 'amount', 'method', 'action', 'supplier']) ->make(true); } $business_locations = BusinessLocation::forDropdown($business_id); $suppliers = Contact::suppliersDropdown($business_id, false); return view('report.purchase_payment_report') ->with(compact('business_locations', 'suppliers')); } /** * Shows sell payment report * * @return \Illuminate\Http\Response */ public function sellPaymentReport(Request $request) { if (! auth()->user()->can('purchase_n_sell_report.view')) { abort(403, 'Unauthorized action.'); } $business_id = $request->session()->get('user.business_id'); $payment_types = $this->transactionUtil->payment_types(null, true, $business_id); if ($request->ajax()) { $customer_id = $request->get('supplier_id', null); $contact_filter1 = ! empty($customer_id) ? "AND t.contact_id=$customer_id" : ''; $contact_filter2 = ! empty($customer_id) ? "AND transactions.contact_id=$customer_id" : ''; $location_id = $request->get('location_id', null); $parent_payment_query_part = empty($location_id) ? 'AND transaction_payments.parent_id IS NULL' : ''; $query = TransactionPayment::leftjoin('transactions as t', function ($join) use ($business_id) { $join->on('transaction_payments.transaction_id', '=', 't.id') ->where('t.business_id', $business_id) ->whereIn('t.type', ['sell', 'opening_balance']); }) ->leftjoin('contacts as c', 't.contact_id', '=', 'c.id') ->leftjoin('customer_groups AS CG', 'c.customer_group_id', '=', 'CG.id') ->where('transaction_payments.business_id', $business_id) ->where(function ($q) use ($business_id, $contact_filter1, $contact_filter2, $parent_payment_query_part) { $q->whereRaw("(transaction_payments.transaction_id IS NOT NULL AND t.type IN ('sell', 'opening_balance') $parent_payment_query_part $contact_filter1)") ->orWhereRaw("EXISTS(SELECT * FROM transaction_payments as tp JOIN transactions ON tp.transaction_id = transactions.id WHERE transactions.type IN ('sell', 'opening_balance') AND transactions.business_id = $business_id AND tp.parent_id=transaction_payments.id $contact_filter2)"); }) ->select( DB::raw("IF(transaction_payments.transaction_id IS NULL, (SELECT c.name FROM transactions as ts JOIN contacts as c ON ts.contact_id=c.id WHERE ts.id=( SELECT tps.transaction_id FROM transaction_payments as tps WHERE tps.parent_id=transaction_payments.id LIMIT 1 ) ), (SELECT CONCAT(COALESCE(CONCAT(c.supplier_business_name, '<br>'), ''), c.name) FROM transactions as ts JOIN contacts as c ON ts.contact_id=c.id WHERE ts.id=t.id ) ) as customer"), 'transaction_payments.amount', 'transaction_payments.is_return', 'method', 'paid_on', 'transaction_payments.payment_ref_no', 'transaction_payments.document', 'transaction_payments.transaction_no', 't.invoice_no', 't.id as transaction_id', 'cheque_number', 'card_transaction_number', 'bank_account_number', 'transaction_payments.id as DT_RowId', 'CG.name as customer_group' ) ->groupBy('transaction_payments.id'); $start_date = $request->get('start_date'); $end_date = $request->get('end_date'); if (! empty($start_date) && ! empty($end_date)) { $query->whereBetween(DB::raw('date(paid_on)'), [$start_date, $end_date]); } $permitted_locations = auth()->user()->permitted_locations(); if ($permitted_locations != 'all') { $query->whereIn('t.location_id', $permitted_locations); } if (! empty($request->get('customer_group_id'))) { $query->where('CG.id', $request->get('customer_group_id')); } if (! empty($location_id)) { $query->where('t.location_id', $location_id); } if (! empty($request->has('commission_agent'))) { $query->where('t.commission_agent', $request->get('commission_agent')); } if (! empty($request->get('payment_types'))) { $query->where('transaction_payments.method', $request->get('payment_types')); } return Datatables::of($query) ->editColumn('invoice_no', function ($row) { if (! empty($row->transaction_id)) { return '<a data-href="'.action([\App\Http\Controllers\SellController::class, 'show'], [$row->transaction_id]) .'" href="#" data-container=".view_modal" class="btn-modal">'.$row->invoice_no.'</a>'; } else { return ''; } }) ->editColumn('paid_on', '{{@format_datetime($paid_on)}}') ->editColumn('method', function ($row) use ($payment_types) { $method = ! empty($payment_types[$row->method]) ? $payment_types[$row->method] : ''; if ($row->method == 'cheque') { $method .= '<br>('.__('lang_v1.cheque_no').': '.$row->cheque_number.')'; } elseif ($row->method == 'card') { $method .= '<br>('.__('lang_v1.card_transaction_no').': '.$row->card_transaction_number.')'; } elseif ($row->method == 'bank_transfer') { $method .= '<br>('.__('lang_v1.bank_account_no').': '.$row->bank_account_number.')'; } elseif ($row->method == 'custom_pay_1') { $method .= '<br>('.__('lang_v1.transaction_no').': '.$row->transaction_no.')'; } elseif ($row->method == 'custom_pay_2') { $method .= '<br>('.__('lang_v1.transaction_no').': '.$row->transaction_no.')'; } elseif ($row->method == 'custom_pay_3') { $method .= '<br>('.__('lang_v1.transaction_no').': '.$row->transaction_no.')'; } if ($row->is_return == 1) { $method .= '<br><small>('.__('lang_v1.change_return').')</small>'; } return $method; }) ->editColumn('amount', function ($row) { $amount = $row->is_return == 1 ? -1 * $row->amount : $row->amount; return '<span class="paid-amount" data-orig-value="'.$amount.'" >'.$this->transactionUtil->num_f($amount, true).'</span>'; }) ->addColumn('action', '<button type="button" class="tw-dw-btn tw-dw-btn-xs tw-dw-btn-outline tw-dw-btn-primary view_payment" data-href="{{ action([\App\Http\Controllers\TransactionPaymentController::class, \'viewPayment\'], [$DT_RowId]) }}">@lang("messages.view") </button> @if(!empty($document))<a href="{{asset("/uploads/documents/" . $document)}}" class="tw-dw-btn tw-dw-btn-xs tw-dw-btn-outline tw-dw-btn-accent" download=""><i class="fa fa-download"></i> @lang("purchase.download_document")</a>@endif') ->rawColumns(['invoice_no', 'amount', 'method', 'action', 'customer']) ->make(true); } $business_locations = BusinessLocation::forDropdown($business_id); $customers = Contact::customersDropdown($business_id, false); $customer_groups = CustomerGroup::forDropdown($business_id, false, true); return view('report.sell_payment_report') ->with(compact('business_locations', 'customers', 'payment_types', 'customer_groups')); } /** * Shows tables report * * @return \Illuminate\Http\Response */ public function getTableReport(Request $request) { if (! auth()->user()->can('purchase_n_sell_report.view')) { abort(403, 'Unauthorized action.'); } $business_id = $request->session()->get('user.business_id'); if ($request->ajax()) { $query = ResTable::leftjoin('transactions AS T', 'T.res_table_id', '=', 'res_tables.id') ->where('T.business_id', $business_id) ->where('T.type', 'sell') ->where('T.status', 'final') ->groupBy('res_tables.id') ->select(DB::raw('SUM(final_total) as total_sell'), 'res_tables.name as table'); $location_id = $request->get('location_id', null); if (! empty($location_id)) { $query->where('T.location_id', $location_id); } $start_date = $request->get('start_date'); $end_date = $request->get('end_date'); if (! empty($start_date) && ! empty($end_date)) { $query->whereBetween(DB::raw('date(transaction_date)'), [$start_date, $end_date]); } return Datatables::of($query) ->editColumn('total_sell', function ($row) { return '<span class="display_currency" data-currency_symbol="true">'.$row->total_sell.'</span>'; }) ->rawColumns(['total_sell']) ->make(true); } $business_locations = BusinessLocation::forDropdown($business_id, true); return view('report.table_report') ->with(compact('business_locations')); } /** * Shows service staff report * * @return \Illuminate\Http\Response */ public function getServiceStaffReport(Request $request) { if (! auth()->user()->can('sales_representative.view')) { abort(403, 'Unauthorized action.'); } $business_id = $request->session()->get('user.business_id'); $business_locations = BusinessLocation::forDropdown($business_id, true); $waiters = $this->transactionUtil->serviceStaffDropdown($business_id); return view('report.service_staff_report') ->with(compact('business_locations', 'waiters')); } /** * Shows product sell report grouped by date * * @return \Illuminate\Http\Response */ public function getproductSellGroupedReport(Request $request) { if (! auth()->user()->can('purchase_n_sell_report.view')) { abort(403, 'Unauthorized action.'); } $business_id = $request->session()->get('user.business_id'); $location_id = $request->get('location_id', null); $vld_str = ''; if (! empty($location_id)) { $vld_str = "AND vld.location_id=$location_id"; } if ($request->ajax()) { $variation_id = $request->get('variation_id', null); $query = TransactionSellLine::join( 'transactions as t', 'transaction_sell_lines.transaction_id', '=', 't.id' ) ->join( 'variations as v', 'transaction_sell_lines.variation_id', '=', 'v.id' ) ->join('product_variations as pv', 'v.product_variation_id', '=', 'pv.id') ->join('products as p', 'pv.product_id', '=', 'p.id') ->leftjoin('units as u', 'p.unit_id', '=', 'u.id') ->where('t.business_id', $business_id) ->where('t.type', 'sell') ->where('t.status', 'final') ->select( 'p.name as product_name', 'p.enable_stock', 'p.type as product_type', 'pv.name as product_variation', 'v.name as variation_name', 'v.sub_sku', 't.id as transaction_id', 't.transaction_date as transaction_date', 'transaction_sell_lines.parent_sell_line_id', DB::raw('DATE_FORMAT(t.transaction_date, "%Y-%m-%d") as formated_date'), DB::raw("(SELECT SUM(vld.qty_available) FROM variation_location_details as vld WHERE vld.variation_id=v.id $vld_str) as current_stock"), DB::raw('SUM(transaction_sell_lines.quantity - transaction_sell_lines.quantity_returned) as total_qty_sold'), 'u.short_name as unit', DB::raw('SUM((transaction_sell_lines.quantity - transaction_sell_lines.quantity_returned) * transaction_sell_lines.unit_price_inc_tax) as subtotal') ) ->groupBy('v.id') ->groupBy('formated_date'); if (! empty($variation_id)) { $query->where('transaction_sell_lines.variation_id', $variation_id); } $start_date = $request->get('start_date'); $end_date = $request->get('end_date'); if (! empty($start_date) && ! empty($end_date)) { $query->where('t.transaction_date', '>=', $start_date) ->where('t.transaction_date', '<=', $end_date); } $permitted_locations = auth()->user()->permitted_locations(); if ($permitted_locations != 'all') { $query->whereIn('t.location_id', $permitted_locations); } if (! empty($location_id)) { $query->where('t.location_id', $location_id); } $customer_id = $request->get('customer_id', null); if (! empty($customer_id)) { $query->where('t.contact_id', $customer_id); } $customer_group_id = $request->get('customer_group_id', null); if (! empty($customer_group_id)) { $query->leftjoin('contacts AS c', 't.contact_id', '=', 'c.id') ->leftjoin('customer_groups AS CG', 'c.customer_group_id', '=', 'CG.id') ->where('CG.id', $customer_group_id); } $category_id = $request->get('category_id', null); if (! empty($category_id)) { $query->where('p.category_id', $category_id); } $brand_id = $request->get('brand_id', null); if (! empty($brand_id)) { $query->where('p.brand_id', $brand_id); } return Datatables::of($query) ->editColumn('product_name', function ($row) { $product_name = $row->product_name; if ($row->product_type == 'variable') { $product_name .= ' - '.$row->product_variation.' - '.$row->variation_name; } return $product_name; }) ->editColumn('transaction_date', '{{@format_date($formated_date)}}') ->editColumn('total_qty_sold', function ($row) { return '<span data-is_quantity="true" class="display_currency sell_qty" data-currency_symbol=false data-orig-value="'.(float) $row->total_qty_sold.'" data-unit="'.$row->unit.'" >'.(float) $row->total_qty_sold.'</span> '.$row->unit; }) ->editColumn('current_stock', function ($row) { if ($row->enable_stock) { return '<span data-is_quantity="true" class="display_currency current_stock" data-currency_symbol=false data-orig-value="'.(float) $row->current_stock.'" data-unit="'.$row->unit.'" >'.(float) $row->current_stock.'</span> '.$row->unit; } else { return ''; } }) ->editColumn('subtotal', function ($row) { $class = is_null($row->parent_sell_line_id) ? 'row_subtotal' : ''; return '<span class="'.$class.'" data-orig-value="'.$row->subtotal.'">'. $this->transactionUtil->num_f($row->subtotal, true).'</span>'; }) ->rawColumns(['current_stock', 'subtotal', 'total_qty_sold']) ->make(true); } } /** * Shows product sell report grouped by date * * @return \Illuminate\Http\Response */ public function productSellReportBy(Request $request) { if (! auth()->user()->can('purchase_n_sell_report.view')) { abort(403, 'Unauthorized action.'); } $business_id = $request->session()->get('user.business_id'); $location_id = $request->get('location_id', null); $group_by = $request->get('group_by', null); $vld_str = ''; if (! empty($location_id)) { $vld_str = "AND vld.location_id=$location_id"; } if ($request->ajax()) { $query = TransactionSellLine::join( 'transactions as t', 'transaction_sell_lines.transaction_id', '=', 't.id' ) ->leftjoin( 'products as p', 'transaction_sell_lines.product_id', '=', 'p.id' ) ->leftjoin('categories as cat', 'p.category_id', '=', 'cat.id') ->leftjoin('brands as b', 'p.brand_id', '=', 'b.id') ->where('t.business_id', $business_id) ->where('t.type', 'sell') ->where('t.status', 'final') ->select( 'b.name as brand_name', 'cat.name as category_name', DB::raw("(SELECT SUM(vld.qty_available) FROM variation_location_details as vld WHERE vld.variation_id=transaction_sell_lines.variation_id $vld_str) as current_stock"), DB::raw('SUM(transaction_sell_lines.quantity - transaction_sell_lines.quantity_returned) as total_qty_sold'), DB::raw('SUM((transaction_sell_lines.quantity - transaction_sell_lines.quantity_returned) * transaction_sell_lines.unit_price_inc_tax) as subtotal'), 'transaction_sell_lines.parent_sell_line_id' ); if ($group_by == 'category') { $query->groupBy('cat.id'); } elseif ($group_by == 'brand') { $query->groupBy('b.id'); } $start_date = $request->get('start_date'); $end_date = $request->get('end_date'); if (! empty($start_date) && ! empty($end_date)) { $query->where('t.transaction_date', '>=', $start_date) ->where('t.transaction_date', '<=', $end_date); } $permitted_locations = auth()->user()->permitted_locations(); if ($permitted_locations != 'all') { $query->whereIn('t.location_id', $permitted_locations); } if (! empty($location_id)) { $query->where('t.location_id', $location_id); } $customer_id = $request->get('customer_id', null); if (! empty($customer_id)) { $query->where('t.contact_id', $customer_id); } $customer_group_id = $request->get('customer_group_id', null); if (! empty($customer_group_id)) { $query->leftjoin('contacts AS c', 't.contact_id', '=', 'c.id') ->leftjoin('customer_groups AS CG', 'c.customer_group_id', '=', 'CG.id') ->where('CG.id', $customer_group_id); } $category_id = $request->get('category_id', null); if (! empty($category_id)) { $query->where('p.category_id', $category_id); } $brand_id = $request->get('brand_id', null); if (! empty($brand_id)) { $query->where('p.brand_id', $brand_id); } return Datatables::of($query) ->editColumn('category_name', '{{$category_name ?? __("lang_v1.uncategorized")}}') ->editColumn('brand_name', '{{$brand_name ?? __("lang_v1.no_brand")}}') ->editColumn('total_qty_sold', function ($row) { return '<span data-is_quantity="true" class="display_currency sell_qty" data-currency_symbol=false data-orig-value="'.(float) $row->total_qty_sold.'" data-unit="" >'.(float) $row->total_qty_sold.'</span> '.$row->unit; }) ->editColumn('current_stock', function ($row) { return '<span data-is_quantity="true" class="display_currency current_stock" data-currency_symbol=false data-orig-value="'.(float) $row->current_stock.'" data-unit="">'.(float) $row->current_stock.'</span> '; }) ->editColumn('subtotal', function ($row) { $class = is_null($row->parent_sell_line_id) ? 'row_subtotal' : ''; return '<span class="'.$class.'" data-orig-value="'.$row->subtotal.'">' .$this->transactionUtil->num_f($row->subtotal, true).'</span>'; }) ->rawColumns(['current_stock', 'subtotal', 'total_qty_sold', 'category_name']) ->make(true); } } /** * Shows product stock details and allows to adjust mismatch * * @return \Illuminate\Http\Response */ public function productStockDetails() { if (! auth()->user()->can('report.stock_details')) { abort(403, 'Unauthorized action.'); } $business_id = request()->session()->get('user.business_id'); $variation_id = request()->get('variation_id', null); $location_id = request()->input('location_id'); $location = null; $stock_details = []; if (! empty(request()->input('location_id'))) { $location = BusinessLocation::where('business_id', $business_id) ->where('id', $location_id) ->first(); $stock_details = $this->productUtil->getVariationStockMisMatch($business_id, $variation_id, $location_id); } $business_locations = BusinessLocation::forDropdown($business_id); return view('report.product_stock_details') ->with(compact('stock_details', 'business_locations', 'location')); } /** * Adjusts stock availability mismatch if found * * @return \Illuminate\Http\Response */ public function adjustProductStock() { if (! auth()->user()->can('report.stock_details')) { abort(403, 'Unauthorized action.'); } if (! empty(request()->input('variation_id')) && ! empty(request()->input('location_id')) && request()->has('stock')) { $business_id = request()->session()->get('user.business_id'); $this->productUtil->fixVariationStockMisMatch($business_id, request()->input('variation_id'), request()->input('location_id'), request()->input('stock')); } return redirect()->back()->with(['status' => [ 'success' => 1, 'msg' => __('lang_v1.updated_succesfully'), ]]); } /** * Retrieves line orders/sales * * @return obj */ public function serviceStaffLineOrders() { $business_id = request()->session()->get('user.business_id'); $query = TransactionSellLine::leftJoin('transactions as t', 't.id', '=', 'transaction_sell_lines.transaction_id') ->leftJoin('variations as v', 'transaction_sell_lines.variation_id', '=', 'v.id') ->leftJoin('products as p', 'v.product_id', '=', 'p.id') ->leftJoin('units as u', 'p.unit_id', '=', 'u.id') ->leftJoin('product_variations as pv', 'v.product_variation_id', '=', 'pv.id') ->leftJoin('users as ss', 'ss.id', '=', 'transaction_sell_lines.res_service_staff_id') ->leftjoin( 'business_locations AS bl', 't.location_id', '=', 'bl.id' ) ->where('t.business_id', $business_id) ->where('t.type', 'sell') ->where('t.status', 'final') ->whereNotNull('transaction_sell_lines.res_service_staff_id'); if (! empty(request()->service_staff_id)) { $query->where('transaction_sell_lines.res_service_staff_id', request()->service_staff_id); } if (request()->has('location_id')) { $location_id = request()->get('location_id'); if (! empty($location_id)) { $query->where('t.location_id', $location_id); } } if (! empty(request()->start_date) && ! empty(request()->end_date)) { $start = request()->start_date; $end = request()->end_date; $query->whereDate('t.transaction_date', '>=', $start) ->whereDate('t.transaction_date', '<=', $end); } $query->select( 'p.name as product_name', 'p.type as product_type', 'v.name as variation_name', 'pv.name as product_variation_name', 'u.short_name as unit', 't.id as transaction_id', 'bl.name as business_location', 't.transaction_date', 't.invoice_no', 'transaction_sell_lines.quantity', 'transaction_sell_lines.unit_price_before_discount', 'transaction_sell_lines.line_discount_type', 'transaction_sell_lines.line_discount_amount', 'transaction_sell_lines.item_tax', 'transaction_sell_lines.unit_price_inc_tax', DB::raw('CONCAT(COALESCE(ss.first_name, ""), COALESCE(ss.last_name, "")) as service_staff') ); $datatable = Datatables::of($query) ->editColumn('product_name', function ($row) { $name = $row->product_name; if ($row->product_type == 'variable') { $name .= ' - '.$row->product_variation_name.' - '.$row->variation_name; } return $name; }) ->editColumn( 'unit_price_inc_tax', '<span class="display_currency unit_price_inc_tax" data-currency_symbol="true" data-orig-value="{{$unit_price_inc_tax}}">{{$unit_price_inc_tax}}</span>' ) ->editColumn( 'item_tax', '<span class="display_currency item_tax" data-currency_symbol="true" data-orig-value="{{$item_tax}}">{{$item_tax}}</span>' ) ->editColumn( 'quantity', '<span class="display_currency quantity" data-unit="{{$unit}}" data-currency_symbol="false" data-orig-value="{{$quantity}}">{{$quantity}}</span> {{$unit}}' ) ->editColumn( 'unit_price_before_discount', '<span class="display_currency unit_price_before_discount" data-currency_symbol="true" data-orig-value="{{$unit_price_before_discount}}">{{$unit_price_before_discount}}</span>' ) ->addColumn( 'total', '<span class="display_currency total" data-currency_symbol="true" data-orig-value="{{$unit_price_inc_tax * $quantity}}">{{$unit_price_inc_tax * $quantity}}</span>' ) ->editColumn( 'line_discount_amount', function ($row) { $discount = ! empty($row->line_discount_amount) ? $row->line_discount_amount : 0; if (! empty($discount) && $row->line_discount_type == 'percentage') { $discount = $row->unit_price_before_discount * ($discount / 100); } return '<span class="display_currency total-discount" data-currency_symbol="true" data-orig-value="'.$discount.'">'.$discount.'</span>'; } ) ->editColumn('transaction_date', '{{@format_date($transaction_date)}}') ->rawColumns(['line_discount_amount', 'unit_price_before_discount', 'item_tax', 'unit_price_inc_tax', 'item_tax', 'quantity', 'total']) ->make(true); return $datatable; } /** * Lists profit by product, category, brand, location, invoice and date * * @return string $by = null */ public function getProfit($by = null) { $business_id = request()->session()->get('user.business_id'); $query = TransactionSellLine::join('transactions as sale', 'transaction_sell_lines.transaction_id', '=', 'sale.id') ->leftjoin('transaction_sell_lines_purchase_lines as TSPL', 'transaction_sell_lines.id', '=', 'TSPL.sell_line_id') ->leftjoin( 'purchase_lines as PL', 'TSPL.purchase_line_id', '=', 'PL.id' ) ->where('sale.type', 'sell') ->where('sale.status', 'final') ->join('products as P', 'transaction_sell_lines.product_id', '=', 'P.id') ->where('sale.business_id', $business_id) ->where('transaction_sell_lines.children_type', '!=', 'combo'); //If type combo: find childrens, sale price parent - get PP of childrens $query->select(DB::raw('SUM(IF (TSPL.id IS NULL AND P.type="combo", ( SELECT Sum((tspl2.quantity - tspl2.qty_returned) * (tsl.unit_price_inc_tax - pl2.purchase_price_inc_tax)) AS total FROM transaction_sell_lines AS tsl JOIN transaction_sell_lines_purchase_lines AS tspl2 ON tsl.id=tspl2.sell_line_id JOIN purchase_lines AS pl2 ON tspl2.purchase_line_id = pl2.id WHERE tsl.parent_sell_line_id = transaction_sell_lines.id), IF(P.enable_stock=0,(transaction_sell_lines.quantity - transaction_sell_lines.quantity_returned) * transaction_sell_lines.unit_price_inc_tax, (TSPL.quantity - TSPL.qty_returned) * (transaction_sell_lines.unit_price_inc_tax - PL.purchase_price_inc_tax)) )) AS gross_profit') ); $permitted_locations = auth()->user()->permitted_locations(); if ($permitted_locations != 'all') { $query->whereIn('sale.location_id', $permitted_locations); } if (! empty(request()->location_id)) { $query->where('sale.location_id', request()->location_id); } if (! empty(request()->start_date) && ! empty(request()->end_date)) { $start = request()->start_date; $end = request()->end_date; $query->whereDate('sale.transaction_date', '>=', $start) ->whereDate('sale.transaction_date', '<=', $end); } if ($by == 'product') { $query->join('variations as V', 'transaction_sell_lines.variation_id', '=', 'V.id') ->leftJoin('product_variations as PV', 'PV.id', '=', 'V.product_variation_id') ->addSelect(DB::raw("IF(P.type='variable', CONCAT(P.name, ' - ', PV.name, ' - ', V.name, ' (', V.sub_sku, ')'), CONCAT(P.name, ' (', P.sku, ')')) as product")) ->groupBy('V.id'); } if ($by == 'category') { $query->join('variations as V', 'transaction_sell_lines.variation_id', '=', 'V.id') ->leftJoin('categories as C', 'C.id', '=', 'P.category_id') ->addSelect('C.name as category') ->groupBy('C.id'); } if ($by == 'brand') { $query->join('variations as V', 'transaction_sell_lines.variation_id', '=', 'V.id') ->leftJoin('brands as B', 'B.id', '=', 'P.brand_id') ->addSelect('B.name as brand') ->groupBy('B.id'); } if ($by == 'location') { $query->join('business_locations as L', 'sale.location_id', '=', 'L.id') ->addSelect('L.name as location') ->groupBy('L.id'); } if ($by == 'invoice') { $query->addSelect( 'sale.invoice_no', 'sale.id as transaction_id', 'sale.discount_type', 'sale.discount_amount', 'sale.total_before_tax' ) ->groupBy('sale.invoice_no'); } if ($by == 'date') { $query->addSelect('sale.transaction_date') ->groupBy(DB::raw('DATE(sale.transaction_date)')); } if ($by == 'day') { $results = $query->addSelect(DB::raw('DAYNAME(sale.transaction_date) as day')) ->groupBy(DB::raw('DAYOFWEEK(sale.transaction_date)')) ->get(); $profits = []; foreach ($results as $result) { $profits[strtolower($result->day)] = $result->gross_profit; } $days = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday']; return view('report.partials.profit_by_day')->with(compact('profits', 'days')); } if ($by == 'customer') { $query->join('contacts as CU', 'sale.contact_id', '=', 'CU.id') ->addSelect('CU.name as customer', 'CU.supplier_business_name') ->groupBy('sale.contact_id'); } $datatable = Datatables::of($query); if (in_array($by, ['invoice'])) { $datatable->editColumn('gross_profit', function ($row) { $discount = $row->discount_amount; if ($row->discount_type == 'percentage') { $discount = ($row->discount_amount * $row->total_before_tax) / 100; } $profit = $row->gross_profit - $discount; $html = '<span class="gross-profit" data-orig-value="'.$profit.'" >'.$this->transactionUtil->num_f($profit, true).'</span>'; return $html; }); } else { $datatable->editColumn( 'gross_profit', function ($row) { return '<span class="gross-profit" data-orig-value="'.$row->gross_profit.'">'.$this->transactionUtil->num_f($row->gross_profit, true).'</span>'; }); } if ($by == 'category') { $datatable->editColumn( 'category', '{{$category ?? __("lang_v1.uncategorized")}}' ); } if ($by == 'brand') { $datatable->editColumn( 'brand', '{{$brand ?? __("report.others")}}' ); } if ($by == 'date') { $datatable->editColumn('transaction_date', '{{@format_date($transaction_date)}}'); } if ($by == 'product') { $datatable->filterColumn( 'product', function ($query, $keyword) { $query->whereRaw("IF(P.type='variable', CONCAT(P.name, ' - ', PV.name, ' - ', V.name, ' (', V.sub_sku, ')'), CONCAT(P.name, ' (', P.sku, ')')) LIKE '%{$keyword}%'"); }); } $raw_columns = ['gross_profit']; if ($by == 'customer') { $datatable->editColumn('customer', '@if(!empty($supplier_business_name)) {{$supplier_business_name}}, <br> @endif {{$customer}}'); $raw_columns[] = 'customer'; } if ($by == 'invoice') { $datatable->editColumn('invoice_no', function ($row) { return '<a data-href="'.action([\App\Http\Controllers\SellController::class, 'show'], [$row->transaction_id]) .'" href="#" data-container=".view_modal" class="btn-modal">'.$row->invoice_no.'</a>'; }); $raw_columns[] = 'invoice_no'; } return $datatable->rawColumns($raw_columns) ->make(true); } /** * Shows items report from sell purchase mapping table * * @return \Illuminate\Http\Response */ public function itemsReport() { $business_id = request()->session()->get('user.business_id'); if (request()->ajax()) { $query = TransactionSellLinesPurchaseLines::leftJoin('transaction_sell_lines as SL', 'SL.id', '=', 'transaction_sell_lines_purchase_lines.sell_line_id') ->leftJoin('stock_adjustment_lines as SAL', 'SAL.id', '=', 'transaction_sell_lines_purchase_lines.stock_adjustment_line_id') ->leftJoin('transactions as sale', 'SL.transaction_id', '=', 'sale.id') ->leftJoin('transactions as stock_adjustment', 'SAL.transaction_id', '=', 'stock_adjustment.id') ->join('purchase_lines as PL', 'PL.id', '=', 'transaction_sell_lines_purchase_lines.purchase_line_id') ->join('transactions as purchase', 'PL.transaction_id', '=', 'purchase.id') ->join('business_locations as bl', 'purchase.location_id', '=', 'bl.id') ->join( 'variations as v', 'PL.variation_id', '=', 'v.id' ) ->join('product_variations as pv', 'v.product_variation_id', '=', 'pv.id') ->join('products as p', 'PL.product_id', '=', 'p.id') ->join('units as u', 'p.unit_id', '=', 'u.id') ->leftJoin('contacts as suppliers', 'purchase.contact_id', '=', 'suppliers.id') ->leftJoin('contacts as customers', 'sale.contact_id', '=', 'customers.id') ->where('purchase.business_id', $business_id) ->select( 'v.sub_sku as sku', 'p.type as product_type', 'p.name as product_name', 'v.name as variation_name', 'pv.name as product_variation', 'u.short_name as unit', 'purchase.transaction_date as purchase_date', 'purchase.ref_no as purchase_ref_no', 'purchase.type as purchase_type', 'purchase.id as purchase_id', 'suppliers.name as supplier', 'suppliers.supplier_business_name', 'PL.purchase_price_inc_tax as purchase_price', 'sale.transaction_date as sell_date', 'stock_adjustment.transaction_date as stock_adjustment_date', 'sale.invoice_no as sale_invoice_no', 'stock_adjustment.ref_no as stock_adjustment_ref_no', 'customers.name as customer', 'customers.supplier_business_name as customer_business_name', 'transaction_sell_lines_purchase_lines.quantity as quantity', 'SL.unit_price_inc_tax as selling_price', 'SAL.unit_price as stock_adjustment_price', 'transaction_sell_lines_purchase_lines.stock_adjustment_line_id', 'transaction_sell_lines_purchase_lines.sell_line_id', 'transaction_sell_lines_purchase_lines.purchase_line_id', 'transaction_sell_lines_purchase_lines.qty_returned', 'bl.name as location', 'SL.sell_line_note', 'PL.lot_number' ); $permitted_locations = auth()->user()->permitted_locations(); if ($permitted_locations != 'all') { $query->whereIn('purchase.location_id', $permitted_locations); } if (! empty(request()->purchase_start) && ! empty(request()->purchase_end)) { $start = request()->purchase_start; $end = request()->purchase_end; $query->whereDate('purchase.transaction_date', '>=', $start) ->whereDate('purchase.transaction_date', '<=', $end); } if (! empty(request()->sale_start) && ! empty(request()->sale_end)) { $start = request()->sale_start; $end = request()->sale_end; $query->where(function ($q) use ($start, $end) { $q->where(function ($qr) use ($start, $end) { $qr->whereDate('sale.transaction_date', '>=', $start) ->whereDate('sale.transaction_date', '<=', $end); })->orWhere(function ($qr) use ($start, $end) { $qr->whereDate('stock_adjustment.transaction_date', '>=', $start) ->whereDate('stock_adjustment.transaction_date', '<=', $end); }); }); } $supplier_id = request()->get('supplier_id', null); if (! empty($supplier_id)) { $query->where('suppliers.id', $supplier_id); } $customer_id = request()->get('customer_id', null); if (! empty($customer_id)) { $query->where('customers.id', $customer_id); } $location_id = request()->get('location_id', null); if (! empty($location_id)) { $query->where('purchase.location_id', $location_id); } $only_mfg_products = request()->get('only_mfg_products', 0); if (! empty($only_mfg_products)) { $query->where('purchase.type', 'production_purchase'); } return Datatables::of($query) ->editColumn('product_name', function ($row) { $product_name = $row->product_name; if ($row->product_type == 'variable') { $product_name .= ' - '.$row->product_variation.' - '.$row->variation_name; } return $product_name; }) ->editColumn('purchase_date', '{{@format_datetime($purchase_date)}}') ->editColumn('purchase_ref_no', function ($row) { $html = $row->purchase_type == 'purchase' ? '<a data-href="'.action([\App\Http\Controllers\PurchaseController::class, 'show'], [$row->purchase_id]) .'" href="#" data-container=".view_modal" class="btn-modal">'.$row->purchase_ref_no.'</a>' : $row->purchase_ref_no; if ($row->purchase_type == 'opening_stock') { $html .= '('.__('lang_v1.opening_stock').')'; } return $html; }) ->editColumn('purchase_price', function ($row) { return '<span class="purchase_price" data-orig-value="'.$row->purchase_price.'">'. $this->transactionUtil->num_f($row->purchase_price, true).'</span>'; }) ->editColumn('sell_date', '@if(!empty($sell_line_id)) {{@format_datetime($sell_date)}} @else {{@format_datetime($stock_adjustment_date)}} @endif') ->editColumn('sale_invoice_no', function ($row) { $invoice_no = ! empty($row->sell_line_id) ? $row->sale_invoice_no : $row->stock_adjustment_ref_no.'<br><small>('.__('stock_adjustment.stock_adjustment').'</small)>'; return $invoice_no; }) ->editColumn('quantity', function ($row) { $html = '<span data-is_quantity="true" class="display_currency quantity" data-currency_symbol=false data-orig-value="'.(float) $row->quantity.'" data-unit="'.$row->unit.'" >'.(float) $row->quantity.'</span> '.$row->unit; if (empty($row->sell_line_id)) { $html .= '<br><small>('.__('stock_adjustment.stock_adjustment').'</small)>'; } if ($row->qty_returned > 0) { $html .= '<small><i>(<span data-is_quantity="true" class="display_currency" data-currency_symbol=false>'.(float) $row->quantity.'</span> '.$row->unit.' '.__('lang_v1.returned').')</i></small>'; } return $html; }) ->editColumn('selling_price', function ($row) { $selling_price = ! empty($row->sell_line_id) ? $row->selling_price : $row->stock_adjustment_price; return '<span class="row_selling_price" data-orig-value="'.$selling_price. '">'.$this->transactionUtil->num_f($selling_price, true).'</span>'; }) ->addColumn('subtotal', function ($row) { $selling_price = ! empty($row->sell_line_id) ? $row->selling_price : $row->stock_adjustment_price; $subtotal = $selling_price * $row->quantity; return '<span class="row_subtotal" data-orig-value="'.$subtotal.'">'. $this->transactionUtil->num_f($subtotal, true).'</span>'; }) ->editColumn('supplier', '@if(!empty($supplier_business_name)) {{$supplier_business_name}},<br> @endif {{$supplier}}') ->editColumn('customer', '@if(!empty($customer_business_name)) {{$customer_business_name}},<br> @endif {{$customer}}') ->filterColumn('sale_invoice_no', function ($query, $keyword) { $query->where('sale.invoice_no', 'like', ["%{$keyword}%"]) ->orWhere('stock_adjustment.ref_no', 'like', ["%{$keyword}%"]); }) ->rawColumns(['subtotal', 'selling_price', 'quantity', 'purchase_price', 'sale_invoice_no', 'purchase_ref_no', 'supplier', 'customer']) ->make(true); } $suppliers = Contact::suppliersDropdown($business_id, false); $customers = Contact::customersDropdown($business_id, false); $business_locations = BusinessLocation::forDropdown($business_id); return view('report.items_report')->with(compact('suppliers', 'customers', 'business_locations')); } /** * Shows purchase report * * @return \Illuminate\Http\Response */ public function purchaseReport() { if ((! auth()->user()->can('purchase.view') && ! auth()->user()->can('purchase.create') && ! auth()->user()->can('view_own_purchase')) || empty(config('constants.show_report_606'))) { abort(403, 'Unauthorized action.'); } $business_id = request()->session()->get('user.business_id'); if (request()->ajax()) { $payment_types = $this->transactionUtil->payment_types(null, true, $business_id); $purchases = Transaction::leftJoin('contacts', 'transactions.contact_id', '=', 'contacts.id') ->join( 'business_locations AS BS', 'transactions.location_id', '=', 'BS.id' ) ->leftJoin( 'transaction_payments AS TP', 'transactions.id', '=', 'TP.transaction_id' ) ->where('transactions.business_id', $business_id) ->where('transactions.type', 'purchase') ->with(['payment_lines']) ->select( 'transactions.id', 'transactions.ref_no', 'contacts.name', 'contacts.contact_id', 'final_total', 'total_before_tax', 'discount_amount', 'discount_type', 'tax_amount', DB::raw('DATE_FORMAT(transaction_date, "%Y/%m") as purchase_year_month'), DB::raw('DATE_FORMAT(transaction_date, "%d") as purchase_day') ) ->groupBy('transactions.id'); $permitted_locations = auth()->user()->permitted_locations(); if ($permitted_locations != 'all') { $purchases->whereIn('transactions.location_id', $permitted_locations); } if (! empty(request()->supplier_id)) { $purchases->where('contacts.id', request()->supplier_id); } if (! empty(request()->location_id)) { $purchases->where('transactions.location_id', request()->location_id); } if (! empty(request()->input('payment_status')) && request()->input('payment_status') != 'overdue') { $purchases->where('transactions.payment_status', request()->input('payment_status')); } elseif (request()->input('payment_status') == 'overdue') { $purchases->whereIn('transactions.payment_status', ['due', 'partial']) ->whereNotNull('transactions.pay_term_number') ->whereNotNull('transactions.pay_term_type') ->whereRaw("IF(transactions.pay_term_type='days', DATE_ADD(transactions.transaction_date, INTERVAL transactions.pay_term_number DAY) < CURDATE(), DATE_ADD(transactions.transaction_date, INTERVAL transactions.pay_term_number MONTH) < CURDATE())"); } if (! empty(request()->status)) { $purchases->where('transactions.status', request()->status); } if (! empty(request()->start_date) && ! empty(request()->end_date)) { $start = request()->start_date; $end = request()->end_date; $purchases->whereDate('transactions.transaction_date', '>=', $start) ->whereDate('transactions.transaction_date', '<=', $end); } if (! auth()->user()->can('purchase.view') && auth()->user()->can('view_own_purchase')) { $purchases->where('transactions.created_by', request()->session()->get('user.id')); } return Datatables::of($purchases) ->removeColumn('id') ->editColumn( 'final_total', '<span class="display_currency final_total" data-currency_symbol="true" data-orig-value="{{$final_total}}">{{$final_total}}</span>' ) ->editColumn( 'total_before_tax', '<span class="display_currency total_before_tax" data-currency_symbol="true" data-orig-value="{{$total_before_tax}}">{{$total_before_tax}}</span>' ) ->editColumn( 'tax_amount', '<span class="display_currency tax_amount" data-currency_symbol="true" data-orig-value="{{$tax_amount}}">{{$tax_amount}}</span>' ) ->editColumn( 'discount_amount', function ($row) { $discount = ! empty($row->discount_amount) ? $row->discount_amount : 0; if (! empty($discount) && $row->discount_type == 'percentage') { $discount = $row->total_before_tax * ($discount / 100); } return '<span class="display_currency total-discount" data-currency_symbol="true" data-orig-value="'.$discount.'">'.$discount.'</span>'; } ) ->addColumn('payment_year_month', function ($row) { $year_month = ''; if (! empty($row->payment_lines->first())) { $year_month = \Carbon::parse($row->payment_lines->first()->paid_on)->format('Y/m'); } return $year_month; }) ->addColumn('payment_day', function ($row) { $payment_day = ''; if (! empty($row->payment_lines->first())) { $payment_day = \Carbon::parse($row->payment_lines->first()->paid_on)->format('d'); } return $payment_day; }) ->addColumn('payment_method', function ($row) use ($payment_types) { $methods = array_unique($row->payment_lines->pluck('method')->toArray()); $count = count($methods); $payment_method = ''; if ($count == 1) { $payment_method = $payment_types[$methods[0]]; } elseif ($count > 1) { $payment_method = __('lang_v1.checkout_multi_pay'); } $html = ! empty($payment_method) ? '<span class="payment-method" data-orig-value="'.$payment_method.'" data-status-name="'.$payment_method.'">'.$payment_method.'</span>' : ''; return $html; }) ->setRowAttr([ 'data-href' => function ($row) { if (auth()->user()->can('purchase.view')) { return action([\App\Http\Controllers\PurchaseController::class, 'show'], [$row->id]); } else { return ''; } }, ]) ->rawColumns(['final_total', 'total_before_tax', 'tax_amount', 'discount_amount', 'payment_method']) ->make(true); } $business_locations = BusinessLocation::forDropdown($business_id); $suppliers = Contact::suppliersDropdown($business_id, false); $orderStatuses = $this->productUtil->orderStatuses(); return view('report.purchase_report') ->with(compact('business_locations', 'suppliers', 'orderStatuses')); } /** * Shows sale report * * @return \Illuminate\Http\Response */ public function saleReport() { if ((! auth()->user()->can('sell.view') && ! auth()->user()->can('sell.create') && ! auth()->user()->can('direct_sell.access') && ! auth()->user()->can('view_own_sell_only')) || empty(config('constants.show_report_607'))) { abort(403, 'Unauthorized action.'); } $business_id = request()->session()->get('user.business_id'); $business_locations = BusinessLocation::forDropdown($business_id, false); $customers = Contact::customersDropdown($business_id, false); return view('report.sale_report') ->with(compact('business_locations', 'customers')); } /** * Calculates stock values * * @return array */ public function getStockValue() { $business_id = request()->session()->get('user.business_id'); $end_date = \Carbon::now()->format('Y-m-d'); $location_id = request()->input('location_id'); $filters = request()->only(['category_id', 'sub_category_id', 'brand_id', 'unit_id']); $permitted_locations = auth()->user()->permitted_locations(); //Get Closing stock $closing_stock_by_pp = $this->transactionUtil->getOpeningClosingStock( $business_id, $end_date, $location_id, false, false, $filters, $permitted_locations ); $closing_stock_by_sp = $this->transactionUtil->getOpeningClosingStock( $business_id, $end_date, $location_id, false, true, $filters, $permitted_locations ); $potential_profit = $closing_stock_by_sp - $closing_stock_by_pp; $profit_margin = empty($closing_stock_by_sp) ? 0 : ($potential_profit / $closing_stock_by_sp) * 100; return [ 'closing_stock_by_pp' => $closing_stock_by_pp, 'closing_stock_by_sp' => $closing_stock_by_sp, 'potential_profit' => $potential_profit, 'profit_margin' => $profit_margin, ]; } public function activityLog() { $business_id = request()->session()->get('user.business_id'); $transaction_types = [ 'contact' => __('report.contact'), 'user' => __('report.user'), 'sell' => __('sale.sale'), 'purchase' => __('lang_v1.purchase'), 'sales_order' => __('lang_v1.sales_order'), 'purchase_order' => __('lang_v1.purchase_order'), 'sell_return' => __('lang_v1.sell_return'), 'purchase_return' => __('lang_v1.purchase_return'), 'sell_transfer' => __('lang_v1.stock_transfer'), 'stock_adjustment' => __('stock_adjustment.stock_adjustment'), 'expense' => __('lang_v1.expense'), ]; if (request()->ajax()) { $activities = Activity::with(['subject']) ->leftjoin('users as u', 'u.id', '=', 'activity_log.causer_id') ->where('activity_log.business_id', $business_id) ->select( 'activity_log.*', DB::raw("CONCAT(COALESCE(u.surname, ''), ' ', COALESCE(u.first_name, ''), ' ', COALESCE(u.last_name, '')) as created_by") ); if (! empty(request()->start_date) && ! empty(request()->end_date)) { $start = request()->start_date; $end = request()->end_date; $activities->whereDate('activity_log.created_at', '>=', $start) ->whereDate('activity_log.created_at', '<=', $end); } if (! empty(request()->user_id)) { $activities->where('causer_id', request()->user_id); } $subject_type = request()->subject_type; if (! empty($subject_type)) { if ($subject_type == 'contact') { $activities->where('subject_type', \App\Contact::class); } elseif ($subject_type == 'user') { $activities->where('subject_type', \App\User::class); } elseif (in_array($subject_type, ['sell', 'purchase', 'sales_order', 'purchase_order', 'sell_return', 'purchase_return', 'sell_transfer', 'expense', 'purchase_order', ])) { $activities->where('subject_type', \App\Transaction::class); $activities->whereHasMorph('subject', Transaction::class, function ($q) use ($subject_type) { $q->where('type', $subject_type); }); } } $sell_statuses = Transaction::sell_statuses(); $sales_order_statuses = Transaction::sales_order_statuses(true); $purchase_statuses = $this->transactionUtil->orderStatuses(); $shipping_statuses = $this->transactionUtil->shipping_statuses(); $statuses = array_merge($sell_statuses, $sales_order_statuses, $purchase_statuses); return Datatables::of($activities) ->editColumn('created_at', '{{@format_datetime($created_at)}}') ->addColumn('subject_type', function ($row) use ($transaction_types) { $subject_type = ''; if ($row->subject_type == \App\Contact::class) { $subject_type = __('contact.contact'); } elseif ($row->subject_type == \App\User::class) { $subject_type = __('report.user'); } elseif ($row->subject_type == \App\Transaction::class && ! empty($row->subject->type)) { $subject_type = isset($transaction_types[$row->subject->type]) ? $transaction_types[$row->subject->type] : ''; } elseif (($row->subject_type == \App\TransactionPayment::class)) { $subject_type = __('lang_v1.payment'); } return $subject_type; }) ->addColumn('note', function ($row) use ($statuses, $shipping_statuses) { $html = ''; if (! empty($row->subject->ref_no)) { $html .= __('purchase.ref_no').': '.$row->subject->ref_no.'<br>'; } if (! empty($row->subject->invoice_no)) { $html .= __('sale.invoice_no').': '.$row->subject->invoice_no.'<br>'; } if ($row->subject_type == \App\Transaction::class && ! empty($row->subject) && in_array($row->subject->type, ['sell', 'purchase'])) { $html .= view('sale_pos.partials.activity_row', ['activity' => $row, 'statuses' => $statuses, 'shipping_statuses' => $shipping_statuses])->render(); } else { $update_note = $row->getExtraProperty('update_note'); if (! empty($update_note) && ! is_array($update_note)) { $html .= $update_note; } } if ($row->description == 'contact_deleted') { $html .= $row->getExtraProperty('supplier_business_name') ?? ''; $html .= '<br>'; } if (! empty($row->getExtraProperty('name'))) { $html .= __('user.name').': '.$row->getExtraProperty('name').'<br>'; } if (! empty($row->getExtraProperty('id'))) { $html .= 'id: '.$row->getExtraProperty('id').'<br>'; } if (! empty($row->getExtraProperty('invoice_no'))) { $html .= __('sale.invoice_no').': '.$row->getExtraProperty('invoice_no'); } if (! empty($row->getExtraProperty('ref_no'))) { $html .= __('purchase.ref_no').': '.$row->getExtraProperty('ref_no'); } return $html; }) ->filterColumn('created_by', function ($query, $keyword) { $query->whereRaw("CONCAT(COALESCE(surname, ''), ' ', COALESCE(first_name, ''), ' ', COALESCE(last_name, '')) like ?", ["%{$keyword}%"]); }) ->editColumn('description', function ($row) { return __('lang_v1.'.$row->description); }) ->rawColumns(['note']) ->make(true); } $users = User::allUsersDropdown($business_id, false); return view('report.activity_log')->with(compact('users', 'transaction_types')); } public function gstSalesReport(Request $request) { if (! auth()->user()->can('tax_report.view') || empty(config('constants.enable_gst_report_india'))) { abort(403, 'Unauthorized action.'); } $business_id = $request->session()->get('user.business_id'); $taxes = TaxRate::where('business_id', $business_id) ->where('is_tax_group', 0) ->select(['id', 'name', 'amount']) ->get() ->toArray(); if ($request->ajax()) { $query = TransactionSellLine::join( 'transactions as t', 'transaction_sell_lines.transaction_id', '=', 't.id' ) ->join('contacts as c', 't.contact_id', '=', 'c.id') ->join('products as p', 'transaction_sell_lines.product_id', '=', 'p.id') ->leftjoin('categories as cat', 'p.category_id', '=', 'cat.id') ->leftjoin('tax_rates as tr', 'transaction_sell_lines.tax_id', '=', 'tr.id') ->leftjoin('units as u', 'p.unit_id', '=', 'u.id') ->where('t.business_id', $business_id) ->where('t.type', 'sell') ->where('t.status', 'final') ->select( 'c.name as customer', 'c.supplier_business_name', 'c.contact_id', 'c.tax_number', 'cat.short_code', 't.id as transaction_id', 't.invoice_no', 't.transaction_date as transaction_date', 'transaction_sell_lines.unit_price_before_discount as unit_price', 'transaction_sell_lines.unit_price as unit_price_after_discount', DB::raw('(transaction_sell_lines.quantity - transaction_sell_lines.quantity_returned) as sell_qty'), 'transaction_sell_lines.line_discount_type as discount_type', 'transaction_sell_lines.line_discount_amount as discount_amount', 'transaction_sell_lines.item_tax', 'tr.amount as tax_percent', 'tr.is_tax_group', 'transaction_sell_lines.tax_id', 'u.short_name as unit', 'transaction_sell_lines.parent_sell_line_id', DB::raw('((transaction_sell_lines.quantity- transaction_sell_lines.quantity_returned) * transaction_sell_lines.unit_price_inc_tax) as line_total'), ) ->groupBy('transaction_sell_lines.id'); $start_date = $request->get('start_date'); $end_date = $request->get('end_date'); if (! empty($start_date) && ! empty($end_date)) { $query->where('t.transaction_date', '>=', $start_date) ->where('t.transaction_date', '<=', $end_date); } $permitted_locations = auth()->user()->permitted_locations(); if ($permitted_locations != 'all') { $query->whereIn('t.location_id', $permitted_locations); } $location_id = $request->get('location_id', null); if (! empty($location_id)) { $query->where('t.location_id', $location_id); } $customer_id = $request->get('customer_id', null); if (! empty($customer_id)) { $query->where('t.contact_id', $customer_id); } $datatable = Datatables::of($query); $raw_cols = ['invoice_no', 'taxable_value', 'discount_amount', 'unit_price', 'tax', 'customer', 'line_total']; $group_taxes_array = TaxRate::groupTaxes($business_id); $group_taxes = []; foreach ($group_taxes_array as $group_tax) { foreach ($group_tax['sub_taxes'] as $sub_tax) { $group_taxes[$group_tax->id]['sub_taxes'][$sub_tax->id] = $sub_tax; } } foreach ($taxes as $tax) { $col = 'tax_'.$tax['id']; $raw_cols[] = $col; $datatable->addColumn($col, function ($row) use ($tax, $col, $group_taxes) { $sub_tax_share = 0; if ($row->is_tax_group == 1 && array_key_exists($tax['id'], $group_taxes[$row->tax_id]['sub_taxes'])) { $sub_tax_share = $this->transactionUtil->calc_percentage($row->unit_price_after_discount, $group_taxes[$row->tax_id]['sub_taxes'][$tax['id']]->amount) * $row->sell_qty; } if ($sub_tax_share > 0) { //ignore child sell line of combo product $class = is_null($row->parent_sell_line_id) ? $col : ''; return '<span class="'.$class.'" data-orig-value="'.$sub_tax_share.'">'.$this->transactionUtil->num_f($sub_tax_share).'</span>'; } else { return ''; } }); } return $datatable->addColumn('taxable_value', function ($row) { $taxable_value = $row->unit_price_after_discount * $row->sell_qty; //ignore child sell line of combo product $class = is_null($row->parent_sell_line_id) ? 'taxable_value' : ''; return '<span class="'.$class.'"data-orig-value="'.$taxable_value.'">'.$this->transactionUtil->num_f($taxable_value).'</span>'; }) ->editColumn('invoice_no', function ($row) { return '<a data-href="'.action([\App\Http\Controllers\SellController::class, 'show'], [$row->transaction_id]) .'" href="#" data-container=".view_modal" class="btn-modal">'.$row->invoice_no.'</a>'; }) ->editColumn('transaction_date', '{{@format_datetime($transaction_date)}}') ->editColumn('sell_qty', function ($row) { return $this->transactionUtil->num_f($row->sell_qty, false, null, true).' '.$row->unit; }) ->editColumn('unit_price', function ($row) { return '<span data-orig-value="'.$row->unit_price.'">'.$this->transactionUtil->num_f($row->unit_price).'</span>'; }) ->editColumn('line_total', function ($row) { return '<span data-orig-value="'.$row->line_total.'">'.$this->transactionUtil->num_f($row->line_total).'</span>'; }) ->editColumn( 'discount_amount', function ($row) { $discount = ! empty($row->discount_amount) ? $row->discount_amount : 0; if (! empty($discount) && $row->discount_type == 'percentage') { $discount = $row->unit_price * ($discount / 100); } return $this->transactionUtil->num_f($discount); } ) ->editColumn('tax_percent', '@if(!empty($tax_percent)){{@num_format($tax_percent)}}% @endif ') ->editColumn('customer', '@if(!empty($supplier_business_name)) {{$supplier_business_name}},<br>@endif {{$customer}}') ->rawColumns($raw_cols) ->make(true); } $customers = Contact::customersDropdown($business_id); return view('report.gst_sales_report')->with(compact('customers', 'taxes')); } public function gstPurchaseReport(Request $request) { if (! auth()->user()->can('tax_report.view') || empty(config('constants.enable_gst_report_india'))) { abort(403, 'Unauthorized action.'); } $business_id = $request->session()->get('user.business_id'); $taxes = TaxRate::where('business_id', $business_id) ->where('is_tax_group', 0) ->select(['id', 'name', 'amount']) ->get() ->toArray(); if ($request->ajax()) { $query = PurchaseLine::join( 'transactions as t', 'purchase_lines.transaction_id', '=', 't.id' ) ->join('contacts as c', 't.contact_id', '=', 'c.id') ->join('products as p', 'purchase_lines.product_id', '=', 'p.id') ->leftjoin('categories as cat', 'p.category_id', '=', 'cat.id') ->leftjoin('tax_rates as tr', 'purchase_lines.tax_id', '=', 'tr.id') ->leftjoin('units as u', 'p.unit_id', '=', 'u.id') ->where('t.business_id', $business_id) ->where('t.type', 'purchase') ->where('t.status', 'received') ->select( 'c.name as supplier', 'c.supplier_business_name', 'c.contact_id', 'c.tax_number', 'cat.short_code', 't.id as transaction_id', 't.ref_no', 't.transaction_date as transaction_date', 'purchase_lines.pp_without_discount as unit_price', 'purchase_lines.purchase_price as unit_price_after_discount', DB::raw('(purchase_lines.quantity - purchase_lines.quantity_returned) as purchase_qty'), 'purchase_lines.discount_percent', 'purchase_lines.item_tax', 'tr.amount as tax_percent', 'tr.is_tax_group', 'purchase_lines.tax_id', 'u.short_name as unit', DB::raw('((purchase_lines.quantity- purchase_lines.quantity_returned) * purchase_lines.purchase_price_inc_tax) as line_total') ) ->groupBy('purchase_lines.id'); $start_date = $request->get('start_date'); $end_date = $request->get('end_date'); if (! empty($start_date) && ! empty($end_date)) { $query->where('t.transaction_date', '>=', $start_date) ->where('t.transaction_date', '<=', $end_date); } $permitted_locations = auth()->user()->permitted_locations(); if ($permitted_locations != 'all') { $query->whereIn('t.location_id', $permitted_locations); } $location_id = $request->get('location_id', null); if (! empty($location_id)) { $query->where('t.location_id', $location_id); } $supplier_id = $request->get('supplier_id', null); if (! empty($supplier_id)) { $query->where('t.contact_id', $supplier_id); } $datatable = Datatables::of($query); $raw_cols = ['ref_no', 'taxable_value', 'discount_amount', 'unit_price', 'tax', 'supplier', 'line_total']; $group_taxes_array = TaxRate::groupTaxes($business_id); $group_taxes = []; foreach ($group_taxes_array as $group_tax) { foreach ($group_tax['sub_taxes'] as $sub_tax) { $group_taxes[$group_tax->id]['sub_taxes'][$sub_tax->id] = $sub_tax; } } foreach ($taxes as $tax) { $col = 'tax_'.$tax['id']; $raw_cols[] = $col; $datatable->addColumn($col, function ($row) use ($tax, $group_taxes) { $sub_tax_share = 0; if ($row->is_tax_group == 1 && array_key_exists($tax['id'], $group_taxes[$row->tax_id]['sub_taxes'])) { $sub_tax_share = $this->transactionUtil->calc_percentage($row->unit_price_after_discount, $group_taxes[$row->tax_id]['sub_taxes'][$tax['id']]->amount) * $row->purchase_qty; } if ($sub_tax_share > 0) { return '<span data-orig-value="'.$sub_tax_share.'">'.$this->transactionUtil->num_f($sub_tax_share).'</span>'; } else { return ''; } }); } return $datatable->addColumn('taxable_value', function ($row) { $taxable_value = $row->unit_price_after_discount * $row->purchase_qty; return '<span class="taxable_value"data-orig-value="'.$taxable_value.'">'.$this->transactionUtil->num_f($taxable_value).'</span>'; }) ->editColumn('ref_no', function ($row) { return '<a data-href="'.action([\App\Http\Controllers\PurchaseController::class, 'show'], [$row->transaction_id]) .'" href="#" data-container=".view_modal" class="btn-modal">'.$row->ref_no.'</a>'; }) ->editColumn('transaction_date', '{{@format_datetime($transaction_date)}}') ->editColumn('purchase_qty', function ($row) { return $this->transactionUtil->num_f($row->purchase_qty, false, null, true).' '.$row->unit; }) ->editColumn('unit_price', function ($row) { return '<span data-orig-value="'.$row->unit_price.'">'.$this->transactionUtil->num_f($row->unit_price).'</span>'; }) ->editColumn('line_total', function ($row) { return '<span data-orig-value="'.$row->line_total.'">'.$this->transactionUtil->num_f($row->line_total).'</span>'; }) ->addColumn( 'discount_amount', function ($row) { $discount = ! empty($row->discount_percent) ? $row->discount_percent : 0; if (! empty($discount)) { $discount = $row->unit_price * ($discount / 100); } return $this->transactionUtil->num_f($discount); } ) ->editColumn('tax_percent', '@if(!empty($tax_percent)){{@num_format($tax_percent)}}% @endif ') ->editColumn('supplier', '@if(!empty($supplier_business_name)) {{$supplier_business_name}},<br>@endif {{$supplier}}') ->rawColumns($raw_cols) ->make(true); } $suppliers = Contact::suppliersDropdown($business_id); return view('report.gst_purchase_report')->with(compact('suppliers', 'taxes')); } }