/**
  * Function that uses a reservation. It creates a transaction for the remainder of the money and makes the sale.
  *
  * @return Response
  */
 public function useReservation()
 {
     // Validate Input.
     $validator = Validator::make(Input::all(), array('id' => 'required'));
     if ($validator->fails()) {
         return response()->json(['error' => 'No se recibieron los datos necesarios!']);
     }
     // Check that user is part of authorized staff.
     if (Auth::user()->Type != 1) {
         $response['state'] = 'No Autorizado';
         $response['error'] = 'Usuario no autorizado!';
         return response()->json($response);
     }
     // Get user branch.
     $worker = Worker::find(Auth::user()->TypeId);
     $userBranch = $worker->BranchId;
     $salePrice = 0;
     // Get the cashbox.
     $cashbox = Cashbox::where('UserId', '=', Auth::user()->Id)->where('Close', '=', NULL)->first();
     // Check that we actually have a cashbox open.
     if (!$cashbox) {
         $response['state'] = 'Error';
         $response['error'] = 'La caja no esta abierta o por lo tanto no se puede realizar la transaccion!';
         return response()->json($response);
     }
     // Get the reservation.
     $reservation = Reservation::find(Input::get('id'));
     // Make sure the reservation hasn't been used yet.
     if ($reservation->State == 'used' || $reservation->State == 'credit') {
         $response['state'] = 'Error';
         $response['error'] = 'Esta reservacion ya ha sido utilizada!';
         return response()->json($response);
     }
     // Now make sure the reservation hasn't been deleted.
     if ($reservation->State == 'delete') {
         $response['state'] = 'Error';
         $response['error'] = 'Esta reservacion fue eliminada!';
         return response()->json($response);
     }
     // Now make sure the reservation hasn't expired.
     if ($reservation->State == 'late') {
         $response['state'] = 'Error';
         $response['error'] = 'Esta reservacion ya ha expirado!';
         return response()->json($response);
     }
     // Get the reservation breakdown.
     $reservationBreakdown = ReservationBreakdown::where('ReservationId', '=', Input::get('id'))->get();
     // Loop through all items.
     foreach ($reservationBreakdown as $breakdown) {
         // Check if it is a product.
         $product = Stock::where('Code', '=', $breakdown->Code)->where('BranchId', '=', $userBranch)->first();
         if (!$product) {
             // Check if it is a service.
             $service = Service::where('Code', '=', $breakdown->Code)->where('BranchId', '=', $userBranch)->first();
             if (!$service) {
                 $response['state'] = 'Error';
                 $response['error'] = 'No se reconocio uno de los productos o servicios!';
                 return response()->json($response);
             }
             // Make sure there are enough materials in system and withdraw them.
             $materials = json_decode($service->Materials);
             foreach ($materials as $materialCode => $quantity) {
                 $stock = Stock::where('Code', '=', $materialCode)->where('BranchId', '=', $userBranch);
                 // If we have enough in stock withdraw it.
                 if ($stock->Quantity >= $quantity * $breakdown->Quantity) {
                     $stock->Quantity -= $quantity * $breakdown->Quantity;
                     $stock->save();
                 } else {
                     // Return all items and materials withdrawn so far.
                     $this->returnItems($reservationBreakdown, $breakdown->Code);
                     $response['state'] = 'Error';
                     $response['error'] = 'No hay suficientes materiales o productos!';
                     return response()->json($response);
                 }
             }
             // TODO: Check if any special functions need to be executed.
         } else {
             // Check quantity being taken is not greater than existing quantity in system.
             if ($product->Quantity >= $breakdown->Quantity) {
                 // Reduce products from stock.
                 $product->Quantity -= $breakdown->Quantity;
                 $product->save();
             } else {
                 // Return all items and materials withdrawn so far.
                 $this->returnItems($reservationBreakdown, $breakdown->Code);
                 $response['state'] = 'Error';
                 $response['info'] = $breakdown;
                 $response['product'] = $product;
                 $response['error'] = 'No hay suficientes materiales o productos!';
                 return response()->json($response);
             }
         }
     }
     // Make transaction for remaining reservation debt.
     $transaction = CashboxTransaction::create(array('CashboxId' => $cashbox->Id, 'DateTime' => date('Y-m-d H:i:s'), 'Type' => 1, 'Amount' => $reservation->Value + $reservation->Tax - $reservation->Discount - $reservation->Deposit, 'Reason' => 'Venta con Reservacion.'));
     // Make sale.
     $sale;
     // TODO: Payment can also be with credit card.
     $sale = Sale::create(array('WorkerId' => $worker->Id, 'Value' => $reservation->Value - $reservation->Discount, 'Tax' => $reservation->Tax, 'Card' => false, 'TransactionId' => $transaction->Id, 'BranchId' => $userBranch, 'Credit' => 0, 'CreditorId' => $reservation->CreditorId, 'CreditorType' => $reservation->CreditorType, 'Cancelled' => 1));
     // Now add sales breakdown.
     foreach ($reservationBreakdown as $breakdown) {
         // Check if product.
         $product = Stock::where('Code', '=', $breakdown->Code)->where('BranchId', '=', $userBranch)->first();
         if (!$product) {
             // Get service cost.
             $service = Service::where('Code', '=', $breakdown->Code)->where('BranchId', '=', $userBranch)->first();
             $materials = json_decode($service->Materials);
             $cost = 0;
             foreach ($materials as $materialCode => $quantity) {
                 $material = Stock::where('Code', '=', $materialCode)->where('BranchId', '=', $userBranch)->first();
                 $cost += $material->AverageCost * $quantity;
             }
             SaleBreakdown::create(array('SaleId' => $sale->Id, 'Code' => $breakdown->Code, 'Quantity' => $breakdown->Quantity, 'Cost' => $cost * $breakdown->Quantity, 'Price' => $breakdown->Price));
         } else {
             SaleBreakdown::create(array('SaleId' => $sale->Id, 'Code' => $breakdown->Code, 'Quantity' => $breakdown->Quantity, 'Cost' => $product->AverageCost * $breakdown->Quantity, 'Price' => $breakdown->Price));
         }
     }
     // Now update the reservation.
     $reservation->State = 'used';
     $reservation->save();
     $response['state'] = 'Success';
     $response['saleId'] = $sale->Id;
     // Return response.
     return response()->json($response);
 }
