Implementación inicial
This commit is contained in:
parent
857e9b2e16
commit
934efde4c3
7 changed files with 265 additions and 8 deletions
17
common.ts
Normal file
17
common.ts
Normal 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;
|
||||||
|
}
|
|
@ -1,8 +1,89 @@
|
||||||
<!doctype html>
|
<!DOCTYPE html>
|
||||||
<meta charset="utf8">
|
<meta charset="utf8" />
|
||||||
<title>hyperpop.js demo</title>
|
<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">
|
<script type="module">
|
||||||
import { prueba } from "../build/index.js"
|
import { dummy, getProductos, getPricesByCustomer } from "../build/index.js";
|
||||||
prueba()
|
|
||||||
|
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>
|
</script>
|
||||||
|
|
15
dummy.ts
Normal file
15
dummy.ts
Normal 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");
|
||||||
|
}
|
||||||
|
}
|
8
index.ts
8
index.ts
|
@ -1,3 +1,5 @@
|
||||||
export function prueba() {
|
// Docs: https://github.com/TangoSoftware/ApiTiendas
|
||||||
console.log("¡Hola desde hyperpop.js!");
|
export * from "./common.js";
|
||||||
}
|
export * from "./dummy.js";
|
||||||
|
export * from "./product.js";
|
||||||
|
export * from "./priceByCustomer.js";
|
||||||
|
|
55
priceByCustomer.ts
Normal file
55
priceByCustomer.ts
Normal 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
86
product.ts
Normal 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;
|
||||||
|
}
|
|
@ -2,8 +2,9 @@
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
/* Visit https://aka.ms/tsconfig.json to read more about this file */
|
/* Visit https://aka.ms/tsconfig.json to read more about this file */
|
||||||
|
|
||||||
"target": "es5",
|
"target": "ES2015",
|
||||||
"module": "es6",
|
"module": "es6",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
|
||||||
"outDir": "./build",
|
"outDir": "./build",
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue