-- TODO GENERAL: Completar la generacion de factura A y B (hoy solo esta C de monotributo)
--[[
Se ingresa:
- Punto de venta (dropdown con los elementos)
- El tipo de comprobante a generar (factura A, B, C, recibo, nota de debito, nota de credito, etc)
{
"uid": "53935f27-5cf0-4281-9a29-a68f100ee981",
"execution_status": "Borrador",
"tipo_comprobante": "factura c",
"fecha_comprobante": "13/11/2025",
"tipo_concepto": "servicios",
"servicio_fecha_desde": "01/10/2025",
"servicio_fecha_hasta": "01/10/2025",
"servicio_fecha_vencimiento_pago": "13/11/2025",
"referencia": "",
"tipo_iva_receptor": "consumidor final",
"cuit_receptor": "",
"forma_pago": "contado",
"monto_unitario": "10000",
"cantidad": "1",
"descripcion": "Clase de apoyo",
"request": {
"request_uid": "f976aa76-8d49-4564-8e44-2100819bae77",
"execution_status": "Fallido",
"user_uid": "bc31ddeb-b8c7-48e1-b569-20bbd8e7ec12",
"options": {
"automatic_confirmation_flag": false
},
"csv_data": "factura c,16/11/2025,servicios,01/10/2025,01/10/2025,16/11/2025,,monotributo,27287630412,contado,10000,1,Clase de apoyo\\n",
"credentials": {
"cuit": "20292929092",
"password": "password",
"orden_punto_venta": 1,
"nombre_empresa": "NOMBRE DE EMPRESA"
}
}
}
--]]
local json = require("json")
----------------------------------------------------------------------
-- Helpers
----------------------------------------------------------------------
local function logErrorAndExit(message)
log(message)
error(message)
end
-- Normalizar el input que viene del JSON por si acaso lowercase
local function normalize(s)
if not s then return "" end
s = string.lower(s)
-- s = s:gsub("^%s+", ""):gsub("%s+$", "")
return s
end
--[[
TODO: Analizar la posta, los tipos de comprobantes dependen del punto de venta, en el caso de un monotributo salen estos
asi que ver como hacer con el caso de un consumidor final y otros. Quizas buscar por el texto y en funcion de eso elegir el valor? (como se hace con el punto de venta?)
]]--
-- TODO: Factura A o B
local function is_factura_a(tipo)
return tipo == "factura a" or tipo == "a"
end
local function is_factura_b(tipo)
return tipo == "factura b" or tipo == "b"
end
local function is_factura_c(tipo)
return tipo == "factura c" or tipo == "c"
end
local function is_nota_debito(tipo)
return tipo == "nota de debito" or tipo == "debito"
end
local function is_nota_credito(tipo)
return tipo == "nota de credito" or tipo == "credito"
end
local function is_recibo(tipo)
return tipo == "recibo"
end
--[[
Valores que corresponden al value del select
TipoComprobanteInvalido = 0
TipoComprobanteFacturaC = 2
TipoComprobanteNotaDebito = 3
TipoComprobanteNotaCredito = 4
TipoComprobanteRecibo = 5
]]--
local function mapTipoComprobante(tipo)
local t = normalize(tipo)
if is_factura_c(t) then
return "2"
elseif is_nota_debito(t) then
return "3"
elseif is_nota_credito(t) then
return "4"
elseif is_recibo(t) then
return "5"
elseif is_factura_a(t) then
return "6" -- TODO: Check real value
elseif is_factura_b(t) then
return "7" -- TODO: Check real value
end
return ""
end
----------------------------------------------------------------------
-- Main logic
----------------------------------------------------------------------
local function main()
log("afip_ingresar_punto_venta_y_comprobante: starting")
--------------------------------------------------------------------
-- Decode payload
--------------------------------------------------------------------
local payload, err = json.decode(json_payload)
if err then
logErrorAndExit("afip_ingresar_punto_venta_y_comprobante: error decoding payload: " .. err)
end
--------------------------------------------------------------------
-- Extract fields from payload
--------------------------------------------------------------------
-- Punto de venta: should correspond to comprobante.PuntoDeVenta
-- as used in Go (selectDropdownItemByPosition second argument).
local puntoDeVenta = nil
if payload["request"] and payload["request"]["credentials"] and payload["request"]["credentials"]["orden_punto_venta"] then
puntoDeVenta = payload["request"]["credentials"]["orden_punto_venta"]
else
logErrorAndExit("afip_ingresar_punto_venta_y_comprobante: punto_de_venta is missing in payload")
end
-- Tipo de comprobante: we can receive textual or numeric.
local tipoComprobanteRaw = payload["tipo_comprobante"]
if not tipoComprobanteRaw or tipoComprobanteRaw == "" then
logErrorAndExit("afip_ingresar_punto_venta_y_comprobante: tipo_comprobante is missing in payload")
end
-- Ensure punto de venta is numeric
local puntoDeVentaNum = tonumber(puntoDeVenta)
if not puntoDeVentaNum then
logErrorAndExit(
"afip_ingresar_punto_venta_y_comprobante: punto_de_venta must be numeric, got: " .. tostring(puntoDeVenta)
)
end
local tipoComprobanteValor = mapTipoComprobante(tipoComprobanteRaw)
if tipoComprobanteValor == "" then
logErrorAndExit(
"afip_ingresar_punto_venta_y_comprobante: tipo_comprobante could not be mapped: " ..
tostring(tipoComprobanteRaw)
)
end
log("afip_ingresar_punto_venta_y_comprobante: punto_de_venta=", tostring(puntoDeVentaNum),
" tipo_comprobante_valor=", tostring(tipoComprobanteValor))
--------------------------------------------------------------------
-- 1) Seleccionar punto de venta (select#puntodeventa)
--------------------------------------------------------------------
local puntoVentaId = "puntodeventa"
-- Uses the binding selectDropdownItemByPosition(id, position)
err = selectDropdownItemByPosition(puntoVentaId, puntoDeVentaNum)
if err then
logErrorAndExit(
"afip_ingresar_punto_venta_y_comprobante: selectDropdownItemByPosition failed for punto_de_venta: " ..
tostring(err)
)
end
log("afip_ingresar_punto_venta_y_comprobante: punto_de_venta selected OK")
--------------------------------------------------------------------
-- 2) Seleccionar tipo de comprobante (select#universocomprobante)
--------------------------------------------------------------------
local tipoComprobanteId = "universocomprobante"
--[[
]]--
-- ERROR: 2026/01/19 23:57:13 Error running script: :45: afip_ingresar_punto_venta_y_comprobante failed: :45: afip_ingresar_punto_venta_y_comprobante: setTextFieldById for tipo_comprobante failed: could not set value on node 65
-- TODO: The error above does not affect the flow, but happens because after the punto de venta is selected, the tipo de comprobante select is set with the first value which happens to be already "factura c (2)". So when we try to set it again to the same value, it fails. We should improve the function to not fail in this case. Needs some more binding functions on the Go Side.
err = setTextFieldById(tipoComprobanteId, tostring(tipoComprobanteValor))
if err then
logErrorAndExit(
"afip_ingresar_punto_venta_y_comprobante: setTextFieldById for tipo_comprobante failed: " ..
tostring(err)
)
end
log("afip_ingresar_punto_venta_y_comprobante: tipo_comprobante selected OK")
--------------------------------------------------------------------
-- Done
--------------------------------------------------------------------
log("afip_ingresar_punto_venta_y_comprobante: completed successfully")
end
local ok, err = pcall(main)
if not ok then
-- Let Go see this as a Lua error so it can fall back to legacy
logErrorAndExit("afip_ingresar_punto_venta_y_comprobante failed: " .. tostring(err))
end