Пример #2
0
 /**
  * Function that pays tab with a cash transaction.
  *
  * @return Response
  */
 public function payBill()
 {
     // Validate Input.
     $validator = Validator::make(Input::all(), array('items' => 'required', 'institution' => 'required', 'discount' => 'required', 'card' => 'required', 'credit' => 'required', 'authCode' => 'required'));
     $response = array();
     if ($validator->fails()) {
         $response['state'] = 'Error';
         $response['error'] = 'No se proporciono toda la informacion necesaria para realizar transaccion!';
         return response()->json($response);
     }
     // Check that user is part of authorized staff.
     if (Auth::user()->Type != 1) {
         // If they are unauthorized no point in returning anything.
         return response()->json(array());
     }
     // Get user branch.
     $worker = Worker::find(Auth::user()->TypeId);
     $userBranch = $worker->BranchId;
     $branch = Branch::find($userBranch);
     $salePrice = 0;
     // Get the cashbox.
     $cashbox = Cashbox::where('UserId', '=', Auth::user()->Id)->where('Close', '=', NULL)->first();
     // Check that we actually have a cashbox open.
     if (!$cashbox) {
         $response['state'] = 'Error';
         $response['error'] = 'La caja no esta abierta o por lo tanto no se puede realizar la transaccion!';
         return response()->json($response);
     }
     // Check discount is not greater than what user is allowed.
     $permissions = json_decode(UserLevel::find(Auth::user()->UserLevel)->Permissions);
     if (Input::get('discount') > $permissions->permissions->sales->discount->limit) {
         // Check if we have an auth code we can use.
         if (Input::get('authCode') == 0) {
             $response['state'] = 'Error';
             $response['error'] = 'No tiene permiso para otorgar este descuento!';
             return response()->json($response);
         }
         $request = Request::find(Input::get('authCode'));
         if ($request->Used == 1) {
             $response['state'] = 'Error';
             $response['error'] = 'No tiene permiso para otorgar este descuento!';
             return response()->json($response);
         }
         if ($request->Amount != Input::get('discount')) {
             $response['state'] = 'Error';
             $response['error'] = 'No tiene permiso para otorgar este descuento!';
             return response()->json($response);
         }
         $request->Used = 1;
         $request->save();
     }
     // Get client.
     $client = Client::where('Cedula', '=', Input::get('client'))->first();
     // Get institution if defined.
     $institution;
     if (Input::get('institution') != 0) {
         $institution = Institution::find(Input::get('institution'));
         if (!$institution) {
             $response['state'] = 'Error';
             $response['error'] = 'La institucion definida no fue encontrada en el sistema!';
             return response()->json($response);
         }
     }
     // Loop through all items.
     $items = json_decode(Input::get('items'));
     foreach ($items as $code => $info) {
         // Check if it is a product.
         $product = Stock::where('Code', '=', $code)->where('BranchId', '=', $userBranch)->first();
         if (!$product) {
             // Check if it is a service.
             $service = Service::where('Code', '=', $code)->where('BranchId', '=', $userBranch)->first();
             if (!$service) {
                 $response['state'] = 'Error';
                 $response['error'] = 'No se reconocio uno de los productos o servicios!';
                 return response()->json($response);
             }
             // Make sure there are enough materials in system and withdraw them.
             $materials = json_decode($service->Materials);
             foreach ($materials as $materialCode => $quantity) {
                 $stock = Stock::where('Code', '=', $materialCode)->where('BranchId', '=', $userBranch)->first();
                 // If we have enough in stock withdraw it.
                 if ($stock->Quantity >= $quantity * $info->quantity) {
                     $stock->Quantity -= $quantity * $info->quantity;
                     $stock->save();
                 } else {
                     // Return all items and materials withdrawn so far.
                     $this->returnItems($items, $code);
                     $response['state'] = 'Error';
                     $response['error'] = 'No hay suficientes materiales o productos!';
                     return response()->json($response);
                 }
             }
             // Add price to total of factura.
             $salePrice += $service->Price * $info->quantity;
             // TODO: Check if any special functions need to be executed.
         } else {
             // Check quantity being taken is not greater than existing quantity in system.
             if ($product->Quantity >= $info->quantity) {
                 // Reduce products from stock.
                 $product->Quantity -= $info->quantity;
                 $product->save();
             } else {
                 // Return all items and materials withdrawn so far.
                 $this->returnItems($items, $code);
                 $response['state'] = 'Error';
                 $response['error'] = 'No hay suficientes materiales o productos!';
                 return response()->json($response);
             }
             // Add price to total of factura.
             $salePrice += $product->Price * $info->quantity;
         }
     }
     $subTotal = $salePrice;
     $discount = $salePrice * (Input::get('discount') / 100);
     // Give discount.
     $salePrice = $salePrice * (1 - Input::get('discount') / 100);
     // Calculate tax if required.
     $tax = 0;
     if (json_decode($branch->DefaultExpenses)->regimen == 'cuotageneral') {
         if (Input::get('institution') != 0) {
             if (!$institution->Excempt) {
                 $tax = $salePrice * 0.15;
             }
         } else {
             if (!$client || !$client->Excempt) {
                 $tax = $salePrice * 0.15;
             }
         }
     }
     // Save client information.
     $clientInfo = array();
     if (Input::get('institution') != 0) {
         // Save institution information.
         $clientInfo = array('Name' => $institution->Name, 'Address' => $institution->Address, 'Id' => $institution->RUC);
     } else {
         // Save institution information.
         if ($client) {
             $clientInfo = array('Name' => $client->Name, 'Address' => $client->Address, 'Id' => $client->Cedula);
         }
     }
     // Check if credit that creditor has enough credit available,
     // otherwise check that enough cash is being paid.
     $change = 0;
     if (Input::get('credit') == 1) {
         if (Input::get('institution') != 0) {
             // Get institution debt.
             $debt = 0;
             $pendingBills = Sale::where('CreditorId', '=', $institution->Id)->where('CreditorType', '=', 2)->where('Cancelled', '=', false)->get();
             foreach ($pendingBills as $pendingBill) {
                 $debt += $pendingBill->Value + $pendingBill->Tax;
             }
             // Check they have enough credit available.
             if ($debt + $salePrice + $tax > $institution->CreditLimit) {
                 $this->returnItems($items, '');
                 $response['state'] = 'Error';
                 $response['error'] = 'Esta institucion no tiene suficiente credito disponible para cancelar esta factura!';
                 return response()->json($response);
             }
         } else {
             if (!$client) {
                 $response['state'] = 'Error';
                 $response['error'] = 'No se definio un cliente para asignar factura a credito!';
                 return response()->json($response);
             }
             // Get client debt.
             $debt = 0;
             $pendingBills = Sale::where('CreditorId', '=', $client->Id)->where('CreditorType', '=', 1)->where('Cancelled', '=', false);
             foreach ($pendingBills as $pendingBill) {
                 $debt += $pendingBill->Value + $pendingBill->Tax;
             }
             // Check they have enough credit available.
             if ($debt + $salePrice + $tax > $client->CreditLimit) {
                 $this->returnItems($items, '');
                 $response['state'] = 'Error';
                 $response['error'] = 'Este cliente no tiene suficiente credito disponible para cancelar esta factura!';
                 return response()->json($response);
             }
         }
     } else {
         // Check enough cash is being paid.
         $change = Input::get('cash') - ($salePrice + $tax);
         if ($change < 0) {
             $this->returnItems($items, '');
             $response['state'] = 'Error';
             $response['error'] = 'Debe pagar con un valor igual o mayor al costo de lo facturado!';
             return response()->json($response);
         }
     }
     // Make cashbox transaction.
     $transaction;
     if (Input::get('credit') == 1) {
         $transaction = CashboxTransaction::create(array('CashboxId' => $cashbox->Id, 'DateTime' => date('Y-m-d H:i:s'), 'Type' => 10, 'Amount' => $salePrice + $tax, 'Reason' => 'Venta de Credito.'));
     } else {
         $transaction = CashboxTransaction::create(array('CashboxId' => $cashbox->Id, 'DateTime' => date('Y-m-d H:i:s'), 'Type' => 1, 'Amount' => $salePrice + $tax, 'Reason' => 'Venta.'));
     }
     // Make sale.
     $card = 0;
     if (Input::get('card') != 0) {
         $config = Configuration::find(0);
         $card = $salePrice * ($config->POS / 100);
     }
     $sale;
     $type = 'contado';
     if (Input::get('credit') == 1) {
         $type = 'credito';
         if (Input::get('institution') != 0) {
             // Creditor Type 1 = Client, 2 = Institution.
             $sale = Sale::create(array('WorkerId' => $worker->Id, 'Value' => $salePrice, 'Tax' => $tax, 'Card' => $card, 'TransactionId' => $transaction->Id, 'BranchId' => $userBranch, 'Credit' => 1, 'CreditorId' => Input::get('institution'), 'CreditorType' => 2, 'Cancelled' => 0));
         } else {
             $sale = Sale::create(array('WorkerId' => $worker->Id, 'Value' => $salePrice, 'Tax' => $tax, 'Card' => $card, 'TransactionId' => $transaction->Id, 'BranchId' => $userBranch, 'Credit' => 1, 'CreditorId' => $client->Id, 'CreditorType' => 1, 'Cancelled' => 0));
         }
     } else {
         if (Input::get('institution') != 0) {
             // Creditor Type 1 = Client, 2 = Institution.
             $sale = Sale::create(array('WorkerId' => $worker->Id, 'Value' => $salePrice, 'Tax' => $tax, 'Card' => $card, 'TransactionId' => $transaction->Id, 'BranchId' => $userBranch, 'Credit' => 0, 'CreditorId' => Input::get('institution'), 'CreditorType' => 2, 'Cancelled' => 1));
         } else {
             if (!$client) {
                 $sale = Sale::create(array('WorkerId' => $worker->Id, 'Value' => $salePrice, 'Tax' => $tax, 'Card' => $card, 'TransactionId' => $transaction->Id, 'BranchId' => $userBranch, 'Credit' => 0, 'CreditorId' => 0, 'CreditorType' => 1, 'Cancelled' => 1));
             } else {
                 $sale = Sale::create(array('WorkerId' => $worker->Id, 'Value' => $salePrice, 'Tax' => $tax, 'Card' => $card, 'TransactionId' => $transaction->Id, 'BranchId' => $userBranch, 'Credit' => 0, 'CreditorId' => $client->Id, 'CreditorType' => 1, 'Cancelled' => 1));
             }
         }
     }
     // Now add sales breakdown.
     foreach ($items as $code => $info) {
         // Check if product.
         $product = Stock::where('Code', '=', $code)->where('BranchId', '=', $userBranch)->first();
         if (!$product) {
             // Get service cost.
             $service = Service::where('Code', '=', $code)->where('BranchId', '=', $userBranch)->first();
             $materials = json_decode($service->Materials);
             $cost = 0;
             foreach ($materials as $materialCode => $quantity) {
                 $material = Stock::where('Code', '=', $materialCode)->where('BranchId', '=', $userBranch)->first();
                 $cost += $material->AverageCost * $quantity;
             }
             SaleBreakdown::create(array('SaleId' => $sale->Id, 'Code' => $code, 'Quantity' => $info->quantity, 'Cost' => $cost, 'Price' => $service->Price));
         } else {
             SaleBreakdown::create(array('SaleId' => $sale->Id, 'Code' => $code, 'Quantity' => $info->quantity, 'Cost' => $product->AverageCost, 'Price' => $product->Price));
         }
     }
     // Return success message and bill information.
     $response['state'] = 'Success';
     $response['change'] = $change;
     $response['billInfo'] = array('SubTotal' => $subTotal, 'Discount' => $discount, 'Tax' => $tax, 'Total' => $salePrice + $tax, 'SaleId' => $sale->Id, 'Date' => date('d/m/Y'), 'Type' => $type);
     $response['clientInfo'] = $clientInfo;
     $response['total'] = $salePrice + $tax;
     return response()->json($response);
 }
