Los precios ahora son coherentes
El precio segun divisas corresponde con el total, la divisa del SET es la del origen siempre
This commit is contained in:
@@ -32,6 +32,7 @@ Propuestas:
|
|||||||
|
|
||||||
- Docker (linux) o Docker desktop (widows - WSL)
|
- Docker (linux) o Docker desktop (widows - WSL)
|
||||||
- Ubuntu 24 o similar
|
- Ubuntu 24 o similar
|
||||||
|
- Terminal bash, zsh, sh o compatible
|
||||||
|
|
||||||
## Introduccion
|
## Introduccion
|
||||||
|
|
||||||
@@ -40,6 +41,8 @@ El objetivo es tener un grupo compose con
|
|||||||
- Una BDD para almacenar ejemplos
|
- Una BDD para almacenar ejemplos
|
||||||
- Un servicio que envie peticiones periodicamente
|
- Un servicio que envie peticiones periodicamente
|
||||||
|
|
||||||
|
### Docker
|
||||||
|
|
||||||
Este grupo tiene definida una red externa en el `docker-compose.yaml` que
|
Este grupo tiene definida una red externa en el `docker-compose.yaml` que
|
||||||
tiene que coincidir con la red de los demás compose ejecutados, por ejemplo:
|
tiene que coincidir con la red de los demás compose ejecutados, por ejemplo:
|
||||||
|
|
||||||
|
|||||||
@@ -8,14 +8,53 @@ import { ADDRESS } from "#data/data-pools/ADDRESS.js";
|
|||||||
import { CUSTOMER } from "#data/data-pools/CUSTOMER.js";
|
import { CUSTOMER } from "#data/data-pools/CUSTOMER.js";
|
||||||
import { FieldPool, PoolOf } from "#data/data-pools/pool.type.js";
|
import { FieldPool, PoolOf } from "#data/data-pools/pool.type.js";
|
||||||
import { Shopify } from "../webhooks/order";
|
import { Shopify } from "../webhooks/order";
|
||||||
|
import { PRICE_SET, randomPriceSet } from "./PRICE_SET";
|
||||||
|
import { CURRENCIES, pickCurrencies } from "./shared";
|
||||||
|
|
||||||
|
function genId(digits: number) {
|
||||||
|
return Math.floor(Math.random() * (10 ^ digits))
|
||||||
|
}
|
||||||
|
|
||||||
|
function generatePrice(enteros: number, decimales: number) {
|
||||||
|
return (Math.floor(
|
||||||
|
Math.random() * (10 ** (enteros + decimales + 1)))
|
||||||
|
/
|
||||||
|
(10 ** (decimales))
|
||||||
|
).toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
export function generateOrder(pool: PoolOf<Shopify.Order>) {
|
||||||
|
const id = genId(8)
|
||||||
|
const price = generatePrice(2, 2)
|
||||||
|
const shopCurrency = pickCurrencies(CURRENCIES)
|
||||||
|
|
||||||
|
const ORDER = <Shopify.Order>{
|
||||||
|
...FieldPool.pickRandomOf(pool), // default para el resto de campos
|
||||||
|
id: id,
|
||||||
|
currency: shopCurrency,
|
||||||
|
current_subtotal_price: price,
|
||||||
|
current_subtotal_price_set: randomPriceSet({} as PoolOf<Shopify.PriceSet>, {
|
||||||
|
baseCurrency: shopCurrency,
|
||||||
|
basePrice: price
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
|
||||||
|
return ORDER
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO:
|
||||||
|
* - Hacer que el id sea coherente
|
||||||
|
* - Hacer que el precio sera coherente
|
||||||
|
*/
|
||||||
export const ORDER = new FieldPool<Shopify.Order>({
|
export const ORDER = new FieldPool<Shopify.Order>({
|
||||||
id: [1, 2, 3],
|
id: () => genId(8),
|
||||||
customer: CUSTOMER.randomValue,
|
customer: CUSTOMER.randomValue,
|
||||||
shipping_address: ADDRESS.randomValue,
|
shipping_address: ADDRESS.randomValue,
|
||||||
|
currency: () => pickCurrencies(CURRENCIES),
|
||||||
})
|
current_subtotal_price: () => generatePrice(2, 2),
|
||||||
|
current_subtotal_price_set: PRICE_SET.randomValue,
|
||||||
|
}, generateOrder)
|
||||||
|
|
||||||
export const INVALID_POOL = {
|
export const INVALID_POOL = {
|
||||||
|
|
||||||
|
|||||||
@@ -1,40 +1,47 @@
|
|||||||
import { Shopify } from "#data/webhooks/order.js";
|
import { Shopify } from "#data/webhooks/order.js";
|
||||||
import { FieldPool } from "./pool.type";
|
import { FieldPool, PoolOf } from "./pool.type";
|
||||||
|
import { CURRENCIES, generatePrice, pickCurrencies } from "./shared";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* shop_money y presentment_money tienen una correlacion que no entiendo. Necesitaria una
|
* shop_money y presentment_money tienen una correlacion que no entiendo. Necesitaria una
|
||||||
* funcion aleatoria nueva
|
* funcion aleatoria nueva
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
export function randomPriceSet(pricePool: PoolOf<Shopify.PriceSet>, opts?: {
|
||||||
|
baseCurrency?: string,
|
||||||
|
basePrice?: string,
|
||||||
|
}) {
|
||||||
|
const basePrice = opts?.basePrice ?? generatePrice(3, 2)
|
||||||
|
const currencies = {
|
||||||
|
shop: opts?.baseCurrency ?? pickCurrencies(CURRENCIES),
|
||||||
|
presentment: pickCurrencies(CURRENCIES)
|
||||||
|
}
|
||||||
|
let presentmentPrice = basePrice
|
||||||
|
if (currencies.shop != currencies.presentment) {
|
||||||
|
presentmentPrice = generatePrice(3, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
return <Shopify.PriceSet>{
|
||||||
|
shop_money: {
|
||||||
|
amount: basePrice,
|
||||||
|
currency_code: currencies.shop
|
||||||
|
},
|
||||||
|
presentment_money: {
|
||||||
|
amount: presentmentPrice,
|
||||||
|
currency_code: currencies.presentment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const PRICE_SET = new FieldPool<Shopify.PriceSet>({
|
export const PRICE_SET = new FieldPool<Shopify.PriceSet>({
|
||||||
shop_money: [
|
shop_money: () => ({
|
||||||
{
|
amount: generatePrice(3, 2),
|
||||||
amount: "100.00",
|
currency_code: pickCurrencies(CURRENCIES)
|
||||||
currency_code: "USD"
|
}),
|
||||||
},
|
presentment_money: () => ({
|
||||||
{
|
amount: generatePrice(3, 2),
|
||||||
amount: "45.50",
|
currency_code: pickCurrencies(CURRENCIES)
|
||||||
currency_code: "EUR"
|
}),
|
||||||
},
|
}, randomPriceSet)
|
||||||
{
|
|
||||||
amount: "12500",
|
|
||||||
currency_code: "JPY"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
presentment_money: [
|
|
||||||
{
|
|
||||||
amount: "100.00",
|
|
||||||
currency_code: "USD"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
amount: "39.95",
|
|
||||||
currency_code: "GBP"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
amount: "12500",
|
|
||||||
currency_code: "JPY"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { describe, test } from "vitest";
|
import { describe, expect, test } from "vitest";
|
||||||
import { ORDER } from "./ORDER";
|
import { ORDER } from "./ORDER";
|
||||||
import { CUSTOMER } from "./CUSTOMER";
|
import { CUSTOMER } from "./CUSTOMER";
|
||||||
import { ADDRESS } from "./ADDRESS";
|
import { ADDRESS } from "./ADDRESS";
|
||||||
@@ -10,19 +10,20 @@ describe("Test pool", () => {
|
|||||||
const costumers = [
|
const costumers = [
|
||||||
CUSTOMER.randomValue()
|
CUSTOMER.randomValue()
|
||||||
]
|
]
|
||||||
console.log("Costumers", costumers)
|
expect(costumers[0]).toBeDefined()
|
||||||
})
|
})
|
||||||
test("generacion de address", () => {
|
test("generacion de address", () => {
|
||||||
const costumers = [
|
const address = [
|
||||||
ADDRESS.randomValue()
|
ADDRESS.randomValue()
|
||||||
]
|
]
|
||||||
console.log("ADDRESS", costumers)
|
expect(address[0]).toBeDefined()
|
||||||
})
|
})
|
||||||
test("generacion de 3 order distintos", () => {
|
test("generacion de 3 order distintos", () => {
|
||||||
const orders = [
|
const orders = [
|
||||||
ORDER.randomValue(),
|
ORDER.randomValue(),
|
||||||
]
|
]
|
||||||
|
|
||||||
console.log(orders)
|
console.dir(orders, { depth: null })
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -7,9 +7,12 @@ import { NullablePartial } from "#shared/NullablePartail.js";
|
|||||||
* - Una funcion que devuelve un valor geneerado del mismo tipo que el campo original
|
* - Una funcion que devuelve un valor geneerado del mismo tipo que el campo original
|
||||||
*/
|
*/
|
||||||
export type PoolOf<T> = {
|
export type PoolOf<T> = {
|
||||||
[K in keyof T]: T[K][] | (() => T[K]);
|
//[K in keyof T]: T[K][] | (() => T[K]);
|
||||||
|
[K in keyof T]: PoolField<T[K]>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type PoolField<T> = T[] | (() => T);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
@@ -18,22 +21,26 @@ function getRandomOf<T>(pool: PoolOf<T>) {
|
|||||||
const options = pool
|
const options = pool
|
||||||
if (options == undefined) throw new Error("El campo no existe en la pool")
|
if (options == undefined) throw new Error("El campo no existe en la pool")
|
||||||
for (const optKey in options) {
|
for (const optKey in options) {
|
||||||
|
const field: PoolField<T[keyof T]> = options[optKey as keyof typeof options]
|
||||||
const field: T[keyof T][] | (() => T[keyof T]) = options[optKey as keyof typeof options]
|
const fieldValue = getRandomOfField(field)
|
||||||
if (field == undefined) continue;
|
mock[optKey as keyof typeof mock] = fieldValue // no se como resolver el tipo aqui, se confia que en el ejemplo esté bien
|
||||||
|
|
||||||
if (typeof field === "function") {
|
|
||||||
mock[optKey as keyof typeof mock] = field()
|
|
||||||
} else {
|
|
||||||
const examplesLen = field.length
|
|
||||||
if (examplesLen == undefined) continue;
|
|
||||||
const seleccionado = field[Math.floor(Math.random() * examplesLen)]
|
|
||||||
mock[optKey as keyof typeof mock] = seleccionado as any // no se como resolver el tipo aqui, se confia que en el ejemplo esté bien
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return mock
|
return mock
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getRandomOfField<T>(field: PoolField<T> | undefined) {
|
||||||
|
if (field == undefined) return undefined;
|
||||||
|
|
||||||
|
if (typeof field === "function") {
|
||||||
|
return field()
|
||||||
|
} else {
|
||||||
|
const examplesLen = field.length
|
||||||
|
if (examplesLen == undefined) return undefined;
|
||||||
|
const seleccionado = field[Math.floor(Math.random() * examplesLen)]
|
||||||
|
return seleccionado
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Un FieldPool es un wraper de PoolOf que asocia una funcion
|
* Un FieldPool es un wraper de PoolOf que asocia una funcion
|
||||||
* aleatoria personalizada al tipo de la pool
|
* aleatoria personalizada al tipo de la pool
|
||||||
@@ -46,13 +53,17 @@ export class FieldPool<T> {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
pool: PoolOf<T>,
|
pool: PoolOf<T>,
|
||||||
randFunc?: <T>(pool: PoolOf<T>) => T
|
randFunc?: (pool: PoolOf<T>) => T
|
||||||
) {
|
) {
|
||||||
this.pool = pool
|
this.pool = pool
|
||||||
if (randFunc != undefined) {
|
if (randFunc != undefined) {
|
||||||
this.randomFunc = randFunc
|
this.randomFunc = randFunc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static pickRandomOfField = getRandomOfField
|
||||||
|
public static pickRandomOf = getRandomOf
|
||||||
|
|
||||||
private randomFunc(pool: PoolOf<T>) {
|
private randomFunc(pool: PoolOf<T>) {
|
||||||
const mock: NullablePartial<T> = {}
|
const mock: NullablePartial<T> = {}
|
||||||
const options = pool
|
const options = pool
|
||||||
|
|||||||
14
src/data/data-pools/shared.ts
Normal file
14
src/data/data-pools/shared.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
export function generatePrice(enteros: number, decimales: number) {
|
||||||
|
return (Math.floor(Math.random() * (10 ^ enteros)) / (10 ^ decimales)).toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CURRENCIES = ["USD", "EUR", "JPY"]
|
||||||
|
|
||||||
|
export function pickCurrencies(currencies: string[]) {
|
||||||
|
if (currencies.length == 1) return currencies[0]
|
||||||
|
const max = currencies.length
|
||||||
|
const min = 0
|
||||||
|
const select = Math.floor(Math.random() * (max - min)) + min
|
||||||
|
return currencies[select]
|
||||||
|
}
|
||||||
4
src/data/webhooks/order.d.ts
vendored
4
src/data/webhooks/order.d.ts
vendored
@@ -147,6 +147,9 @@ export declare namespace Shopify {
|
|||||||
user_agent: string,
|
user_agent: string,
|
||||||
}>
|
}>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://shopify.dev/docs/api/admin-graphql/2026-01/objects/MoneyBag
|
||||||
|
*/
|
||||||
export type PriceSet = NullablePartial<{
|
export type PriceSet = NullablePartial<{
|
||||||
shop_money: {
|
shop_money: {
|
||||||
amount: string,
|
amount: string,
|
||||||
@@ -158,6 +161,7 @@ export declare namespace Shopify {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}>
|
}>
|
||||||
|
export type MoneyBag = PriceSet
|
||||||
|
|
||||||
// Webhook orders/create
|
// Webhook orders/create
|
||||||
export type OrderCreate = Order
|
export type OrderCreate = Order
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user