Implementación inicial

This commit is contained in:
Cat /dev/Nulo 2021-09-22 21:17:35 -03:00
parent 857e9b2e16
commit 934efde4c3
7 changed files with 265 additions and 8 deletions

17
common.ts Normal file
View file

@ -0,0 +1,17 @@
// const HOST = 'https://tiendas.axoft.com'
export const HOST = "http://sutty.vm:4001";
export interface Paging {
/**
* Si hay más páginas disponibles
*/
MoreData: boolean;
/**
* El número de la página. Empieza desde 1.
*/
PageNumber: number;
/**
* El tamaño de la página. Tiene un límite de 5000.
*/
PageSize: number;
}

View file

@ -1,8 +1,89 @@
<!doctype html>
<meta charset="utf8">
<!DOCTYPE html>
<meta charset="utf8" />
<title>hyperpop.js demo</title>
<style>
form {
border: solid 2px black;
padding: 0.2em;
}
</style>
<label for="token-input">Access token: </label>
<input id="token-input" name="token" />
<form id="token">
<button>Probar</button>
<p class="status"></p>
</form>
<form id="productos">
<button>Conseguir productos</button>
<p class="status"></p>
</form>
<form id="precios">
<button>Conseguir precios</button>
<p class="status"></p>
</form>
<script type="module">
import { prueba } from "../build/index.js"
prueba()
import { dummy, getProductos, getPricesByCustomer } from "../build/index.js";
function token() {
return document.querySelector("#token-input").value;
}
function clear(el) {
while (el.firstChild) {
el.firstChild.remove();
}
}
function objectToDom(object) {
const preEl = document.createElement("pre");
const codeEl = document.createElement("code");
if (typeof object === "string") {
codeEl.append(JSON.stringify(JSON.parse(object), null, 2));
} else if (Object.entries(object).length > 0) {
codeEl.append(JSON.stringify(object, null, 2));
} else {
codeEl.append(object);
}
preEl.append(codeEl);
return preEl;
}
async function showResponse(statusEl, promise) {
clear(statusEl);
try {
const response = await promise;
statusEl.append("¡Funcionó!");
if (response) {
statusEl.append(" Respuesta:", objectToDom(response));
}
} catch (error) {
statusEl.append("Hubo un error :(", objectToDom(error));
}
}
const tokenForm = document.querySelector("#token");
tokenForm.addEventListener("submit", async (event) => {
event.preventDefault();
const statusEl = event.target.querySelector(".status");
showResponse(statusEl, dummy(token()));
});
const productosForm = document.querySelector("#productos");
productosForm.addEventListener("submit", async (event) => {
event.preventDefault();
const statusEl = event.target.querySelector(".status");
showResponse(statusEl, getProductos(token(), {}));
});
const preciosForm = document.querySelector("#precios");
preciosForm.addEventListener("submit", async (event) => {
event.preventDefault();
const statusEl = event.target.querySelector(".status");
showResponse(statusEl, getPricesByCustomer(token(), {}));
});
</script>

15
dummy.ts Normal file
View file

@ -0,0 +1,15 @@
import { HOST } from "./common.js";
export async function dummy(token: string) {
const res = await fetch(`${HOST}/api/Aperture/dummy`, {
method: "POST",
headers: {
accesstoken: token,
},
});
const json = await res.json();
if (!json.isOk) {
console.error(json);
throw new Error("Tango: error desconocido");
}
}

View file

@ -1,3 +1,5 @@
export function prueba() {
console.log("¡Hola desde hyperpop.js!");
}
// Docs: https://github.com/TangoSoftware/ApiTiendas
export * from "./common.js";
export * from "./dummy.js";
export * from "./product.js";
export * from "./priceByCustomer.js";

55
priceByCustomer.ts Normal file
View file

@ -0,0 +1,55 @@
import { HOST, Paging } from "./common.js";
export interface PreciosQuery {
paginacion?: {
/**
* El número de la página. Empieza desde 1.
*/
number: number;
/**
* El tamaño de la página. Tiene un límite de 5000.
*/
size: number;
};
}
export interface Precio {
SKUCode: string;
CustomerCode: string;
Price: number;
PriceListNumber: number;
}
export interface PreciosResponse {
Paging: Paging;
Data: Precio[];
}
export async function getPricesByCustomer(
token: string,
options: PreciosQuery
): Promise<PreciosResponse> {
let searchParams = new URLSearchParams();
if (options.paginacion) {
searchParams.set("pageSize", options.paginacion.size.toString());
searchParams.set("pageNumber", options.paginacion.number.toString());
} else {
// El máximo, según lo que retorna en 'Paging'
searchParams.set("pageSize", "5000");
searchParams.set("pageNumber", "1");
}
const res = await fetch(
`${HOST}/api/Aperture/PriceByCustomer?${searchParams.toString()}`,
{
headers: {
accesstoken: token,
},
}
);
const json = await res.json();
console.debug(json);
if (json.Message) {
throw new Error(`Tango: ${json.Message}`);
}
return json;
}

86
product.ts Normal file
View file

@ -0,0 +1,86 @@
import { HOST, Paging } from "./common.js";
export interface ProductosQuery {
paginacion?: {
/**
* El número de la página. Empieza desde 1.
*/
number: number;
/**
* El tamaño de la página. Tiene un límite de 5000.
*/
size: number;
};
/**
* Decide si solo traer los productos habilitados.
*/
onlyEnabled?: boolean;
}
export interface Producto {
SKUCode: string;
Description: string;
AdditionalDescription: string;
AlternativeCode: string;
BarCode: string;
Commission: number;
Discount: number;
MeasureUnitCode: string;
SalesMeasureUnitCode: string;
SalesEquivalence: number;
MaximumStock: number;
MinimumStock: number;
RestockPoint: number;
Observations: string;
Kit: boolean;
KitValidityDateSince?: string;
KitValidityDateUntil?: string;
UseScale: string;
Scale1: string;
Scale2: string;
BaseArticle: string;
ScaleValue1: string;
ScaleValue2: string;
DescriptionScale1: string;
DescriptionScale2: string;
DescriptionValueScale1: string;
DescriptionValueScale2: string;
Disabled: boolean;
ProductComposition: { ComponentSKUCode: string; Quantity: number }[];
ProductComments: { Line: number; Text: string }[];
}
export interface ProductosResponse {
Paging: Paging;
Data: Producto[];
}
// https://github.com/TangoSoftware/ApiTiendas#art%C3%ADculos
export async function getProductos(
token: string,
options: ProductosQuery
): Promise<ProductosResponse> {
let searchParams = new URLSearchParams();
if (options.paginacion) {
searchParams.set("pageSize", options.paginacion.size.toString());
searchParams.set("pageNumber", options.paginacion.number.toString());
} else {
// El máximo, según lo que retorna en 'Paging'
searchParams.set("pageSize", "5000");
searchParams.set("pageNumber", "1");
}
if ("onlyEnabled" in options) {
searchParams.set("onlyEnabled", options.onlyEnabled ? "true" : "false");
}
const res = await fetch(
`${HOST}/api/Aperture/Product?${searchParams.toString()}`,
{
headers: {
accesstoken: token,
},
}
);
const json: ProductosResponse = await res.json();
console.debug(json);
return json;
}

View file

@ -2,8 +2,9 @@
"compilerOptions": {
/* Visit https://aka.ms/tsconfig.json to read more about this file */
"target": "es5",
"target": "ES2015",
"module": "es6",
"moduleResolution": "node",
"outDir": "./build",