Пример #3
0
 public function updateStockTakeData()
 {
     // Validate Input.
     $validator = Validator::make(Input::all(), array('stocktake' => 'required'));
     if ($validator->fails()) {
         return response()->json(['error' => 'Informacion incompleta!']);
     }
     // Check that user is part of authorized staff.
     if (Auth::user()->Type != 1) {
         // If they are unauthorized no point in returning anything.
         return response()->json(array());
     }
     // Get the branch of the current worker.
     $worker = Worker::find(Auth::user()->TypeId);
     $branchId = $worker->BranchId;
     $cashbox = Cashbox::where('BranchId', '=', $branchId)->where('Close', '=', null)->where('UserId', '=', Auth::user()->Id)->first();
     if (!$cashbox) {
         $response['state'] = 'Error';
         $response['error'] = 'Es necesario tener la caja abierta para realizar esta accion!';
         return response()->json($response);
     }
     // Let's loop through the stocktake breakdown and start making necessary changes.
     foreach (Input::get('stocktake') as $item) {
         $breakdown = StockTakeBreakdown::find($item['id']);
         // Compare current state to submitted state and that difference is more or less than 0.
         if ($breakdown->State != $item['state'] && $breakdown->Difference != 0) {
             // If we are changing state make sure to undo any previous changes if we have to.
             if ($breakdown->State > 1 && $breakdown->State < 4) {
                 if ($breakdown->State == 2) {
                     // Get the salebreakdown.
                     $salebreakdown = SaleBreakdown::find(json_decode($breakdown->ExtraData)->salebreakdownId);
                     // Now the sale.
                     $sale = Sale::find($salebreakdown->SaleId);
                     // Now the transaction.
                     $transaction = CashboxTransaction::find($sale->TransactionId);
                     // Now delete them all.
                     $transaction->delete();
                     $sale->delete();
                     $salebreakdown->delete();
                     $breakdown->ExtraData = '';
                     $breakdown->save();
                 }
                 $product = Stock::where('Code', '=', $breakdown->Code)->where('BranchId', '=', $branchId)->first();
                 $product->Quantity -= $breakdown->Difference;
                 $product->save();
             }
             // Make changes.
             if ($item['state'] == 2) {
                 // Get the product.
                 $product = Stock::where('Code', '=', $breakdown->Code)->where('BranchId', '=', $branchId)->first();
                 // Now make the sale.
                 if ($breakdown->Difference > 0) {
                     // Make an empty transaction.
                     $transaction = CashboxTransaction::create(array('CashboxId' => $cashbox->Id, 'DateTime' => date('Y-m-d H:i:s'), 'Type' => 10, 'Amount' => 0, 'Reason' => 'Correccion de Inventario.'));
                     // Now make the sale so we can reflect the difference.
                     $sale = Sale::create(array('Created' => date('Y-m-d H:i:s'), 'WorkerId' => $worker->Id, 'Value' => 0, 'Tax' => 0, 'Card' => 0, 'TransactionId' => $transaction->Id, 'BranchId' => $branchId, 'Credit' => 0, 'CreditorId' => 0, 'CreditorType' => 1, 'Cancelled' => 1));
                     $salebreakdown = SaleBreakdown::create(array('SaleId' => $sale->Id, 'Code' => $breakdown->Code, 'Quantity' => -1 * $breakdown->Difference, 'Cost' => $product->AverageCost, 'Price' => 0, 'ExtraData' => json_encode(array('stocktakeBreakdownId' => $breakdown->Id))));
                     $product->Quantity += $breakdown->Difference;
                     $product->save();
                     $breakdown->ExtraData = json_encode(array('salebreakdownId' => $salebreakdown->Id));
                     $breakdown->save();
                 } else {
                     if ($breakdown->Difference < 0) {
                         // Make an empty transaction.
                         $transaction = CashboxTransaction::create(array('CashboxId' => $cashbox->Id, 'DateTime' => date('Y-m-d H:i:s'), 'Type' => 10, 'Amount' => 0, 'Reason' => 'Correccion de Inventario.'));
                         // Now make the sale so we can reflect the difference.
                         $sale = Sale::create(array('Created' => date('Y-m-d H:i:s'), 'WorkerId' => $worker->Id, 'Value' => 0, 'Tax' => 0, 'Card' => 0, 'TransactionId' => $transaction->Id, 'BranchId' => $branchId, 'Credit' => 0, 'CreditorId' => 0, 'CreditorType' => 1, 'Cancelled' => 1));
                         $salebreakdown = SaleBreakdown::create(array('SaleId' => $sale->Id, 'Code' => $breakdown->Code, 'Quantity' => -1 * $breakdown->Difference, 'Cost' => $product->AverageCost, 'Price' => 0, 'ExtraData' => json_encode(array('stocktakeBreakdownId' => $breakdown->Id))));
                         $product->Quantity += $breakdown->Difference;
                         $product->save();
                         $breakdown->ExtraData = json_encode(array('salebreakdownId' => $salebreakdown->Id));
                         $breakdown->save();
                     }
                 }
             } else {
                 if ($item['state'] == 3) {
                     // Get the product.
                     $product = Stock::where('Code', '=', $breakdown->Code)->where('BranchId', '=', $branchId)->first();
                     $product->Quantity += $breakdown->Difference;
                     $product->save();
                 }
             }
         }
         // Now update breakdown State.
         $breakdown->State = $item['state'];
         $breakdown->save();
     }
     $response['state'] = 'Success';
     return response()->json($response);
 }