You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
68 lines
2.2 KiB
68 lines
2.2 KiB
/**
|
|
* Reglas de la tienda.
|
|
*
|
|
* Las canciones se venden en packs cerrados de diez: no hay precio por tema
|
|
* suelto, y el pago se bloquea hasta que el carrito tiene un multiplo de diez.
|
|
* Toda esa aritmetica vive aqui, en funciones puras, porque la usan por igual
|
|
* la pagina del carrito y la accion de pago del servidor, y no puede haber dos
|
|
* versiones del calculo.
|
|
*
|
|
* Diez canciones por el precio de un cafe. Es la propuesta, y por eso el numero
|
|
* y el importe se leen juntos en todas partes: sueltos no dicen nada.
|
|
*/
|
|
|
|
/** Canciones que componen un pack. */
|
|
export const CANCIONES_POR_PACK = 10;
|
|
|
|
/** Precio de un pack, en centimos. */
|
|
export const PRECIO_PACK_CENTIMOS = 150;
|
|
|
|
export const MONEDA = 'eur';
|
|
|
|
export interface ResumenCarrito {
|
|
/** Canciones en el carrito. */
|
|
canciones: number;
|
|
/** Packs completos que se van a cobrar. */
|
|
packs: number;
|
|
/** Canciones que faltan para cerrar el pack empezado. */
|
|
faltan: number;
|
|
/** `true` cuando el carrito se puede pagar. */
|
|
completo: boolean;
|
|
/** Importe a cobrar, en centimos. Solo tiene sentido si `completo`. */
|
|
totalCentimos: number;
|
|
}
|
|
|
|
export function resumirCarrito(canciones: number): ResumenCarrito {
|
|
const n = Math.max(0, Math.floor(canciones));
|
|
const resto = n % CANCIONES_POR_PACK;
|
|
const packs = Math.floor(n / CANCIONES_POR_PACK);
|
|
|
|
return {
|
|
canciones: n,
|
|
packs,
|
|
faltan: resto === 0 ? 0 : CANCIONES_POR_PACK - resto,
|
|
completo: n > 0 && resto === 0,
|
|
totalCentimos: packs * PRECIO_PACK_CENTIMOS
|
|
};
|
|
}
|
|
|
|
/** "1,50 €" */
|
|
export function formatearPrecio(centimos: number, locale = 'es-ES'): string {
|
|
return new Intl.NumberFormat(locale, {
|
|
style: 'currency',
|
|
currency: MONEDA.toUpperCase()
|
|
}).format(centimos / 100);
|
|
}
|
|
|
|
/** Mensaje que explica que le falta al carrito para poder pagarse. */
|
|
export function mensajeDeCarrito(resumen: ResumenCarrito): string {
|
|
if (resumen.canciones === 0) return 'El carrito está vacío.';
|
|
if (resumen.completo) {
|
|
const packs = resumen.packs === 1 ? '1 pack' : `${resumen.packs} packs`;
|
|
return `${packs} de ${CANCIONES_POR_PACK} canciones.`;
|
|
}
|
|
return resumen.faltan === 1
|
|
? 'Falta 1 canción para completar el pack.'
|
|
: `Faltan ${resumen.faltan} canciones para completar el pack.`;
|
|
}
|