/** * *Registra una nueva compra fuera de caja, puede usarse para que el administrador haga directamente una compra. El usuario y al sucursal seran tomados de la sesion. La fecha sera tomada del servidor. La empresa sera tomada del almacen del cual fueron tomados los productos. * * @param descuento float Monto descontado por descuentos * @param subtotal float Total de la compra antes de impuestos y descuentos. * @param detalle json Objeto que contendr el arreglo de id productos, cantidad, precio, descuento, id de unidad y procesado que involucran esta compra. * @param impuesto float Monto agregado por impuestos * @param tipo_compra string Si la compra es a credito o de contado * @param retencion float Monto agregado por retenciones * @param id_usuario_compra int Id usuario al que se le compra, si es a una sucursal, se pone el id en negativo * @param id_empresa int Id de la empresa a nombre de la cual se hace la compra * @param total float Total de la compra * @param cheques json Si el tipo de pago es con cheque, se almacena el nombre del banco, el monto y los ultimos 4 numeros del o de los cheques * @param saldo float Cantidad pagada de la * @param tipo_de_pago string Si el pago sera en efectivo, con cheque o tarjeta * @return id_compra int Id autogenerado por la inserci�n de la compra **/ public static function Nueva($descuento, $detalle, $id_empresa, $id_usuario_compra, $impuesto, $retencion, $subtotal, $tipo_compra, $total, $cheques = null, $id_sucursal = null, $saldo = 0, $tipo_de_pago = null) { Logger::log(" ===== Creando nueva compra... ===== "); //validemos al comprador $proveedor = UsuarioDAO::getByPK($id_usuario_compra); if (is_null($proveedor)) { Logger::error("el provedor {$id_usuario_compra} no exite"); throw new InvalidDataException("El proveedor no existe"); } if ($proveedor->getActivo() == false) { throw new BusinessLogicException("No se puede comprar de un proveedor no activo."); } //validemos la empresa $empresa = EmpresaDAO::getByPK($id_empresa); if (is_null($empresa)) { Logger::error("La empresa {$id_empresa} no existe"); throw new InvalidDataException("La empresa que compra no existe."); } if ($empresa->getActivo() == false) { throw new BusinessLogicException("Una empresa inactiva no puede hacer compras."); } //validemos los valores conocidos //( 0 >= descuento > 100, subtotal > 0, total >= subtotal, etc etc) //validemos sucursal $sucursal = null; if (!is_null($id_sucursal) && strlen($id_sucursal) > 0) { $sucursal = SucursalDAO::getByPK($id_sucursal); if (is_null($sucursal)) { Logger::error("La sucursal {$id_sucursal} no existe"); //throw new InvalidDataException("La sucural que se envio no existe."); } } //validemos detalles de compra //debe traer // -id_producto // -cantidad // -precio // -lote if (!is_array($detalle)) { throw InvalidDataException("El detalle no es un arreglo"); } for ($detalleIterator = 0; $detalleIterator < sizeof($detalle); $detalleIterator++) { //por cada producto // -debe existir // -si se lo compro a un proveedor no hay pedo // si se lo compro a un cliente, debe de tener comprar_caja = 1 // -debe tener cantidad mayor a 0 // -que exista el lote a donde va a ir $p = $detalle[$detalleIterator]; if (!isset($p->precio)) { throw new InvalidArgumentException("No se envio el precio"); } if (!isset($p->id_producto)) { throw new InvalidArgumentException("No se envio el id_producto"); } if (!isset($p->cantidad)) { throw new InvalidArgumentException("No se envio la cantidad"); } if (!isset($p->lote)) { throw new InvalidArgumentException("No se envio el lote"); } $producto = ProductoDAO::getByPK($p->id_producto); if (is_null($producto)) { throw new InvalidArgumentException("El producto a comprar no existe"); } if ($p->cantidad <= 0) { throw new InvalidArgumentException("No puedes comprar 0 unidades"); } } $s = SesionController::getCurrentUser(); //terminaron las validaciones $compra = new Compra(); $compra->setIdVendedorCompra($id_usuario_compra); $compra->setTipoDeCompra($tipo_compra); $compra->setFecha(time()); $compra->setSubtotal($subtotal); $compra->setImpuesto($impuesto); $compra->setDescuento($descuento); $compra->setTotal($subtotal + $impuesto); $compra->setIdUsuario($s->getIdUsuario()); $compra->setIdEmpresa($id_empresa); $compra->setSaldo(0); $compra->setCancelada(false); $compra->setTipoDePago($tipo_de_pago); $compra->setRetencion(0); try { DAO::transBegin(); CompraDAO::save($compra); } catch (Exception $e) { DAO::transRollback(); throw InvalidDatabaseOperationException($e); } for ($detalleIterator = 0; $detalleIterator < sizeof($detalle); $detalleIterator++) { //por cada producto // --- procesos --- // -insertar en productoempresa // -insertar en loteproducto // -insertar en entradalote // -si el tipo de precio de venta es costo, actualizar // -insertar compra producto $p = $detalle[$detalleIterator]; try { ProductoEmpresaDAO::save(new ProductoEmpresa(array("id_empresa" => $id_empresa, "id_producto" => $p->id_producto))); if (is_null($p->lote)) { throw new InvalidDataException("No selecciono a que lote ira el producto " . $p->id_producto); } if (strlen($p->lote) == 0) { throw new InvalidDataException("No selecciono a que lote ira el producto " . $p->id_producto); } //busquemos el id del lote $l = LoteDAO::search(new Lote(array("folio" => $p->lote))); $l = $l[0]; //busquemos la unidad que nos mandaron $uAbreviacion = $p->id_unidad; $uResults = UnidadMedidaDAO::search(new UnidadMedida(array("abreviacion" => $uAbreviacion, "activa" => 1))); if (sizeof($uResults) != 1) { throw new InvalidDataException("La unidad de medida `" . $p->id_unidad . "` no existe, o no esta activa."); } else { $p->id_unidad = $uResults[0]->getIdUnidadMedida(); } //busequemos si este producto ya existe en este lote $lp = LoteProductoDAO::getByPK($l->getIdLote(), $p->id_producto); if (is_null($lp)) { //no existe, insertar $loteProducto = new LoteProducto(array("id_lote" => $l->getIdLote(), "id_producto" => $p->id_producto, "cantidad" => $p->cantidad, "id_unidad" => $p->id_unidad)); LoteProductoDAO::save($loteProducto); } else { //ya existe, sumar //revisemos si es de la misma unidad if ($lp->getIdUnidad() == $p->id_unidad) { //es igual, solo hay que sumar $lp->setCantidad($lp->getCantidad() + $p->cantidad); } else { //no es igual, hay que convertir try { $r = UnidadMedidaDAO::convertir($p->id_unidad, $lp->getIdUnidad(), $p->cantidad); } catch (BusinessLogicException $ide) { //no se pudo convertir porque son de //diferentes categorias throw $ide; //mostrar una excpetion mas fresona } $lp->setCantidad($lp->getCantidad() + $r); } //$lp->setCantidad( $lp->getCantidad() + $p->cantidad ); LoteProductoDAO::save($lp); } $loteEntrada = new LoteEntrada(array("id_lote" => $l->getIdLote(), "id_usuario" => $s->getIdUsuario(), "fecha_registro" => time(), "motivo" => "Compra a Proveedor")); LoteEntradaDAO::save($loteEntrada); LoteEntradaProductoDAO::save(new LoteEntradaProducto(array("id_lote_entrada" => $loteEntrada->getIdLoteEntrada(), "id_producto" => $p->id_producto, "id_unidad" => $p->id_unidad, "cantidad" => $p->cantidad))); $compraProducto = new CompraProducto(array("id_compra" => $compra->getIdCompra(), "id_producto" => $p->id_producto, "cantidad" => $p->cantidad, "precio" => $p->precio, "descuento" => 0, "impuesto" => 0, "id_unidad" => $p->id_unidad, "retencion" => 0)); CompraProductoDAO::save($compraProducto); } catch (InvalidDataException $e) { Logger::error($e); DAO::transRollback(); throw $e; } catch (exception $e) { Logger::error($e); DAO::transRollback(); throw new InvalidDatabaseOperationException($e); } } //for try { DAO::transEnd(); } catch (Exception $e) { throw InvalidDatabaseOperationException($e); } Logger::log("===== COMPRA " . $compra->getIdCompra() . " EXITOSA ===== "); return array("id_compra" => $compra->getIdCompra()); }
public function testBuscarProductosPorID_Sucursal() { $dir_suc = self::RandomString(25, FALSE, FALSE, FALSE); $desc = self::RandomString(10, FALSE, FALSE, FALSE); $sucursal = SucursalesController::Nueva($descripcion = $desc, $direccion = $dir_suc, $id_tarifa = 1); $this->assertInternalType("int", $sucursal['id_sucursal'], "---- 'testBuscarProductosPorID_Sucursal' 'id_sucursal' NO ES UN ENTERO"); $empresa_rfc = self::RandomString(13, FALSE, FALSE, FALSE); $empresa_razon = self::RandomString(10, FALSE, FALSE, FALSE); $contabilidad['id_moneda'] = 1; $contabilidad['ejercicio'] = "2013"; $contabilidad['periodo_actual'] = 1; $contabilidad['duracion_periodo'] = 1; $empresa = EmpresasController::Nuevo((object) $contabilidad, $direccion = array(array("calle" => "Monte Balcanes", "numero_exterior" => "107", "colonia" => "Arboledas", "id_ciudad" => 334, "codigo_postal" => "38060", "numero_interior" => null, "referencia" => "Calle cerrada", "telefono1" => "4616149974", "telefono2" => "45*451*454")), $razon_social = $empresa_razon, $rfc = $empresa_rfc); $this->assertInternalType("int", $empresa['id_empresa'], "---- 'testBuscarProductosPorID_Sucursal' 'id_empresa' NO ES UN ENTERO"); //se crea un nuevo producto $codigo_p = self::RandomString(5, FALSE, FALSE, FALSE); $nombre_p = self::RandomString(15, FALSE, FALSE, FALSE); $p = ProductosController::Nuevo($activo = true, $codigo_producto = $codigo_p, $compra_en_mostrador = true, $id_unidad_compra = 1, $metodo_costeo = "costo", $nombre_producto = $nombre_p, $visible_en_vc = true, $codigo_de_barras = null, $control_de_existencia = null, $costo_estandar = 10, $descripcion_producto = null, $foto_del_producto = null, $garantia = null, $id_categoria = null, $id_empresas = array($empresa['id_empresa']), $id_unidad = null, $impuestos = null, $precio_de_venta = 12); //TODO: En un futuro desaparecera esto ya que por instancia lo correctro es que haya una sola empresa y todas als sucursales perteneceran a la empresa ProductoEmpresaDAO::save(new ProductoEmpresa(array("id_producto" => $p["id_producto"], "id_empresa" => $empresa['id_empresa']))); SucursalEmpresaDAO::save(new SucursalEmpresa(array("id_sucursal" => $sucursal['id_sucursal'], "id_empresa" => $empresa['id_empresa']))); $res = ProductosController::Buscar($query = null, $id_producto = null, $id_sucursal = $sucursal['id_sucursal']); $this->assertInternalType("int", $res["numero_de_resultados"], "---- 'testBuscarProductosPorID_Sucursal' 'numero_de_resultados' NO ES UN ENTERO"); $this->assertGreaterThan(0, $res['numero_de_resultados'], "---- 'testBuscarProductosPorID_Sucursal' SE DEBIÓ DE ENCONTRAR ALMENOS 1 RESULTADO CON NOMBRE PRODUCTO: " . $nombre_p); }
/** * *Edita la informaci?n de un producto * * @param id_producto int Id del producto a editar * @param clasificaciones json Uno o varios id_clasificacion de este producto, esta clasificacion esta dada por el usuario * @param codigo_de_barras string El Codigo de barras para este producto * @param codigo_producto string Codigo del producto * @param compra_en_mostrador bool Verdadero si este producto se puede comprar en mostrador, para aquello de compra-venta * @param control_de_existencia int 00000001 = Unidades. 00000010 = Caractersticas. 00000100 = Series. 00001000 = Pedimentos. 00010000 = Lote * @param costo_estandar float Valor del costo estndar del producto. * @param costo_extra_almacen float Si este producto produce un costo extra por tenerlo en almacen * @param descripcion_producto string Descripcion larga del producto * @param empresas json arreglo de ids de empresas a las que pertenece este producto * @param foto_del_producto string url a una foto de este producto * @param garantia int Numero de meses de garantia con los que cuenta esta categoria de producto * @param id_unidad int La unidad preferente de este producto * @param id_unidad_compra int El id de la unidad de medida en la que se adquiere el producto al comprarlo * @param impuestos json array de ids de impuestos que tiene este producto * @param metodo_costeo string Puede ser "precio" o "costo" e indican si el precio final sera tomado a partir del costo del producto o del precio del mismo * @param nombre_producto string Nombre del producto * @param peso_producto float el peso de este producto en KG * @param precio int El precio de este producto * @param visible_en_vc bool Verdadero si este producto sera visible a los clientes. **/ static function Editar($id_producto, $clasificaciones = null, $codigo_de_barras = null, $codigo_producto = null, $compra_en_mostrador = null, $control_de_existencia = null, $costo_estandar = null, $costo_extra_almacen = null, $descripcion_producto = null, $empresas = null, $foto_del_producto = null, $garantia = null, $id_unidad = null, $id_unidad_compra = null, $impuestos = null, $metodo_costeo = null, $nombre_producto = null, $peso_producto = null, $precio = null, $visible_en_vc = null) { Logger::log("== Editando producto " . $id_producto . " =="); //se validan los parametros recibidos $validar = self::validarParametrosProducto($id_producto, $compra_en_mostrador, $metodo_costeo, null, $codigo_producto, $nombre_producto, $garantia, $costo_estandar, $control_de_existencia, $descripcion_producto, $foto_del_producto, $costo_extra_almacen, $codigo_de_barras, $peso_producto, $id_unidad, $precio); if (is_string($validar)) { Logger::error($validar); throw new Exception($validar); } //is_string($validar) $producto = ProductoDAO::getByPK($id_producto); //Los parametros que no sean nulos seran tomados como una actualizacion if (!is_null($compra_en_mostrador)) { $producto->setCompraEnMostrador($compra_en_mostrador); } //!is_null($compra_en_mostrador) if (!is_null($descripcion_producto)) { $producto->setDescripcion($descripcion_producto); } //!is_null($descripcion_producto) if (!is_null($metodo_costeo)) { $producto->setMetodoCosteo($metodo_costeo); } //!is_null($metodo_costeo) if (!is_null($codigo_producto)) { $producto->setCodigoProducto(trim($codigo_producto)); } //!is_null($codigo_producto) if (!is_null($nombre_producto)) { $producto->setNombreProducto(trim($nombre_producto)); } //!is_null($nombre_producto) if (!is_null($garantia)) { $producto->setGarantia($garantia); } //!is_null($garantia) if (!is_null($costo_estandar)) { $costo_estandar = $metodo_costeo == "costo" ? $costo_estandar : null; //sólo en caso de que se haya seleccionado metodo_costeo == 'costo' tomar en cuenta este valor ver API $producto->setCostoEstandar($costo_estandar); } //!is_null($costo_estandar) if (!is_null($control_de_existencia)) { $producto->setControlDeExistencia($control_de_existencia); } //!is_null($control_de_existencia) if (!is_null($foto_del_producto)) { $producto->setFotoDelProducto($foto_del_producto); } //!is_null($foto_del_producto) if (!is_null($costo_extra_almacen)) { $producto->setCostoExtraAlmacen($costo_extra_almacen); } //!is_null($costo_extra_almacen) if (!is_null($codigo_de_barras)) { $producto->setCodigoDeBarras(trim($codigo_de_barras)); } //!is_null($codigo_de_barras) if (!is_null($peso_producto)) { $producto->setPesoProducto($peso_producto); } //!is_null($peso_producto) if (!is_null($id_unidad)) { $producto->setIdUnidad($id_unidad); } //!is_null($id_unidad) if (!is_null($id_unidad_compra)) { $producto->setIdUnidadCompra($id_unidad_compra); } //!is_null($id_unidad_compra) if (!is_null($precio)) { $producto->setPrecio($precio); } //!is_null($precio) if (!is_null($visible_en_vc)) { $producto->setVisibleEnVc($visible_en_vc); } if ($metodo_costeo == "precio" && is_null($producto->getPrecio())) { Logger::error("Se intenta registrar un producto con metodo de costeo precio sin especificar un precio"); throw new Exception("Se intenta registrar un producto con metodo de costeo precio sin especificar un precio", 901); } else { if ($metodo_costeo == "costo" && is_null($producto->getCostoEstandar())) { Logger::error("Se intenta registrar un producto con metodo de costeo costo sin especificar un costo estandar"); throw new Exception("Se intenta registrar un producto con metodo de costeo costo sin especificar un costo estandar", 901); } } //$metodo_costeo == "costo" && is_null($producto->getCostoEstandar()) DAO::transBegin(); try { ProductoDAO::save($producto); //Si se reciben empresas, clasificaciones y/o impuestos se modifican en sus respectivas tablas // //Primero se guardan o actualizan los registros pasados en la lista, despues se recorren los registros //actuales y si alguno no se encuentra en la lista se elimina. if (!is_null($empresas)) { $empresas = object_to_array($empresas); if (!is_array($empresas)) { throw new Exception("Las empresas fueron enviadas incorrectamente", 901); } //!is_array($empresas) $producto_empresa = new ProductoEmpresa(array("id_producto" => $id_producto)); foreach ($empresas as $empresa) { $validar = self::validarParametrosProductoEmpresa($empresa); if (is_string($validar)) { throw new Exception($validar, 901); } $producto_empresa->setIdEmpresa($empresa); ProductoEmpresaDAO::save($producto_empresa); } //$empresas as $empresa $productos_empresa = ProductoEmpresaDAO::search(new ProductoEmpresa(array("id_producto" => $id_producto))); foreach ($productos_empresa as $p_e) { $encontrado = false; foreach ($empresas as $empresa) { if ($empresa == $p_e->getIdEmpresa()) { $encontrado = true; } //$empresa == $p_e->getIdEmpresa() } //$empresas as $empresa if (!$encontrado) { ProductoEmpresaDAO::delete($p_e); } } //$productos_empresa as $p_e } //!is_null($empresas) /* Fin if de empresas */ if (!is_null($clasificaciones)) { $clasificaciones = object_to_array($clasificaciones); if (!is_array($clasificaciones)) { throw new Exception("Las clasificaciones fueron recibidas incorrectamente", 901); } //!is_array($clasificaciones) $producto_clasificacion = new ProductoClasificacion(array("id_producto" => $id_producto)); foreach ($clasificaciones as $clasificacion) { $c = ClasificacionProductoDAO::getByPK($clasificacion); if (is_null($c)) { throw new Exception("La clasificacion de producto con id " . $clasificacion . " no existe", 901); } if (!$c->getActiva()) { throw new Exception("La clasificaicon de producto con id " . $clasificacion . " no esta activa", 901); } $producto_clasificacion->setIdClasificacionProducto($clasificacion); ProductoClasificacionDAO::save($producto_clasificacion); } //$clasificaciones as $clasificacion $productos_clasificacion = ProductoClasificacionDAO::search(new ProductoClasificacion(array("id_producto" => $id_producto))); foreach ($productos_clasificacion as $p_c) { $encontrado = false; foreach ($clasificaciones as $clasificacion) { if ($clasificacion == $p_c->getIdClasificacionProducto()) { $encontrado = true; } //$clasificacion == $p_c->getIdClasificacionProducto() } //$clasificaciones as $clasificacion if (!$encontrado) { ProductoClasificacionDAO::delete($p_c); } } //$productos_clasificacion as $p_c } //!is_null($clasificaciones) /* Fin if de clasificaciones */ if (!is_null($impuestos)) { $impuestos = object_to_array($impuestos); if (!is_array($impuestos)) { throw new Exception("Los impuestos fueron recibidos incorrectamente", 901); } //!is_array($impuestos) $impuesto_producto = new ImpuestoProducto(array("id_producto" => $producto->getIdProducto())); foreach ($impuestos as $impuesto) { if (is_null(ImpuestoDAO::getByPK($impuesto))) { throw new Exception("El impuesto con id " . $impuesto . " no existe", 901); } $impuesto_producto->setIdImpuesto($impuesto); ImpuestoProductoDAO::save($impuesto_producto); } //$impuestos as $impuesto $impuestos_producto = ImpuestoProductoDAO::search(new ImpuestoProducto(array("id_producto" => $id_producto))); foreach ($impuestos_producto as $i_p) { $encontrado = false; foreach ($impuestos as $impuesto) { if ($impuesto == $i_p->getIdImpuesto()) { $encontrado = true; } //$impuesto == $i_p->getIdImpuesto() } //$impuestos as $impuesto if (!$encontrado) { ImpuestoProductoDAO::delete($i_p); } } //$impuestos_producto as $i_p } //!is_null($impuestos) /* Fin if de impuestos */ } catch (Exception $e) { DAO::transRollback(); Logger::error("El producto no pudo ser editado: " . $e); if ($e->getCode() == 901) { throw new Exception("El producto no pudo ser editado: " . $e->getMessage(), 901); } throw new Exception("El producto no pudo ser editado", 901); } DAO::transEnd(); Logger::log("Producto editado exitosamente"); }