/** * * Permite dar conocer al sistema las verdaderas existencias en un almacen, o sucursal. * * @param inventario json [{id_producto: 1,id_unidad: 2,cantidad: 0,id_lote : 2}] * @param id_sucursal int * */ static function Fisico($inventario, $id_sucursal = "") { //POS.API.POST("api/inventario/fisico", {inventario : Ext.JSON.encode([{id_producto:8, id_unidad:1, cantidad:7, id_lote:1}]) } , {callback:function(){}}) $s = SesionController::Actual(); Logger::log("---------- INVENTARIO FISICO SE ENCONTRARON " . count($inventario) . " AJUSTES ----------"); foreach ($inventario as $producto) { //self::ajustarLoteProducto($producto->id_lote, $producto->id_producto, $producto->id_unidad); //[{id_producto: 1,id_unidad: 2,cantidad: 0,id_lote : 2}] $producto->nombre = ProductoDAO::getByPK($producto->id_producto)->getNombreProducto(); Logger::log(" Estamos en {$producto->nombre}, id_unidad {$producto->id_unidad}, {$producto->cantidad} " . UnidadMedidaDAO::getByPK($producto->id_unidad)->getAbreviacion() . ", lote {$producto->id_lote}"); try { //verificamos si el lote indicado existe if (is_null($producto->id_lote) || strlen($producto->id_lote) == 0) { throw new InvalidDataException("No selecciono a que lote ira el producto {$producto->id_producto}"); } //busquemos el id del lote if (!($lote = LoteDAO::getByPK($producto->id_lote))) { throw new InvalidDataException("No se tiene registro del lote {$producto->id_lote}"); } //verificamos que exista la unidad de medida y este activa if (!UnidadMedidaDAO::getByPK($producto->id_unidad)) { throw new InvalidDataException("La unidad de medida {$producto->id_unidad} no existe, o no esta activa."); } //busquemos si este producto ya existe en este lote $lote_producto = LoteProductoDAO::getByPK($lote->getIdLote(), $producto->id_producto); if (is_null($lote_producto)) { Logger::log("El producto no estaba en el lote, se insertara"); /* //no existe, insertar $loteProducto = new LoteProducto(array( "id_lote" => $lote->getIdLote(), "id_producto" => $producto->id_producto, "cantidad" => $producto->cantidad, "id_unidad" => $producto->id_unidad )); LoteProductoDAO::save($loteProducto); Logger::log("Se guardo el LoteProducto : id_lote {$lote->getIdLote()}, id_producto {$producto->id_producto}, cantidad {$producto->cantidad} id_unidad {$producto->id_unidad}"); $loteEntrada = new LoteEntrada(array( "id_lote" => $lote->getIdLote(), "id_usuario" => $s['id_usuario'], "fecha_registro" => time(), "motivo" => "Entrada por ajuste de inventario" )); LoteEntradaDAO::save($loteEntrada); Logger::log("Se guardo el LoteEntrada: id_lote {$lote->getIdLote()}, id_usuario {$s['id_usuario']}, motivo {Entrada por ajuste de inventario}"); */ AlmacenesController::EntradaLote($lote->getIdLote(), array($producto), "Entrada por ajuste de inventario"); } else { Logger::log("El producto si estaba en el lote, verificaremos las cantidades"); //revisemos si es de la misma unidad if ($lote_producto->getIdUnidad() == $producto->id_unidad) { Logger::log("Se encontro que la unidad enviada es igual a la unidad del lote producto"); Logger::log("Se detecto una merma de {$producto->cantidad} " . UnidadMedidaDAO::getByPK($producto->id_unidad)->getAbreviacion() . " de {$producto->nombre}"); //$existencias_lote = ProductoDAO::ExistenciasLote($producto->id_producto, $lote->getIdLote(), $lote_producto->getIdUnidad()); $existencias_lote = ProductoDAO::ExistenciasTotales($producto->id_producto); Logger::log("Se encontraron {$existencias_lote} existencias en el lote {$lote->getIdLote()} para el producto {$producto->id_producto}"); } else { Logger::log("Se encontro que la unidad enviada es diferente a la unidad del lote producto, se procede a transformar"); //$existencias_lote = ProductoDAO::ExistenciasLote($producto->id_producto, $lote->getIdLote(), $lote_producto->getIdUnidad()); $existencias_lote = ProductoDAO::ExistenciasTotales($producto->id_producto); Logger::log("Se encontraron {$existencias_lote} " . UnidadMedidaDAO::getByPK($lote_producto->getIdUnidad())->getAbreviacion() . " en el lote {$lote->getIdLote()} para el producto " . ProductoDAO::getByPK($producto->id_producto)->getNombreProducto() . " , nosotros necesitamos que se transforme en " . UnidadMedidaDAO::getByPK($producto->id_unidad)->getAbreviacion()); //var_dump($producto->id_unidad, $lote_producto->getIdUnidad(), $existencias_lote); try { Logger::log("Enviara a transformar unidad base : {$producto->id_unidad}, unidad a transformar : {$lote_producto->getIdUnidad()}, cantidad a transformar : {$existencias_lote}"); $existencias_lote = UnidadMedidaDAO::convertir($lote_producto->getIdUnidad(), $producto->id_unidad, $existencias_lote); Logger::log("Como producto de la transformacion se obtuvo {$existencias_lote} "); } catch (BusinessLogicException $ide) { //no se pudo convertir porque son de //diferentes categorias throw $ide; //mostrar una excpetion mas fresona } } Logger::log("se evaluara {$existencias_lote} - {$producto->cantidad}"); //hacemos el ajuste $diff = $existencias_lote - $producto->cantidad; if ($diff > 0) { //entonces hay una merma y se reporta una salida al lote igual a $diff, especificando en motivo el id del movimiento realizado //se actualiza la cantidad de producto en lote producto //AlmacenesController::Salida($l->getIdAlmacen(), $producto, "100"); $diff = abs($diff); Logger::log("Se detecto una merma de {$diff} " . UnidadMedidaDAO::getByPK($producto->id_unidad)->getAbreviacion() . " de {$producto->nombre}"); /* $lote_salida = new LoteSalida(array( "id_lote" => $lote->getIdLote(), "id_usuario" => $s['id_usuario'], "fecha_registro" => time(), "motivo" => "Salida de producto por ajuste de inventario (merma)" )); LoteSalidaDAO::save($lote_salida); Logger::log("Se creo un lote salida id_lote {$lote->getIdLote()}, id_usuario {$s['id_usuario']}, motivo Salida de producto por ajuste de inventario (merma)"); $lote_salida_producto = new LoteSalidaProducto(array( "id_lote_salida" => $lote_salida->getIdLoteSalida(), "id_producto" => $producto->id_producto, "id_unidad" => $producto->id_unidad, "cantidad" => $producto->cantidad )); LoteSalidaProductoDAO::save($lote_salida_producto); Logger::log("Se creo un lote salida producto con id_lote_salida {$lote_salida->getIdLoteSalida()}, id_producto {$producto->id_producto}, id_unidad {$producto->id_unidad}, cantidad {$producto->cantidad}"); */ AlmacenesController::SalidaLote($lote->getIdLote(), array(array("id_producto" => $producto->id_producto, "cantidad" => $diff, "id_unidad" => $producto->id_unidad)), "Salida de producto por ajuste de inventario (merma)"); } if ($diff < 0) { $diff = abs($diff); //entonces hay un sobrante y se reporta una entrada al lote igual a $diff, especificando en motivo el id del movimiento realizado //se actualiza la cantidad de producto en lote producto //AlmacenesController::Entrada($l->getIdAlmacen(), $producto, "101"); Logger::log("Se detecto una sobrante de {$diff} " . UnidadMedidaDAO::getByPK($producto->id_unidad)->getAbreviacion()); /* $lote_entrada = new LoteEntrada(array( "id_lote" => $lote->getIdLote(), "id_usuario" => $s['id_usuario'], "fecha_registro" => time(), "motivo" => "Entrada de producto por ajuste de inventario (sobrante)" )); LoteEntradaDAO::save($lote_entrada); Logger::log("Se creo un lote entrada id_lote {$lote->getIdLote()}, id_usuario {$s['id_usuario']}, motivo Entrada de producto por ajuste de inventario (sobrante)"); $lote_entrada_producto = new LoteEntradaProducto(array( "id_lote_entrada" => $lote_entrada->getIdLote(), "id_producto" => $producto->id_producto, "id_unidad" => $producto->id_unidad, "cantidad" => $producto->cantidad )); LoteEntradaProductoDAO::save($lote_entrada_producto); Logger::log("Se creo un lote entrada producto con id_lote_entrada {$lote_entrada->getIdLoteEntrada()}, id_producto {$producto->id_producto}, id_unidad {$producto->id_unidad}, cantidad {$producto->cantidad}"); */ //AlmacenesController::EntradaLote($lote->getIdLote(), array($producto), "Entrada de producto por ajuste de inventario (sobrante)"); AlmacenesController::EntradaLote($lote->getIdLote(), array(array("id_producto" => $producto->id_producto, "cantidad" => $diff, "id_unidad" => $producto->id_unidad)), "Entrada de producto por ajuste de inventario (sobrante)"); } //TODO:HAY QUE AHCER PRUEBAS EXHAUSTIVAS PARA VER SI ESTE ULTIMO BLOQUE DE CODIGO SE DEBERIA DE ELIMINAR //actualizamos las existencias de lote producto if ($diff != 0) { Logger::log("Se procede a hacer el ajuste del lote producto"); self::ajustarLoteProducto($producto->id_lote, $producto->id_producto, $producto->id_unidad); } else { Logger::log("Se detecto que la cantidad en tote producto concuerda con la cantidad inventariada, pero aun asi se llamara al metodo de ajuste de prodcuto"); self::ajustarLoteProducto($producto->id_lote, $producto->id_producto, $producto->id_unidad); } } } catch (InvalidDataException $e) { Logger::error($e); DAO::transRollback(); throw $e; } catch (exception $e) { Logger::error($e); DAO::transRollback(); throw new InvalidDatabaseOperationException($e); } } }
function idlote($v) { $loteO = LoteDAO::getByPK($v); return $loteO->getFolio(); }
/** * * * Lotes * **/ public function testLotes() { $almacenes = AlmacenesController::Buscar(true); $almacenId = $almacenes["resultados"][0]->getIdAlmacen(); //nuevo lote $nLote = AlmacenesController::NuevoLote($almacenId); $this->assertNotNull($l = LoteDAO::getByPK($nLote["id_lote"])); $producto = new Producto(array("compra_en_mostrador" => false, "metodo_costeo" => "precio", "precio" => 123.123, "activo" => true, "codigo_producto" => time() . "tp", "nombre_producto" => time() . "np", "costo_estandar" => 12.3123, "id_unidad" => 1)); ProductoDAO::save($producto); $r = AlmacenesController::EntradaLote($nLote["id_lote"], array(array("id_producto" => $producto->getIdProducto(), "cantidad" => 23))); //Vamos a validar estas tablas $this->assertNotNull(LoteEntradaDAO::getByPK($r["id_entrada_lote"])); $this->assertNotNull(LoteProductoDAO::getByPK($nLote["id_lote"], $producto->getIdProducto())); $this->assertNotNull(LoteEntradaProductoDAO::getByPK($r["id_entrada_lote"], $producto->getIdProducto(), 1)); //sacar de ese lote, uno por uno hasta llegar a retirar todo for ($i = 0; $i < 23; $i++) { AlmacenesController::SalidaLote($nLote["id_lote"], array(array("id_producto" => $producto->getIdProducto(), "cantidad" => 1, "id_unidad" => 1))); } Logger::log("la siguiente vez que retire algo, debe de arrojar una exception"); try { AlmacenesController::SalidaLote($nLote["id_lote"], array(array("id_producto" => $producto->getIdProducto(), "cantidad" => 1, "id_unidad" => 1))); //esto nunca se deberia de ejecutar $this->assertTrue(false); } catch (InvalidDataException $ivde) { $this->assertNotNull($ivde); } }
/** * Regresa la cantidad total de producto en un lote especifico * * ESTE METODO SIRVE PARA CUANDO EN LOTE PRODUCTO HAY REGISTROS CON UNIDADES DIFERENTES, YA QUE EN EL CASO DE ExistenciasTotales NO * TRABAJARIA DE MANERA CORRECTA YA QUE SE INFIERE QUE TODOS LOS TEGISTROS EN LOTE PRODUCTO TIENEN LA MISMA UNIDAD * * @param type $id_producto * @param type $id_lote * @param type $id_unidad * @return \stdClass */ public static function ExistenciasLote($id_producto, $id_lote, $id_unidad) { //Logger::log("EXISTENCIAS LOTE PARA RECIBE " . ProductoDAO::getByPK($id_producto)->getNombreProducto() . ", LOTE {$id_lote}, todas las operaciones para el calculo deberan hacerse en {$id_unidad} (" . UnidadMedidaDAO::getByPK($id_unidad)->getAbreviacion() . ")"); $error = ""; $cantidad = 0; $nentradas = 0; $nsalidas = 0; //verificamos si el producto existe if (!($producto = ProductoDAO::getByPK($id_producto))) { $error .= "No se tiene registro del producto {$id_producto}. \n"; } //verificamos si se envia el lote if (!($lote = LoteDAO::getByPK($id_lote))) { $error .= "No se tiene registro del lote {$id_lote}. \n"; } //obtenemos los lotes de entrada $lotes_entrada = LoteEntradaDAO::search(new LoteEntrada(array("id_lote" => $id_lote))); //Logger::log("Iteramos sobre los lote entrada, se encontraron " . count($lotes_entrada) . " lotes entrada."); //iteramos sobre los lote de entrada foreach ($lotes_entrada as $lote_entrada) { if ($lote_entrada->getIdLote() != $id_lote) { continue; } $array = array("id_lote_entrada" => $lote_entrada->getIdLoteEntrada(), "id_producto" => $id_producto); $lotes_entrada_producto = LoteEntradaProductoDAO::search(new LoteEntradaProducto($array)); //Logger::log("--- Iteramos sobre los lote entrada producto , se encontraron " . count($lotes_entrada_producto) . " lotes entrada."); foreach ($lotes_entrada_producto as $lote_entrada_producto) { //Logger::log("--- Revisando el lote entrada producto tiene como unidad " . UnidadMedidaDAO::getByPK($lote_entrada_producto->getIdUnidad())->getAbreviacion() . " se comparara contra " . UnidadMedidaDAO::getByPK($id_unidad)->getAbreviacion() . "."); if ($lote_entrada_producto->getIdProducto() != $id_producto) { //Logger::error("El search fallo!! el lote entrada producto trajo al producto {$lote_entrada_producto->getIdProducto()} y lo compara con {$id_producto}"); continue; } else { //revisemos si es de la misma unidad if ($lote_entrada_producto->getIdUnidad() == $id_unidad) { //Logger::log("Se detectaron que las unidades son iguales, el conteo se encuentra en {$cantidad}, se agregaran {$lote_entrada_producto->getCantidad()}"); //es igual, solo hay que sumar $cantidad += $lote_entrada_producto->getCantidad(); $nentradas += $lote_entrada_producto->getCantidad(); // Logger::log("Des pues de la operacion el conteo se encuentra en {$cantidad}"); } else { //no es igual, hay que convertir //Logger::log("Se detecto que las unidades son diferentes, se procede a transformar {$lote_entrada_producto->getCantidad()} " . UnidadMedidaDAO::getByPK($lote_entrada_producto->getIdUnidad())->getDescripcion() . " a " . UnidadMedidaDAO::getByPK($id_unidad)->getDescripcion()); //Logger::log("**** INFO DEL LOTE : " . $lote_entrada_producto . " ***"); $equivalencia = UnidadMedidaDAO::convertir($lote_entrada_producto->getIdUnidad(), $id_unidad, $lote_entrada_producto->getCantidad()); // Logger::log("El conteo se encuentra en {$cantidad}, se agregaran {$equivalencia} " . UnidadMedidaDAO::getByPK($id_unidad)->getDescripcion()); $cantidad += $equivalencia; $nentradas += $equivalencia; // Logger::log("Des pues de la operacion el conteo se encuentra en {$cantidad}"); } } } } //obtenemos los lotes de salida $lotes_salida = LoteSalidaDAO::search(new LoteSalida(array("id_lote" => $id_lote))); //Logger::log("Iteramos sobre los lote salida, se encontraron " . count($lotes_entrada) . " lotes salida."); //iteramos sobre los lote de salida foreach ($lotes_salida as $lote_salida) { $array = array("id_lote_salida" => $lote_salida->getIdLoteSalida(), "id_producto" => $id_producto); $lotes_salida_producto = LoteSalidaProductoDAO::search(new LoteSalidaProducto($array)); //Logger::log("--- Iteramos sobre los lote salida producto , se encontraron " . count($lotes_salida_producto) . " lotes salida producto."); foreach ($lotes_salida_producto as $lote_salida_producto) { //Logger::log("--- Revisando el lote salida producto tiene como unidad " . UnidadMedidaDAO::getByPK($lote_salida_producto->getIdUnidad())->getAbreviacion() . " se comparara contra " . UnidadMedidaDAO::getByPK($id_unidad)->getAbreviacion() . "."); if ($lote_salida_producto->getIdProducto() != $id_producto) { //Logger::error("El search fallo!! el lote salida producto trajo al producto {$lote_salida_producto->getIdProducto()} y lo compara con {$id_producto}"); continue; } else { //revisemos si es de la misma unidad if ($lote_salida_producto->getIdUnidad() == $id_unidad) { //Logger::log("Se detectaron que las unidades son iguales, el conteo se encuentra en {$cantidad}, se restaran {$lote_salida_producto->getCantidad()}"); //es igual, solo hay que restar $cantidad -= $lote_salida_producto->getCantidad(); $nsalidas += $lote_salida_producto->getCantidad(); //Logger::log("Des pues de la operacion el conteo se encuentra en {$cantidad}"); } else { //Logger::log("Se detecto que las unidades son diferentes, se procede a transformar {$lote_salida_producto->getCantidad()} " . UnidadMedidaDAO::getByPK($lote_salida_producto->getIdUnidad())->getDescripcion() . " a " . UnidadMedidaDAO::getByPK($id_unidad)->getDescripcion()); // Logger::log("**** INFO DEL LOTE : " . $lote_salida_producto . " ***"); //no es igual, hay que convertir $equivalencia = UnidadMedidaDAO::convertir($lote_salida_producto->getIdUnidad(), $id_unidad, $lote_salida_producto->getCantidad()); // Logger::log("El conteo se encuentra en {$cantidad}, se restaran {$equivalencia} " . UnidadMedidaDAO::getByPK($id_unidad)->getDescripcion()); $cantidad -= $equivalencia; $nsalidas += $equivalencia; // Logger::log("Des pues de la operacion el conteo se encuentra en {$cantidad}"); } } } } if ($error != "") { Logger::error($error); } // Logger::log("########### Se encontro que para el producto " . ProductoDAO::getByPK($id_producto)->getNombreProducto() . " existen {$cantidad} " . UnidadMedidaDAO::getByPK($id_unidad)->getAbreviacion() . ". Hubo {$nentradas} entradas y {$nsalidas} salidas ###############"); return $cantidad; }
/** * *Envia productos fuera del almacen. Ya sea que sea un traspaso de un alamcen a otro o por motivos de inventarios fisicos. * * @param id_lote int Id del lote de donde se descontaran los productos. * @param productos json Objeto que contendra los ids de los productos que seran sacados del alamcen con sus cantidades y sus unidades * @param motivo string Motivo de la salida del producto * @return id_salida_lote int ID de la salida del producto **/ static function SalidaLote($id_lote, $productos, $motivo = null) { if (is_null(LoteDAO::getByPK($id_lote))) { throw new InvalidDataException("este lote no existe"); } if (!is_array($productos)) { throw new InvalidDataException("productos no es un array"); } $sesion = SesionController::Actual(); DAO::transBegin(); $sl = new LoteSalida(); $sl->setIdLote($id_lote); $sl->setIdUsuario($sesion["id_usuario"]); $sl->setFechaRegistro(time()); $sl->setMotivo(is_null($motivo) ? "" : $motivo); try { LoteSalidaDAO::save($sl); } catch (Exception $e) { DAO::transRollback(); throw new InvalidDatabaseOperationException($e); } for ($i = 0; $i < sizeof($productos); $i++) { if (!is_array($productos[$i])) { throw new InvalidDataException("El producto en la posicion {$i} no es un arreglo como se esperaba"); } if (!array_key_exists("id_producto", $productos[$i])) { throw new InvalidDataException("El producto en {$i} no tiene id_prodcuto"); } if (!array_key_exists("cantidad", $productos[$i])) { throw new InvalidDataException("El producto en {$i} no tiene cantidad"); } if (is_null(ProductoDAO::getByPK($productos[$i]["id_producto"]))) { throw new InvalidDataException("El producto " . $productos[$i]["id_producto"] . " no existe."); } $lp = LoteProductoDAO::getByPK($id_lote, $productos[$i]["id_producto"]); if (is_null($lp)) { throw new InvalidDataException("El lote {$id_lote} no tiene el producto " . $productos[$i]["id_producto"]); } if ($productos[$i]["cantidad"] > $lp->getCantidad()) { throw new InvalidDataException("Estas intentando sacar mas de lo que hay en el lote."); } if (!isset($productos[$i]["id_unidad"])) { throw new InvalidDataException("El producto " . $productos[$i]["id_producto"] . " proporcionado no tiene id_unidad"); } $equivalencia = UnidadMedidaDAO::convertir($productos[$i]["id_unidad"], $lp->getIdUnidad(), $productos[$i]["cantidad"]); if ($equivalencia > $lp->getCantidad()) { Logger::log("Se Comparara {$equivalencia} > {$lp->getCantidad()}"); throw new InvalidDataException("Estas intentando sacar mas de lo que hay en el lote."); } $lp->setCantidad($lp->getCantidad() - $productos[$i]["cantidad"]); try { LoteProductoDAO::save($lp); LoteSalidaProductoDAO::save(new LoteSalidaProducto(array("id_lote_salida" => $sl->getIdLoteSalida(), "id_producto" => $productos[$i]["id_producto"], "id_unidad" => $productos[$i]["id_unidad"], "cantidad" => $productos[$i]["cantidad"]))); Logger::log("Removiendo qty=" . $productos[$i]["cantidad"] . "; prod=" . $productos[$i]["id_producto"] . "; lote=" . $id_lote); } catch (Exception $e) { Logger::error($e); throw new InvalidDatabaseOperationException($e); } } DAO::transEnd(); return array("id_salida_lote" => $sl->getIdLoteSalida()); }