KOKINIO - MANAGER
Edit File: VentaController.php
<?php namespace App\Http\Controllers; use App\Banco; use Illuminate\Http\Request; use App\Venta; use App\Producto; use App\Cliente; use App\Comision; use App\ComisionPago; use App\Factura; use App\FacturaPago; use App\FormaPago; use Facturapi\Facturapi; use Validator; use Uuid; use Auth; use App\Helper; use App\Http\Controllers\PremioClienteController; use App\Http\Controllers\ComisionesController; use App\Http\Controllers\ComisionPagoController; use Carbon\Carbon; use DateTime; use stdClass; class VentaController extends Controller { protected $facturapi; private $ACTIVE_PAID_PRICE = 0.01; public function __construct(Facturapi $facturapi) { $this->facturapi = $facturapi; } public function index($limit = null) { $clientesI = new Cliente(); $clientes = $clientesI->Clientes(); $venta = new Venta(); $formaPago = FormaPago::where('status_id', 1)->get(); $banco = Banco::where('status_id', 1)->get(); $year = null; $month = null; $cliente = null; $pagination = null; $pagoComision = []; if (Helper::getRol() == Auth::user()->rol_id) { $ventas = $venta->VentasWithLimit($id = null, $limit); // $ventasAll = $venta->VentasAll(); $ventasCount = $venta->VentasCount(); $ventasPago = $venta->ventasAllPagos(); } else if (Helper::getRolOp() == Auth::user()->rol_id) { $ventas = $venta->VentasWithLimit($id = null, $limit, "vacio", $month, $year, Auth::user()->id); // $ventasAll = $venta->VentasAll($id = null,"vacio",$month, $year, Auth::user()->id); $ventasCount = $venta->VentasCount($id = null, "vacio", $month, $year, Auth::user()->id); $ventasPago = $venta->ventasAllPagos($id = null, "vacio", $month, $year, Auth::user()->id); } else { $cliente = Auth::user()->id; $ventas = $venta->VentasWithLimit($id = null, $limit, $cliente); // $ventasAll = $venta->VentasAll($id = null,$cliente); $ventasPago = $venta->ventasAllPagos($id = null, $cliente); $ventasCount = $venta->VentasCount($id = null, $cliente); } if ($ventasCount && $ventasCount[0]->total > 100) { $pagination = ceil($ventasCount[0]->total / 100); } $ventaCopy = []; $i = 0; $j = 0; $cantidad = $ventasCount[0]->cantidad ?? 0; $countVentas = $ventasCount[0]->total ?? 0; $productos = Producto::where('status_id', 1)->get(); $allVentas = Venta::where('status_id', 1)->get(); foreach ($allVentas as $venta) { $date = Carbon::parse($venta->fecha_venta); $years[] = $date->year; $months[] = $date->format('m'); } $years = array_values(array_unique($years)); $months = array_values(array_unique($months)); sort($years); sort($months); // $redes = new Venta(); // $years = $redes->monthYearVenta(); // $months = $redes->monthYearVenta(2021); $data = ['years' => $years, 'months' => $months]; return view('Catalogos.Venta')->with(compact('ventas', 'productos', 'clientes', 'data', 'cantidad', 'ventasPago', 'pagination', 'countVentas', 'formaPago', 'banco')); } public function getVentas(Request $request) { $data = $request->all(); $limit = $data['limit'] ?? null; $clientesI = new Cliente(); $clientes = $clientesI->Clientes(); $pagination = null; $venta = new Venta(); $year = $data['year'] ?? null; $month = $data['month'] ?? null; $pagoComision = []; if (Helper::getRol() == Auth::user()->rol_id) { $cliente = $data['cliente']; $ventasCount = $venta->VentasCount($id = null, $cliente, $month, $year); $ventas = $venta->VentasWithLimit($id = null, $limit, $cliente, $month, $year); // $ventasAll = $venta->ventasAll($id = null,$cliente, $month, $year); $ventasPago = $venta->ventasAllPagos($id = null, $cliente, $month, $year); } else if (Helper::getRolOp() == Auth::user()->rol_id) { $cliente = $data['cliente']; $ventas = $venta->VentasWithLimit($id = null, $limit, $cliente, $month, $year, Auth::user()->id); // $ventasAll = $venta->ventasAll($id = null,$cliente,$month, $year, Auth::user()->id); $ventasCount = $venta->VentasCount($id = null, $cliente, $month, $year, Auth::user()->id); $ventas = $venta->ventasAllPagos($id = null, $cliente, $month, $year, Auth::user()->id); } else { $cliente = Auth::user()->id; $ventas = $venta->VentasWithLimit($id = null, $limit, $cliente, $month, $year); // $ventasAll = $venta->ventasAll($id = null,$cliente,$month, $year); $ventasCount = $venta->VentasCount($id = null, $cliente, $month, $year); $ventas = $venta->ventasAllPagos($id = null, $cliente, $month, $year); } if ($ventasCount && $ventasCount[0]->total > 100) { $pagination = ceil($ventasCount[0]->total / 100); } $ventaCopy = []; $i = 0; $j = 0; $cantidad = $ventasCount[0]->cantidad ?? 0; $countVentas = $ventasCount[0]->total ?? 0; $productos = Producto::where('status_id', 1)->get(); $redes = new Venta(); $years = $redes->monthYearVenta(); $months = $redes->monthYearVenta(2021); $data = ['years' => $years, 'months' => $months]; return view('Catalogos.sectionVentaTable')->with(compact('ventas', 'productos', 'clientes', 'data', 'cantidad', 'ventasPago', 'pagination', 'countVentas')); } public function checkSomeComisiones($data) { $comision = new Comision(); $redes = new Venta(); $date = \DateTime::createFromFormat("Y-m-d", $data['fecha_venta']); for ($i = 1; $i <= 3; $i++) { if (($data['cliente_comision_' . $i] != 'vacio' && $data['cliente_comision_' . $i] != '' && $data['cliente_comision_' . $i] != null) || $data['cantidad_comision_' . $i]) { // $comisionResult = $comision->existComisionCantidad($data['id'], $data['cliente_comision_'.$i], $data['cantidad_comision_'.$i], $date->format('Y'), $date->format('m')); if (!$data['cliente_comision_' . $i]) return ['status' => false, 'message' => 'Debe seleccionar un usuario para usar la comision']; $comisionAvilable = $redes->Get_3_Months($data['cliente_comision_' . $i], $date->format('Y'), $date->format('m')); $clienteData = Cliente::find($data['cliente_comision_' . $i]); if ($data['cantidad_comision_' . $i] > $comisionAvilable[0]->comision) { return ['status' => false, 'message' => 'El cliente ' . $clienteData->nombre . ' ' . $clienteData->ape_p . ' no dispone de comisiones']; } } } return ['status' => true, 'message' => 'ok']; } public function getComisionAmount($data) { $comision = 0; for ($i = 1; $i <= 3; $i++) { $comision += $data['cantidad_comision_' . $i]; } return $comision; } public function generateArrayProducts($data){ $productos = Producto::where('status_id', 1)->get(); $productWithData = array_map(function ($item) use ($productos) { $producto = $productos->first(fn($p) => $p->id === $item['producto']); return [ 'producto_id' => $producto->id, 'descripcion' => $producto->descripcion, 'orden_activo' => $producto->orden_activo, 'clave_sat' => $producto->clave_sat, 'costo_mx' => $producto->costo_mx, 'cantidad' => $item['cantidad'], ]; }, $data['venta']); usort($productWithData, function ($a, $b) { return $a['orden_activo'] <=> $b['orden_activo']; }); return $productWithData; } public function calculateAmountInvoiceProduct($data) { $products = []; $comision = $this->getComisionAmount($data); $productWithData = $this->generateArrayProducts($data); if ($comision > 0) { $restComision = $comision; foreach($productWithData as $product) { $productObj = new stdClass(); $totalPaymentProduct = $product['cantidad'] * $product['costo_mx']; if ($comision >= $totalPaymentProduct) { $productObj->quantity = $product['cantidad']; $productObj->product = $this->generateProductObject($product); $restComision -= $totalPaymentProduct; $products[] = $productObj; } else { $productObj = new stdClass(); // when is not enough comision to pay the product needs to use rule of three $partOfProduct = round(($restComision/$totalPaymentProduct) * $product['cantidad'], 2); $cantidadPending = $product['cantidad'] - $partOfProduct; $productObj->quantity = $partOfProduct; $productObj->product = $this->generateProductObject($product); $products[] = $productObj; if ($cantidadPending > 0) { $productObj = new stdClass(); $productObj->quantity = $cantidadPending; $productObj->product = $this->generateProductObject($product, $cantidadPending * $product['costo_mx']); $products[] = $productObj; } } } } else { foreach ($productWithData as $product) { $productObj = new stdClass(); $productObj->quantity = $product['cantidad']; $productObj->product = $this->generateProductObject($product, $product['costo_mx']); $products[] = $productObj; } } return $products; } public function generateProductObject($product, $price = 0) { return [ "description" => $product['descripcion'], "product_key" => $product['clave_sat'], "price" => $price ? $price : $this->ACTIVE_PAID_PRICE, "sku" => $product['producto_id'], ]; } public function generateInvoiceFacturaApi($data, $formPayment, $customer) { $formPaymentSAT = FormaPago::find($formPayment[0]['paidInvoice']); $date = new DateTime( $data['fecha_venta']); $isoString = $date->format(DateTime::ATOM); $products = $this->calculateAmountInvoiceProduct($data); if ($data['id'] && $data['facturapi_id']) { return $this->facturapi->Invoices->update_draft($data['facturapi_id'], [ "customer" =>$data['invoice_type'] === 'invoice' ? $customer->factura_api_id : Cliente::where('rfc', 'XAXX010101000')->first()->factura_api_id, "items" => $products, "payment_form" => $formPaymentSAT->clave_sat, "payment_method" => "PUE", "folio_number" => $data['invoice_number'], "status" => "draft", "date"=> $isoString ]); } return $this->facturapi->Invoices->create([ "customer" =>$data['invoice_type'] === 'invoice' ? $customer->factura_api_id : Cliente::where('rfc', 'XAXX010101000')->first()->factura_api_id, "items" => $products, "payment_form" => $formPaymentSAT->clave_sat, "payment_method" => "PUE", "folio_number" => $data['invoice_number'], "use" => "D01", "status" => "draft", "date"=> $isoString ]); } public function generateInvoice($data) { $customer = Cliente::find($data['vendedor']); $formPayment = $data['formPayment']; $invoiceApi = $this->generateInvoiceFacturaApi($data, $formPayment, $customer); if (!$invoiceApi->id) { return ['status' => false, 'message' => 'Error al generar la factura SAT']; } if ($data['id']) { $invoice = Factura::find($data['id']); $invoice->updated_by = Auth::user()->id; } else { $invoice = new Factura(); $invoice->id = Uuid::generate()->string; $invoice->created_by = Auth::user()->id; } $invoice->cliente_id = $customer->id; $invoice->factura_api_id = $invoiceApi->id; $invoice->status = $invoiceApi->status; $invoice->total = $invoiceApi->total; $invoice->folio = $invoiceApi->folio_number; $invoice->tipo_factura = $data['invoice_type']; if ($invoice->save()) { foreach ($data['formPayment'] as $formPayment) { if ($formPayment["paidInvoice"]) { if ($formPayment["id"]) { $payment = FacturaPago::find($formPayment["id"]); $payment->updated_by = Auth::user()->id; } else { $payment = new FacturaPago(); $payment->id = Uuid::generate()->string; $payment->created_by = Auth::user()->id; } $payment->forma_pago_id = $formPayment["paidInvoice"]; $payment->factura_api_id = $invoiceApi->id; $payment->cantidad = $formPayment["price"]; $payment->referencia = $formPayment["reference"]; $payment->banco_id = $formPayment["bank"]; if (!$payment->save()) { return ['status' => false, 'message' => 'Error al guardar el pago']; } } } return ['status' => true, 'factura_api_id' => $invoiceApi->id]; } return ['status' => false, 'message' => 'Error al guardar la factura']; } public function guardar(Request $request) { $data = $request->all(); $checkComisiones = $this->checkSomeComisiones($data); if (!$checkComisiones['status']) return response()->json(['status' => $checkComisiones['status'], 'message' => $checkComisiones['message']]); // $premioCliente = new PremioClienteController(); $validacion = Validator::make( $data, array( 'vendedor' => 'required', 'venta' => 'required', 'formPayment.*.paidInvoice' => 'required', 'formPayment.*.price' => 'required', 'fecha_venta' => 'required', 'invoice_number' => 'required', 'invoice_type' => 'required' ), array( 'vendedor.required' => 'El vendedor es obligatorio', 'venta.required' => 'Debe haber productos en la venta', 'formPayment.*.paidInvoice.required' => 'El metodo de pago es obligatorio', 'formPayment.*.price.required' => 'El Pago es obligatorio', 'fecha_venta.required' => 'Se debe seleccionar una fecha', 'invoice_number.required' => 'El Folio de factura es obligatorio', 'invoice_type.required' => 'El Tipo de factura es obligatorio', ) ); if ($validacion->fails()) { return response()->json(['status' => false, 'message' => $validacion->messages()]); } if ($data['id'] == "0") { $responseInvoice = $this->generateInvoice($data); if (!$responseInvoice['status']) { return response()->json($responseInvoice); } foreach ($data['venta'] as $key => $value) { if ($value['cantidad'] == "" || $value['cantidad'] == 0) { return response()->json(['status' => false, 'message' => 'Error en una cantidad, esta vacia o en 0']); } else if ($value['producto'] == "") { return response()->json(['status' => false, 'message' => 'Error en un producto, esta vacio']); } else { $venta = new Venta(); $venta->id = Uuid::generate()->string; $venta->cliente_id = $data['vendedor']; $venta->fecha_venta = $data['fecha_venta']; $venta->comentario = $data['comentario']; $venta->cantidad = $value['cantidad']; $venta->producto_id = $value['producto']; $venta->total = $this->getTotal($value['cantidad'], $value['producto']); $venta->registro_id = Auth::user()->id; $venta->factura_api_id = $responseInvoice['factura_api_id']; if (Helper::getRol() == Auth::user()->rol_id) { $venta->approved = 1; $venta->approved_by = Auth::user()->id; } if (!$venta->save()) { return response()->json(['status' => false, 'message' => 'Error al registrar la venta']); } } } $mesage = "La venta ha sido creada exitosamente"; } else { $responseInvoice = $this->generateInvoice($data); if (!$responseInvoice['status']) { return response()->json($responseInvoice); } foreach ($data['venta'] as $key => $value) { if ($value['cantidad'] == "" || $value['cantidad'] == 0) { return response()->json(['status' => false, 'message' => 'Error en una cantidad, esta vacia o en 0']); } else if ($value['producto'] == "") { return response()->json(['status' => false, 'message' => 'Error en un producto, esta vacio']); } else { $venta = Venta::find($value['venta_id']); $venta->cliente_id = $data['vendedor']; $venta->comentario = $data['comentario']; $venta->fecha_venta = $data['fecha_venta']; $venta->cantidad = $value['cantidad']; $venta->producto_id = $value['producto']; $venta->total = $this->getTotal($value['cantidad'], $value['producto']); $venta->registro_id = Auth::user()->id; if (!$venta->save()) { return response()->json(['status' => false, 'message' => 'Error al registrar la venta']); } } } $mesage = "La venta ha sido actualizada correctamente"; } $saveComision = $this->saveComisionPago($data, $venta->id); if (!$saveComision['status']) return response()->json(['status' => $saveComision['status'], 'message' => $saveComision['message']]); // Arrglar premios //$premioCliente->clientePremio(); return response()->json(['status' => true, 'message' => $mesage, 'data' => $data]); } public function saveComisionPago($data, $venta_id) { // $comisionPago = new ComisionPagoController(); $comisiones = new ComisionesController(); for ($i = 1; $i <= 3; $i++) { if ($data['cliente_comision_' . $i] != 'vacio' && $data['cliente_comision_' . $i] != '' && $data['cliente_comision_' . $i] != null) { $pago = $comisiones->updateGastoComision($data['cliente_comision_' . $i], $venta_id, $data['cantidad_comision_' . $i]); // return $pago = $comisionPago->guardar($data['cliente_comision_'.$i], $venta_id, $data['cantidad_comision_'.$i]); if (!$pago['status']) { return ['status' => false, 'message' => 'Algo fallo en el guardado de Pago', 'data' => $data]; } } } return ['status' => true, 'message' => 'ok', 'data' => $data]; } public function deletePayment($id) { $invoicePayment = FacturaPago::find($id); $invoicePayment->status_id = 0; $invoicePayment->updated_by = Auth::user()->id; if(!$invoicePayment->save()) { return response()->json(['status' => false, 'message' => 'Error al eliminar el pago']); } return response()->json(['status' => true, 'message' => 'Pago eliminado correctamente']); } public function getTotal($cantidad, $producto) { // if (filter_var($isPaidActive, FILTER_VALIDATE_BOOLEAN)) return $cantidad * $this->ACTIVE_PAID_PRICE; $productos = Producto::find($producto); return $productos->costo_mx * $cantidad; } public function update(Request $request) { $id = $request->input('id'); $venta = new Venta(); $comisionPago = ComisionPago::select( 'comision_pago.id', 'comision_pago.venta_id', 'comision_pago.cliente_id', 'comision_pago.cantidad', 'cliente.registro', 'cliente.ape_p', 'cliente.nombre', 'cliente.ape_m' ) ->join('cliente', 'cliente.id', 'comision_pago.cliente_id') ->whereIn('venta_id', [$id])->where('comision_pago.status_id', 1)->get(); $ventas = $venta->ventasAll($id); $facturaPayment = FacturaPago::where('factura_api_id', $ventas[0]->factura_api_id)->get(); $invoice = Factura::where('factura_api_id', $ventas[0]->factura_api_id)->first(); return ['comisionPago' => $comisionPago, 'ventas' => $ventas, 'facturaPayment' => $facturaPayment, 'invoice' => $invoice, 'facturapi_id' => $ventas[0]->factura_api_id]; } public function delete(Request $request) { // $comisionPago = new ComisionPagoController(); $ids = $request->input('id'); $ventas = new Venta(); $venta = $ventas->ventasAll($ids); $factura_id = $venta[0]->factura_api_id; if ($factura_id) { $canceled_invoice = $this->facturapi->Invoices->cancel( $factura_id, [ "motive" => "02" ] ); if(!$canceled_invoice) { return response()->json(['status' => false, 'message' => 'Error al cancelar la factura']); } } foreach ($venta as $value) { $comisionPago = ComisionPago::where('venta_id', $value->id)->get(); if ($comisionPago) { foreach ($comisionPago as $comision) { $comision->status_id = 0; if (!$comision->save()) return response()->json(['status' => false, 'message' => 'Error al eliminar registro en comisiones']); } } $ventaById = Venta::find($value->id); $ventaById->status_id = 0; $ventaById->registro_id = Auth::user()->id; if (!$ventaById->save()) return response()->json(['status' => false, 'message' => 'Error al eliminar registro en venta']); } $invoice = Factura::where('factura_api_id', $factura_id)->first(); if ($invoice) { $invoice->status = 0; $invoice->updated_by = Auth::user()->id; if (!$invoice->save()) return response()->json(['status' => false, 'message' => 'Error al eliminar registro en factura']); } return response()->json(['status' => true, 'message' => 'Registro eliminado correctamente']); } public function section(Request $request) { $count = $request->input('count'); $productos = Producto::where('status_id', 1)->get(); return view('Catalogos.sectionVenta')->with(compact('productos', 'count')); } public function sectionFormPayment(Request $request) { $formPaymentCount = $request->input('formPaymentCount'); $formaPago = FormaPago::where('status_id', 1)->get(); $banco = Banco::where('status_id', 1)->get(); return view('Catalogos.sectionFormPayment')->with(compact('formaPago', 'banco', 'formPaymentCount')); } public function approve(Request $request) { $venta_id = $request->input('venta_id'); $venta = Venta::find($venta_id); $venta->approved = 1; $venta->approved_by = Auth::user()->id; if ($venta->save()) { return response()->json(['status' => true, 'message' => 'Registro aprovado correctamente']); } else { return response()->json(['status' => false, 'message' => 'Error al aprovar registro']); } } public function invoice(Request $request) { if (!$request->type) { $factura_id = Venta::find($request->id); $invoice_id = $factura_id->factura_api_id; } else { $invoice_id = $request->id; } $type = $request->type ?? 'zip'; switch ($type) { case 'pdf': $fileContent = $this->facturapi->Invoices->download_pdf($invoice_id); $contentType = "application/pdf"; break; case 'xml': $fileContent = $this->facturapi->Invoices->download_xml($invoice_id); $contentType = "application/xml"; // Verificar si es un Blob antes de convertirlo if (is_object($fileContent) && method_exists($fileContent, 'getContent')) { // Extraer el contenido del Blob $fileContent = $fileContent->getContent(); } // Asegurarse de que el contenido sea un string XML vĂ¡lido if (is_string($fileContent)) { $fileContent = mb_convert_encoding($fileContent, 'UTF-8', 'auto'); } else { throw new \Exception("Error: Invalid content returned for XML."); } break; default: $fileContent = $this->facturapi->Invoices->download_zip($invoice_id); $contentType = "application/zip"; break; } if (!$fileContent) { return response()->json(["error" => "No se pudo descargar el archivo."], 500); } return response($fileContent, 200) ->header("Content-Type", $contentType) ->header("Content-Disposition", "attachment; filename=factura_{$invoice_id}.{$type}") ->header("Cache-Control", "no-cache, no-store, must-revalidate") ->header("Pragma", "no-cache") ->header("Expires", "0"); } public function stamp(Request $request) { $invoice_id = $request->input('id'); $date = $request->input('fecha_venta'); $invoice = Factura::find($invoice_id); $date = new DateTime( $date); $isoString = $date->format(DateTime::ATOM); $updateInvoice = $this->facturapi->Invoices->update_draft($invoice->factura_api_id, [ "date" => $isoString ]); $stampInvoice = $this->facturapi->Invoices->stamp_draft($updateInvoice->id); $invoice->status = $stampInvoice->status; if ($invoice->save()) { return response()->json(['status' => true, 'message' => 'Factura timbrada correctamente']); } else { return response()->json(['status' => false, 'message' => 'Error al timbrar factura']); } } }