Buenas tardes, ya estoy dando los primeros pasos con el mod-harbour-v2
Les comento que la idea es hacer una app de pedidos para una distribuidora de helados, cuyos vendedores van a levantar el pedido de los clientes a través del celular.
En base v2.order "Charly" , me abrió el panorama para empezar, agregando funcionalidades como por ejemplo seleccionar el cliente al levantar la orden.
Voy compartiendo código para quien aun no empezó, se anime
Formulario de ingreso
Código: Seleccionar todo
Function main()
Local cHtml := ''
local cUrl := mh_GetUri()
// Autenticar inicio-------------------------------
if !mh_SessionActive()
mh_Redirect( cUrl + 'login.prg' )
return nil
endif
mh_SessionInit() // Activamos la sesion
// Autenticar fin----------------------------------
// Abrir tabla de Articulos------------------------
cAlias := OpenDataArticulo()
//? cAlias // Si muestra el alias es xq salio todo bien
if empty( cAlias )
? 'Error al abrir la tabla'
Return nil
endif
BLOCKS TO cHtml
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="UTF-8">
<title>Pedidos</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/numeral.js/2.0.6/numeral.min.js"></script>
</head>
<body>
<h1>Pedidos</h1>
<form action="order.prg" method="POST">
<label for="articulo">Seleccione un articulo:</label>
<select name="articulo" id="articulo" onchange="selArt()">
ENDTEXT
WHILE (cAlias)->(!Eof())
cHtml += '<option value="'+(cAlias)->nombre+'">'+(cAlias)->nombre+'</option>'
(cAlias)->(DbSkip())
END
BLOCKS TO cHtml
</select>
<br>
Cantidad: <input name="cantidad" value="1" id="cantidad">
<br>
ENDTEXT
cHtml += 'Precio Unitario: <input name="pu" id="pu" readonly>'
cHtml += '<br>'
cHtml += 'Importe Neto: <input name="importeNeto" id="importeNeto" readonly>'
cHtml += '<br>'
cHtml += 'Tasa Iva: <input name="tasaIva" id="tasaIva" readonly>'
cHtml += '<br>'
cHtml += 'Importe Iva: <input name="importeIva" id="importeIva" readonly>'
cHtml += '<br>'
cHtml += 'Importe Final: <input name="importeFinal" id="importeFinal" readonly>'
BLOCKS TO cHtml
<br><br>
<input type="submit" value="Enviar Pedido">
</form>
<script>
function selArt() {
cNombreArticulo = document.getElementById("articulo").value;
//alert("Articulo: " + cNombreArticulo);
var oParam = new Object()
oParam[ 'action' ] = 'buscarArticulo'
oParam[ 'nameProd' ] = cNombreArticulo
$.ajax({
url: 'articulos.prg',
method: 'POST',
data: oParam
})
.done(function (response) {
console.log("success");
console.log(response);
$("#pu").val(response['puNeto']);
$("#importeNeto").val(response['puNeto']);
$("#tasaIva").val(numeral(response['tasaIva']).format('0.00'));
calculoPrecioItem();
})
.fail(function () {
console.log("error");
})
.always(function () {
console.log("complete");
});
}
function calculoPrecioItem(){
var cantidad = parseFloat($("#cantidad").val());
var price = parseFloat($("#pu").val());
var resultado = cantidad*price;
var tasaIva = parseFloat($("#tasaIva").val());
var impIva = resultado*tasaIva/100;
var impFinal = resultado+impIva;
$("#pu").val(numeral(price).format('0,0.00'));
$("#importeNeto").val(numeral(resultado).format('0,0.00'));
$("#importeIva").val(numeral(impIva).format('0,0.00'));
$("#importeFinal").val(numeral(impFinal).format('0,0.00'));
}
//--------------------------------------------------
$(document).ready(function() {
$("#cantidad").change(function(){
calculoPrecioItem();
});
});
//--------------------------------------------------
</script>
</body>
</html>
ENDTEXT
?? cHtml
Return nil
{% mh_LoadFile('funciones.prg') %}
El siguiente codigo es el articulo.prg que escucha la llamada de axaj
Obs.: Este archivo debe tener la funcion de escucha arriba de todo y luego las otras funciones
Código: Seleccionar todo
//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
Function mainArticulo()
local hParam := ap_PostPairs()
AP_SetContentType( "application/json" )
do case
case hParam[ 'action' ] == 'buscarArticulo' ; buscarArticulo( hParam )
case hParam[ 'action' ] == 'agregarArticulo' ; agregarArticulo( hParam )
otherwise
?? hb_jsonEncode( { 'error' => 'Accion no permitida' } )
endcase
Return nil
//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
Function buscarArticulo(hParam)
local cPath := hb_GetEnv('PRGPATH')
local id, publico
USE ( cPath + '/Articulo.dbf' ) SHARED NEW
LOCATE FOR Articulo->nombre==hParam['nameProd']
IF FOUND()
id=Articulo->id
puNeto=Str(Articulo->neto)
tasaIva=Str(Articulo->tasa_iva)
ENDIF
?? hb_jsonEncode( { 'id' => id,'puNeto' => puNeto, 'tasaIva' => tasaIva } )
Return nil
//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
Function agregarArticulo(hParam)
?? hb_jsonEncode( hParam )
Return nil
Archivo prg para guardar la entrada de datos
Código: Seleccionar todo
function main()
local hParam
local cUrl := mh_GetUri()
LOCAL cHtml:= ''
// Autenticar inicio--------------------------------------
if !mh_SessionActive()
mh_Redirect( cUrl + 'login.prg' )
return nil
endif
mh_SessionInit() // Activamos la sesion
// Autenticar fin-----------------------------------------
// Recuperar los parametros-------------------------------
hParam := ap_PostPairs()
? hParam
cUser := mh_Session('username')
// Abrir la base de datos---------------------------------
cAlias := OpenData()
if empty( cAlias )
? 'Error al abrir la tabla'
Return nil
endif
// Grabar los datos---------------------------------------
if ( cAlias )->( DbAppend())
( cAlias )->date := DATE()
( cAlias )->time := TIME()
( cAlias )->user := cUser
( cAlias )->ip := ap_GetEnv('REMOTE_ADDR')
( cAlias )->articulo := hParam['articulo']
( cAlias )->cantidad := VAL(hParam['cantidad'])
( cAlias )->pu := VAL(hParam['pu'])
( cAlias )->neto := VAL(hParam['importeNeto'])
( cAlias )->tasaiva := VAL(hParam['tasaIva'])
( cAlias )->impiva := VAL(hParam['importeIva'])
( cAlias )->impfinal := VAL(hParam['importeFinal'])
( cAlias )->( DbCommit() )
( cAlias )->( DbUnlock() )
endif
// Mostrar mensaje
BLOCKS TO cHtml
<!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="UTF-8">
<title>Pedido Realizado</title>
<body>
<h1>Pedido Realizado</h1>
<table border="1">
<tr>
<th>Usuario</th>
<th>Fecha</th>
<th>Hora</th>
<th>IP</th>
<th>Artículo</th>
<th>Cantidad</th>
<th>P.U.</th>
<th>Neto</th>
<th>Tasa Iva</th>
<th>Imp.Iva</th>
<th>Imp.Final</th>
</tr>
ENDTEXT
cHtml += '<tr>'
cHtml += '<td>' + (cAlias)->user + '</td>'
cHtml += '<td>' + DTOC( (cAlias)->date) + '</td>'
cHtml += '<td>' + (cAlias)->time + '</td>'
cHtml += '<td>' + (cAlias)->ip + '</td>'
cHtml += '<td>' + (cAlias)->articulo + '</td>'
cHtml += '<td>' + str((cAlias)->cantidad) + '</td>'
cHtml += '<td>' + str((cAlias)->pu) + '</td>'
cHtml += '<td>' + str((cAlias)->neto) + '</td>'
cHtml += '<td>' + str((cAlias)->tasaIva) + '</td>'
cHtml += '<td>' + str((cAlias)->impIva) + '</td>'
cHtml += '<td>' + str((cAlias)->impFinal) + '</td>'
cHtml += '</tr>'
BLOCKS TO cHtml PARAMS cUrl
</table>
<br>
<a href="{{ cUrl + 'entry.prg' }}"><button>Generar Pedido</button></a>
<a href="{{ cUrl + 'menu.prg' }}"><button>Menu</button></a>
<a href="{{ cUrl + 'cerrar.prg' }}"><button>Cerrar Sesión</button></a>
</body>
</html>
ENDTEXT
// Cerrar la base de datos
// Generar la salida
?? cHtml
Return nil
{% mh_LoadFile('funciones.prg') %}
Todo esto es similar casi igual a lo que hizo Chaly en su presentación del viernes pasado.
Puedes probarlo en
App Pedidos
Marcelo