########################################################################### ## API COMXAR (Fase 3) - agregado 28-ago-2026 ## ------------------------------------------------------------------------- ## Suma: ventas (solo lectura) y cobros (solo lectura) con detalle anidado, ## alta de "pedido simple" (cliente + items, sin tocar stock ni facturacion), ## informes agregados de solo lectura, e importacion masiva de productos. ## Reusa la infraestructura de Fase 1/2 (auth, scopes, rate limit, logging). ########################################################################### /* --------------------------------------------------------------------- Recurso: ventas (solo lectura, con items_de_ventas y cobros anidados) --------------------------------------------------------------------- */ function api_items_de_venta_de($venta_id){ global $db_link; $stmt = mysqli_prepare($db_link,"select id,producto,concepto,cantidad,precio_unitario,importe,costo from items_de_ventas where venta=? and sys_delete is null order by id asc"); mysqli_stmt_bind_param($stmt,"i",$venta_id); mysqli_stmt_execute($stmt); $r = mysqli_stmt_get_result($stmt); $items = array(); while ($rs = mysqli_fetch_array($r, MYSQLI_ASSOC)){ $items[] = array( "id" => intval($rs['id']), "producto" => $rs['producto']!="" ? intval($rs['producto']) : null, "concepto" => $rs['concepto'], "cantidad" => $rs['cantidad'], "precio_unitario" => $rs['precio_unitario'], "importe" => $rs['importe'], ); } mysqli_stmt_close($stmt); return $items; } function api_cobros_de_venta($venta_id){ global $db_link; $stmt = mysqli_prepare($db_link,"select id,fecha,importe,efectivo,transferencia,mercadopago from cobros where venta=? and sys_delete is null order by id asc"); mysqli_stmt_bind_param($stmt,"i",$venta_id); mysqli_stmt_execute($stmt); $r = mysqli_stmt_get_result($stmt); $items = array(); while ($rs = mysqli_fetch_array($r, MYSQLI_ASSOC)){ $items[] = array( "id" => intval($rs['id']), "fecha" => $rs['fecha'], "importe"=> $rs['importe'], ); } mysqli_stmt_close($stmt); return $items; } function api_ventas_serializar($rs, $con_detalle=false){ $out = array( "id" => intval($rs['id']), "cliente" => $rs['cliente']!="" ? intval($rs['cliente']) : null, "fecha" => $rs['fecha'], "confirmado" => $rs['confirmado'], "estado" => isset($rs['estado']) ? $rs['estado'] : null, "cancelada" => $rs['cancelada'], "total" => $rs['total'], "importe_pago" => $rs['importe_pago'], "forma_de_pago" => isset($rs['forma_de_pago']) ? $rs['forma_de_pago'] : null, "referencia" => isset($rs['referencia']) ? $rs['referencia'] : null, "fecha_de_entrega" => isset($rs['fecha_de_entrega']) ? $rs['fecha_de_entrega'] : null, "origen" => isset($rs['origen']) ? $rs['origen'] : null, "cantidad_de_productos" => isset($rs['cantidad_de_productos']) ? $rs['cantidad_de_productos'] : null, "sys_create" => $rs['sys_create'], "sys_modify" => $rs['sys_modify'], ); if ($con_detalle){ $out['items'] = api_items_de_venta_de($rs['id']); $out['cobros'] = api_cobros_de_venta($rs['id']); } return $out; } function api_recurso_ventas($metodo,$id,$input,$key_row){ global $db_link; if ($id!==null and !is_numeric($id)){ api_error_json(422,"id_invalido","El id debe ser numerico."); } if ($metodo=="GET" and $id===null){ api_requerir_scope($key_row,"ventas:leer"); $page = isset($_GET['page']) ? max(1,intval($_GET['page'])) : 1; $per_page = isset($_GET['per_page']) ? max(1,min(100,intval($_GET['per_page']))) : 20; $offset = ($page-1)*$per_page; $where = "where sys_delete is null"; $tipos = ""; $valores = array(); if (isset($_GET['cliente']) and is_numeric($_GET['cliente'])){ $where .= " and cliente=?"; $tipos .= "i"; $valores[] = intval($_GET['cliente']); } if (isset($_GET['desde']) and trim($_GET['desde'])!=""){ $where .= " and STR_TO_DATE(fecha,'%d/%m/%y %H:%i') >= STR_TO_DATE(?,'%Y-%m-%d')"; $tipos .= "s"; $valores[] = trim($_GET['desde']); } if (isset($_GET['hasta']) and trim($_GET['hasta'])!=""){ $where .= " and STR_TO_DATE(fecha,'%d/%m/%y %H:%i') <= STR_TO_DATE(?,'%Y-%m-%d')"; $tipos .= "s"; $valores[] = trim($_GET['hasta']); } if (isset($_GET['confirmado'])){ if ($_GET['confirmado']=="1"){ $where .= " and confirmado is not null and confirmado<>''"; }elseif($_GET['confirmado']=="0"){ $where .= " and (confirmado is null or confirmado='')"; } } $sql_count = "select count(*) as total from ventas ".$where; $sql = "select * from ventas ".$where." order by id desc limit ".intval($offset).",".intval($per_page); $stmt1 = mysqli_prepare($db_link,$sql_count); if ($tipos!="") api_bind_params($stmt1,$tipos,$valores); mysqli_stmt_execute($stmt1); $rowcount = mysqli_fetch_array(mysqli_stmt_get_result($stmt1), MYSQLI_ASSOC); $total = intval($rowcount['total']); mysqli_stmt_close($stmt1); $stmt2 = mysqli_prepare($db_link,$sql); if ($tipos!="") api_bind_params($stmt2,$tipos,$valores); mysqli_stmt_execute($stmt2); $r = mysqli_stmt_get_result($stmt2); $items = array(); while ($rs = mysqli_fetch_array($r, MYSQLI_ASSOC)){ $items[] = api_ventas_serializar($rs,false); } mysqli_stmt_close($stmt2); api_responder_json(200, array("data"=>$items,"pagina"=>$page,"por_pagina"=>$per_page,"total"=>$total)); }elseif($metodo=="GET" and $id!==null){ api_requerir_scope($key_row,"ventas:leer"); $stmt = mysqli_prepare($db_link,"select * from ventas where id=? and sys_delete is null limit 1"); mysqli_stmt_bind_param($stmt,"i",$id); mysqli_stmt_execute($stmt); $rs = mysqli_fetch_array(mysqli_stmt_get_result($stmt), MYSQLI_ASSOC); mysqli_stmt_close($stmt); if (!$rs){ api_error_json(404,"no_encontrado","No existe una venta con id ".$id."."); } api_responder_json(200, api_ventas_serializar($rs,true)); }elseif($metodo=="POST" and $id===null){ api_requerir_scope($key_row,"ventas:escribir"); api_ventas_crear_pedido($input,$key_row); }else{ api_error_json(405,"metodo_no_permitido","Metodo ".$metodo." no soportado para /ventas."); } } /* --------------------------------------------------------------------- Alta de "pedido simple": cliente + items nada mas. Queda como cotizacion/pedido pendiente (confirmado = NULL), NO descuenta stock ni genera comprobante -- eso lo termina el staff desde el panel. Por eso el scope es "ventas:escribir" pero el alcance de lo que hace esta funcion es deliberadamente chico y no reusa guardar_venta() (que esta atada al form del panel y hace muchas mas cosas). --------------------------------------------------------------------- */ function api_ventas_crear_pedido($input,$key_row){ global $db_link; if (!isset($input['cliente']) or !is_numeric($input['cliente'])){ api_error_json(422,"campo_requerido","El campo 'cliente' (id de contacto) es obligatorio y debe ser numerico.","cliente"); } $cliente_id = intval($input['cliente']); $stmt_c = mysqli_prepare($db_link,"select id from contactos where id=? and sys_delete is null limit 1"); mysqli_stmt_bind_param($stmt_c,"i",$cliente_id); mysqli_stmt_execute($stmt_c); $existe_cliente = mysqli_fetch_array(mysqli_stmt_get_result($stmt_c), MYSQLI_ASSOC); mysqli_stmt_close($stmt_c); if (!$existe_cliente){ api_error_json(422,"cliente_invalido","No existe un contacto con id ".$cliente_id.".","cliente"); } if (!isset($input['items']) or !is_array($input['items']) or count($input['items'])==0){ api_error_json(422,"campo_requerido","El campo 'items' es obligatorio y debe ser una lista con al menos un elemento.","items"); } $items_normalizados = array(); $total = 0.0; $cantidad_de_productos = 0; foreach ($input['items'] as $idx => $item){ if (!is_array($item)){ api_error_json(422,"item_invalido","El item en la posicion ".$idx." no es un objeto valido.","items"); } $cantidad = isset($item['cantidad']) ? floatval($item['cantidad']) : 1; if ($cantidad<=0){ api_error_json(422,"item_invalido","El item en la posicion ".$idx." debe tener cantidad mayor a 0.","items"); } $producto_id = null; $concepto = isset($item['concepto']) ? trim($item['concepto']) : ""; $precio_unitario = isset($item['precio_unitario']) ? floatval($item['precio_unitario']) : null; $costo = null; if (isset($item['producto']) and $item['producto']!==null and $item['producto']!==""){ if (!is_numeric($item['producto'])){ api_error_json(422,"item_invalido","El campo 'producto' del item en la posicion ".$idx." debe ser numerico.","items"); } $producto_id = intval($item['producto']); $stmt_p = mysqli_prepare($db_link,"select id,nombre,precio,costo from productos where id=? and sys_delete is null limit 1"); mysqli_stmt_bind_param($stmt_p,"i",$producto_id); mysqli_stmt_execute($stmt_p); $prod = mysqli_fetch_array(mysqli_stmt_get_result($stmt_p), MYSQLI_ASSOC); mysqli_stmt_close($stmt_p); if (!$prod){ api_error_json(422,"item_invalido","No existe un producto con id ".$producto_id." (item ".$idx.").","items"); } if ($concepto==""){ $concepto = $prod['nombre']; } if ($precio_unitario===null){ $precio_unitario = floatval(precio_a_float($prod['precio'])); } $costo = $prod['costo']; } if ($concepto==""){ api_error_json(422,"item_invalido","El item en la posicion ".$idx." necesita 'producto' o 'concepto'.","items"); } if ($precio_unitario===null){ api_error_json(422,"item_invalido","El item en la posicion ".$idx." necesita 'precio_unitario' (o un 'producto' con precio cargado).","items"); } $importe = round($precio_unitario * $cantidad, 2); $total += $importe; $cantidad_de_productos += $cantidad; $items_normalizados[] = array( "producto" => $producto_id, "concepto" => $concepto, "cantidad" => $cantidad, "precio_unitario" => $precio_unitario, "importe" => $importe, "costo" => $costo, ); } $fecha_y_hora = date("d/m/y H:i"); $referencia = isset($input['referencia']) and is_string($input['referencia']) ? trim($input['referencia']) : ""; $origen = "api"; $usuario = "api:".$key_row['id']; $total_str = number_format($total,2,'.',''); $stmt_v2 = mysqli_prepare($db_link,"insert into ventas (cliente,fecha,total,referencia,origen,sys_create,sys_create_user) values (?,?,?,?,?,?,?)"); mysqli_stmt_bind_param($stmt_v2,"issssss",$cliente_id,$fecha_y_hora,$total_str,$referencia,$origen,$fecha_y_hora,$usuario); mysqli_stmt_execute($stmt_v2); $venta_id = mysqli_insert_id($db_link); mysqli_stmt_close($stmt_v2); if (!$venta_id){ api_error_json(500,"error_interno","No se pudo crear el pedido."); } foreach ($items_normalizados as $it){ $stmt_i = mysqli_prepare($db_link,"insert into items_de_ventas (venta,producto,concepto,cantidad,precio_unitario,importe,costo,sys_create,sys_create_user) values (?,?,?,?,?,?,?,?,?)"); $producto_val = $it['producto']; $cantidad_str = strval($it['cantidad']); $precio_str = number_format($it['precio_unitario'],2,'.',''); $importe_str = number_format($it['importe'],2,'.',''); $costo_val = $it['costo']!==null ? strval($it['costo']) : null; mysqli_stmt_bind_param($stmt_i,"iisssssss",$venta_id,$producto_val,$it['concepto'],$cantidad_str,$precio_str,$importe_str,$costo_val,$fecha_y_hora,$usuario); mysqli_stmt_execute($stmt_i); mysqli_stmt_close($stmt_i); } $stmt_u = mysqli_prepare($db_link,"update ventas set cantidad_de_productos=? where id=?"); $cant_str = strval($cantidad_de_productos); mysqli_stmt_bind_param($stmt_u,"si",$cant_str,$venta_id); mysqli_stmt_execute($stmt_u); mysqli_stmt_close($stmt_u); api_log_escritura($key_row['id'],"ventas","crear",$venta_id,null,array("cliente"=>$cliente_id,"total"=>$total_str,"items"=>count($items_normalizados))); $stmt_f = mysqli_prepare($db_link,"select * from ventas where id=? limit 1"); mysqli_stmt_bind_param($stmt_f,"i",$venta_id); mysqli_stmt_execute($stmt_f); $rs = mysqli_fetch_array(mysqli_stmt_get_result($stmt_f), MYSQLI_ASSOC); mysqli_stmt_close($stmt_f); api_responder_json(201, api_ventas_serializar($rs,true)); } /* --------------------------------------------------------------------- Recurso: cobros (solo lectura) --------------------------------------------------------------------- */ function api_cobros_serializar($rs){ return array( "id" => intval($rs['id']), "venta" => $rs['venta']!="" ? intval($rs['venta']) : null, "cliente" => $rs['cliente']!="" ? intval($rs['cliente']) : null, "fecha" => $rs['fecha'], "importe" => $rs['importe'], "efectivo" => $rs['efectivo'], "transferencia" => $rs['transferencia'], "mercadopago" => $rs['mercadopago'], "sys_create" => $rs['sys_create'], ); } function api_recurso_cobros($metodo,$id,$input,$key_row){ global $db_link; if ($id!==null and !is_numeric($id)){ api_error_json(422,"id_invalido","El id debe ser numerico."); } if ($metodo=="GET" and $id===null){ api_requerir_scope($key_row,"cobros:leer"); $page = isset($_GET['page']) ? max(1,intval($_GET['page'])) : 1; $per_page = isset($_GET['per_page']) ? max(1,min(100,intval($_GET['per_page']))) : 20; $offset = ($page-1)*$per_page; $where = "where sys_delete is null"; $tipos = ""; $valores = array(); if (isset($_GET['venta']) and is_numeric($_GET['venta'])){ $where .= " and venta=?"; $tipos .= "i"; $valores[] = intval($_GET['venta']); } if (isset($_GET['cliente']) and is_numeric($_GET['cliente'])){ $where .= " and cliente=?"; $tipos .= "i"; $valores[] = intval($_GET['cliente']); } $sql_count = "select count(*) as total from cobros ".$where; $sql = "select * from cobros ".$where." order by id desc limit ".intval($offset).",".intval($per_page); $stmt1 = mysqli_prepare($db_link,$sql_count); if ($tipos!="") api_bind_params($stmt1,$tipos,$valores); mysqli_stmt_execute($stmt1); $rowcount = mysqli_fetch_array(mysqli_stmt_get_result($stmt1), MYSQLI_ASSOC); $total = intval($rowcount['total']); mysqli_stmt_close($stmt1); $stmt2 = mysqli_prepare($db_link,$sql); if ($tipos!="") api_bind_params($stmt2,$tipos,$valores); mysqli_stmt_execute($stmt2); $r = mysqli_stmt_get_result($stmt2); $items = array(); while ($rs = mysqli_fetch_array($r, MYSQLI_ASSOC)){ $items[] = api_cobros_serializar($rs); } mysqli_stmt_close($stmt2); api_responder_json(200, array("data"=>$items,"pagina"=>$page,"por_pagina"=>$per_page,"total"=>$total)); }elseif($metodo=="GET" and $id!==null){ api_requerir_scope($key_row,"cobros:leer"); $stmt = mysqli_prepare($db_link,"select * from cobros where id=? and sys_delete is null limit 1"); mysqli_stmt_bind_param($stmt,"i",$id); mysqli_stmt_execute($stmt); $rs = mysqli_fetch_array(mysqli_stmt_get_result($stmt), MYSQLI_ASSOC); mysqli_stmt_close($stmt); if (!$rs){ api_error_json(404,"no_encontrado","No existe un cobro con id ".$id."."); } api_responder_json(200, api_cobros_serializar($rs)); }else{ api_error_json(405,"metodo_no_permitido","Metodo ".$metodo." no soportado para /cobros."); } } /* --------------------------------------------------------------------- Recurso: informes (solo lectura, agregados -- no exponen filas crudas de ventas/cobros, solo totales agrupados) --------------------------------------------------------------------- */ function api_informes_rango_fechas(){ $desde = isset($_GET['desde']) and trim($_GET['desde'])!="" ? trim($_GET['desde']) : date("Y-m-d", strtotime("-30 days")); $hasta = isset($_GET['hasta']) and trim($_GET['hasta'])!="" ? trim($_GET['hasta']) : date("Y-m-d"); return array($desde,$hasta); } function api_informe_resumen_financiero(){ global $db_link; list($desde,$hasta) = api_informes_rango_fechas(); $sql_cotizado = "select coalesce(sum(0+total),0) s from ventas where sys_delete is null and (confirmado is null or confirmado='') and STR_TO_DATE(fecha,'%d/%m/%y %H:%i') between STR_TO_DATE(?,'%Y-%m-%d') and STR_TO_DATE(?,'%Y-%m-%d')"; $sql_vendido = "select coalesce(sum(0+total),0) s from ventas where sys_delete is null and confirmado is not null and confirmado<>'' and STR_TO_DATE(confirmado,'%d/%m/%Y') between STR_TO_DATE(?,'%Y-%m-%d') and STR_TO_DATE(?,'%Y-%m-%d')"; $sql_cobrado = "select coalesce(sum(0+importe),0) s from cobros where sys_delete is null and STR_TO_DATE(fecha,'%d/%m/%y %H:%i') between STR_TO_DATE(?,'%Y-%m-%d') and STR_TO_DATE(?,'%Y-%m-%d')"; $sql_facturado= "select coalesce(sum(0+total),0) s from ventas where sys_delete is null and confirmado is not null and confirmado<>'' and fecha_de_facturacion is not null and STR_TO_DATE(fecha_de_facturacion,'%d/%m/%y %H:%i') between STR_TO_DATE(?,'%Y-%m-%d') and STR_TO_DATE(?,'%Y-%m-%d')"; $resultado = array(); foreach (array("cotizado"=>$sql_cotizado,"vendido"=>$sql_vendido,"cobrado"=>$sql_cobrado,"facturado"=>$sql_facturado) as $clave => $sql){ $stmt = mysqli_prepare($db_link,$sql); mysqli_stmt_bind_param($stmt,"ss",$desde,$hasta); mysqli_stmt_execute($stmt); $rs = mysqli_fetch_array(mysqli_stmt_get_result($stmt), MYSQLI_ASSOC); mysqli_stmt_close($stmt); $resultado[$clave] = floatval($rs['s']); } api_responder_json(200, array("desde"=>$desde,"hasta"=>$hasta) + $resultado); } function api_informe_top_productos(){ global $db_link; list($desde,$hasta) = api_informes_rango_fechas(); $limite = isset($_GET['limite']) ? max(1,min(50,intval($_GET['limite']))) : 10; $sql = "select items_de_ventas.producto, productos.nombre, sum(items_de_ventas.cantidad) cant, sum(0+items_de_ventas.importe) imp from items_de_ventas left outer join ventas on items_de_ventas.venta = ventas.id left outer join productos on productos.id = items_de_ventas.producto where ventas.sys_delete is null and items_de_ventas.sys_delete is null and ventas.cancelada is null and ventas.session is null and ventas.confirmado is not null and ventas.confirmado<>'' and STR_TO_DATE(ventas.confirmado,'%d/%m/%Y') between STR_TO_DATE(?,'%Y-%m-%d') and STR_TO_DATE(?,'%Y-%m-%d') and items_de_ventas.producto is not null and items_de_ventas.producto<>'' and items_de_ventas.producto<>0 group by items_de_ventas.producto order by cant desc limit ".intval($limite); $stmt = mysqli_prepare($db_link,$sql); mysqli_stmt_bind_param($stmt,"ss",$desde,$hasta); mysqli_stmt_execute($stmt); $r = mysqli_stmt_get_result($stmt); $items = array(); while ($rs = mysqli_fetch_array($r, MYSQLI_ASSOC)){ $items[] = array( "producto" => intval($rs['producto']), "nombre" => $rs['nombre'], "cantidad_vendida" => floatval($rs['cant']), "importe_total" => floatval($rs['imp']), ); } mysqli_stmt_close($stmt); api_responder_json(200, array("desde"=>$desde,"hasta"=>$hasta,"data"=>$items)); } function api_informe_deuda_por_cliente(){ global $db_link; $limite = isset($_GET['limite']) ? max(1,min(100,intval($_GET['limite']))) : 20; $sql = "select cliente, sum(0+total) t, sum(0+importe_pago) p, count(*) c from ventas where sys_delete is null and cancelada is null and confirmado is not null and confirmado<>'' and (0+total > 0+importe_pago or importe_pago is null) group by cliente order by (sum(0+total)-sum(0+importe_pago)) desc limit ".intval($limite); $r = mysqli_query($db_link,$sql); $items = array(); while ($rs = mysqli_fetch_array($r, MYSQLI_ASSOC)){ if ($rs['cliente']=="" or $rs['cliente']===null){ continue; } $deuda = floatval($rs['t']) - floatval($rs['p']); if ($deuda<=0){ continue; } $items[] = array( "cliente" => intval($rs['cliente']), "deuda" => $deuda, "cantidad_ventas" => intval($rs['c']), ); } api_responder_json(200, array("data"=>$items)); } function api_informe_stock_bajo(){ global $db_link; $limite = isset($_GET['limite']) ? max(1,min(200,intval($_GET['limite']))) : 50; $sql = "select id,nombre,codigo,stock,stock_minimo from productos where sys_delete is null and habilitado is not null and habilitado<>'' and stock_minimo is not null and stock_minimo<>'' and (0+stock) <= (0+stock_minimo) order by (0+stock) asc limit ".intval($limite); $r = mysqli_query($db_link,$sql); $items = array(); while ($rs = mysqli_fetch_array($r, MYSQLI_ASSOC)){ $items[] = array( "id" => intval($rs['id']), "nombre"=> $rs['nombre'], "codigo"=> $rs['codigo'], "stock" => $rs['stock'], "stock_minimo" => $rs['stock_minimo'], ); } api_responder_json(200, array("data"=>$items)); } function api_recurso_informes($metodo,$id,$input,$key_row){ if ($metodo!="GET"){ api_error_json(405,"metodo_no_permitido","Metodo ".$metodo." no soportado para /informes."); } api_requerir_scope($key_row,"informes:leer"); switch ($id){ case "resumen_financiero": api_informe_resumen_financiero(); break; case "top_productos": api_informe_top_productos(); break; case "deuda_por_cliente": api_informe_deuda_por_cliente(); break; case "stock_bajo": api_informe_stock_bajo(); break; default: api_error_json(404,"informe_no_encontrado","'".$id."' no es un informe disponible. Opciones: resumen_financiero, top_productos, deuda_por_cliente, stock_bajo."); } } /* --------------------------------------------------------------------- Importacion masiva de productos: alta/actualizacion en lote. Cada item se procesa de forma independiente (uno falla, los demas siguen), y la respuesta detalla el resultado item por item. --------------------------------------------------------------------- */ function api_productos_importar($input,$key_row){ global $db_link; api_requerir_scope($key_row,"productos:escribir"); if (!isset($input['productos']) or !is_array($input['productos']) or count($input['productos'])==0){ api_error_json(422,"campo_requerido","El campo 'productos' es obligatorio y debe ser una lista con al menos un elemento.","productos"); } if (count($input['productos'])>200){ api_error_json(422,"demasiados_items","Maximo 200 productos por importacion. Dividi la carga en lotes mas chicos.","productos"); } $campos_permitidos = api_productos_campos_editables(); $resultados = array(); $creados = 0; $actualizados = 0; $con_error = 0; foreach ($input['productos'] as $idx => $item){ if (!is_array($item)){ $resultados[] = array("indice"=>$idx,"ok"=>false,"error"=>"item_invalido","mensaje"=>"El item no es un objeto valido."); $con_error++; continue; } $id_existente = (isset($item['id']) and is_numeric($item['id'])) ? intval($item['id']) : null; $codigo = isset($item['codigo']) ? trim($item['codigo']) : null; // Si no vino id pero si codigo, buscamos por codigo para decidir alta vs modificacion. if ($id_existente===null and $codigo!==null and $codigo!==""){ $stmt_b = mysqli_prepare($db_link,"select id from productos where codigo=? and sys_delete is null limit 1"); mysqli_stmt_bind_param($stmt_b,"s",$codigo); mysqli_stmt_execute($stmt_b); $existente = mysqli_fetch_array(mysqli_stmt_get_result($stmt_b), MYSQLI_ASSOC); mysqli_stmt_close($stmt_b); if ($existente){ $id_existente = intval($existente['id']); } } $datos = array(); foreach ($campos_permitidos as $c){ if (array_key_exists($c,$item) and !is_array($item[$c])){ $datos[$c] = is_string($item[$c]) ? trim($item[$c]) : $item[$c]; } } if ($id_existente===null){ if (!isset($datos['nombre']) or trim($datos['nombre'])==""){ $resultados[] = array("indice"=>$idx,"ok"=>false,"error"=>"campo_requerido","mensaje"=>"Falta 'nombre' para dar de alta el producto."); $con_error++; continue; } $fecha_y_hora = date("d/m/y H:i"); $datos['sys_create'] = $fecha_y_hora; $datos['sys_create_user'] = "api:".$key_row['id']; $cols = array_keys($datos); $marcas = implode(",", array_fill(0,count($cols),"?")); $tipos = str_repeat("s", count($cols)); $stmt = mysqli_prepare($db_link,"insert into productos (".implode(",",$cols).") values (".$marcas.")"); if (!$stmt){ $resultados[] = array("indice"=>$idx,"ok"=>false,"error"=>"error_interno","mensaje"=>"No se pudo preparar el alta."); $con_error++; continue; } $valores = array_values($datos); api_bind_params($stmt,$tipos,$valores); mysqli_stmt_execute($stmt); $nuevo_id = mysqli_insert_id($db_link); mysqli_stmt_close($stmt); if (!$nuevo_id){ $resultados[] = array("indice"=>$idx,"ok"=>false,"error"=>"error_interno","mensaje"=>"No se pudo crear el producto."); $con_error++; continue; } api_log_escritura($key_row['id'],"productos","crear",$nuevo_id,null,$datos); $resultados[] = array("indice"=>$idx,"ok"=>true,"accion"=>"creado","id"=>$nuevo_id); $creados++; }else{ $stmt0 = mysqli_prepare($db_link,"select * from productos where id=? and sys_delete is null limit 1"); mysqli_stmt_bind_param($stmt0,"i",$id_existente); mysqli_stmt_execute($stmt0); $antes = mysqli_fetch_array(mysqli_stmt_get_result($stmt0), MYSQLI_ASSOC); mysqli_stmt_close($stmt0); if (!$antes){ $resultados[] = array("indice"=>$idx,"ok"=>false,"error"=>"no_encontrado","mensaje"=>"No existe un producto con id ".$id_existente."."); $con_error++; continue; } if (empty($datos)){ $resultados[] = array("indice"=>$idx,"ok"=>true,"accion"=>"sin_cambios","id"=>$id_existente); continue; } $fecha_y_hora = date("d/m/y H:i"); $datos['sys_modify'] = $fecha_y_hora; $datos['sys_modify_user'] = "api:".$key_row['id']; $sets = array(); foreach (array_keys($datos) as $c){ $sets[] = $c."=?"; } $tipos = str_repeat("s", count($datos)); $stmt = mysqli_prepare($db_link,"update productos set ".implode(",",$sets)." where id=?"); $valores = array_values($datos); $valores[] = $id_existente; api_bind_params($stmt,$tipos."i",$valores); mysqli_stmt_execute($stmt); mysqli_stmt_close($stmt); api_log_escritura($key_row['id'],"productos","actualizar",$id_existente,$antes,$datos); $resultados[] = array("indice"=>$idx,"ok"=>true,"accion"=>"actualizado","id"=>$id_existente); $actualizados++; } } api_responder_json(200, array( "total" => count($input['productos']), "creados" => $creados, "actualizados" => $actualizados, "con_error" => $con_error, "resultados" => $resultados, )); }
Warning: Cannot modify header information - headers already sent by (output started at /var/www/default.contactopuro.com/public_html/admin/inc/functions.php:10697) in /var/www/default.contactopuro.com/public_html/inc/front_processor.php on line 59
https://dietaberazategui.comx.ar/ https://dietaberazategui.comx.ar/registro https://dietaberazategui.comx.ar/terminos https://dietaberazategui.comx.ar/registro https://dietaberazategui.comx.ar/dp-descenso-progresivo-1-mes-4-reuniones https://dietaberazategui.comx.ar/ind-individual-con-nutricionista-4-reuniones https://dietaberazategui.comx.ar/ind-individual-con-nutricionista-3-meses-12-reuniones