Files
Qris-Soundbox/dist/shared/store/locationStore.js

173 lines
5.4 KiB
JavaScript

import { randomUUID } from "node:crypto";
import { getPool } from "../db/pool";
function nowIso() {
return new Date().toISOString();
}
function makeCode(prefix, id) {
return `${prefix}_${id.slice(0, 6)}`;
}
function mapOutlet(row) {
return {
id: row.id,
merchant_id: row.merchant_id,
outlet_code: row.outlet_code,
name: row.name,
address: row.address || undefined,
status: row.status,
created_at: row.created_at,
updated_at: row.updated_at
};
}
function mapTerminal(row) {
return {
id: row.id,
outlet_id: row.outlet_id,
terminal_code: row.terminal_code,
qr_mode: row.qr_mode,
partner_reference: row.partner_reference || undefined,
status: row.status,
created_at: row.created_at,
updated_at: row.updated_at
};
}
export async function createOutlet(payload) {
const id = randomUUID();
const now = nowIso();
const { rows } = await getPool().query(`INSERT INTO outlets (id, merchant_id, outlet_code, name, address, status, created_at, updated_at)
VALUES ($1,$2,$3,$4,$5,$6,$7,$8)
RETURNING *`, [
id,
payload.merchant_id,
payload.outlet_code || makeCode("out", id),
payload.name,
payload.address,
payload.status || "active",
now,
now
]);
return mapOutlet(rows[0]);
}
export async function createTerminal(payload) {
const id = randomUUID();
const now = nowIso();
const { rows } = await getPool().query(`INSERT INTO terminals (id, outlet_id, terminal_code, qr_mode, partner_reference, status, created_at, updated_at)
VALUES ($1,$2,$3,$4,$5,$6,$7,$8)
RETURNING *`, [
id,
payload.outlet_id,
payload.terminal_code || makeCode("term", id),
payload.qr_mode || "static",
payload.partner_reference || null,
payload.status || "active",
now,
now
]);
return mapTerminal(rows[0]);
}
export async function listOutlets(filter) {
const clauses = [];
const params = [];
let i = 1;
if (filter?.merchant_id) {
clauses.push(`merchant_id = $${i++}`);
params.push(filter.merchant_id);
}
if (filter?.status) {
clauses.push(`status = $${i++}`);
params.push(filter.status);
}
if (filter?.q) {
const value = `%${filter.q.toLowerCase()}%`;
clauses.push(`(LOWER(name) LIKE $${i++} OR LOWER(outlet_code) LIKE $${i++})`);
params.push(value, value);
}
const where = clauses.length ? `WHERE ${clauses.join(" AND ")}` : "";
const { rows } = await getPool().query(`SELECT * FROM outlets ${where} ORDER BY created_at DESC`, params);
return rows.map(mapOutlet);
}
export async function listTerminals(filter) {
const clauses = [];
const params = [];
let i = 1;
if (filter?.outlet_id) {
clauses.push(`outlet_id = $${i++}`);
params.push(filter.outlet_id);
}
if (filter?.status) {
clauses.push(`status = $${i++}`);
params.push(filter.status);
}
if (filter?.q) {
const value = `%${filter.q.toLowerCase()}%`;
clauses.push(`(LOWER(terminal_code) LIKE $${i++} OR LOWER(COALESCE(partner_reference, '')) LIKE $${i++})`);
params.push(value, value);
}
const where = clauses.length ? `WHERE ${clauses.join(" AND ")}` : "";
const { rows } = await getPool().query(`SELECT * FROM terminals ${where} ORDER BY created_at DESC`, params);
return rows.map(mapTerminal);
}
export async function getOutletById(id) {
const { rows } = await getPool().query("SELECT * FROM outlets WHERE id = $1", [id]);
return rows[0] ? mapOutlet(rows[0]) : null;
}
export async function getTerminalById(id) {
const { rows } = await getPool().query("SELECT * FROM terminals WHERE id = $1", [id]);
return rows[0] ? mapTerminal(rows[0]) : null;
}
export async function patchOutlet(id, patch) {
const existing = await getOutletById(id);
if (!existing) {
throw new Error("OUTLET_NOT_FOUND");
}
const merged = { ...existing, ...patch, updated_at: nowIso() };
const { rows } = await getPool().query(`UPDATE outlets
SET merchant_id = $2,
outlet_code = $3,
name = $4,
address = $5,
status = $6,
updated_at = $7
WHERE id = $1
RETURNING *`, [
id,
merged.merchant_id,
merged.outlet_code,
merged.name,
merged.address || null,
merged.status,
merged.updated_at
]);
return mapOutlet(rows[0]);
}
export async function patchTerminal(id, patch) {
const existing = await getTerminalById(id);
if (!existing) {
throw new Error("TERMINAL_NOT_FOUND");
}
const merged = { ...existing, ...patch, updated_at: nowIso() };
const { rows } = await getPool().query(`UPDATE terminals
SET outlet_id = $2,
terminal_code = $3,
qr_mode = $4,
partner_reference = $5,
status = $6,
updated_at = $7
WHERE id = $1
RETURNING *`, [
id,
merged.outlet_id,
merged.terminal_code,
merged.qr_mode,
merged.partner_reference || null,
merged.status,
merged.updated_at
]);
return mapTerminal(rows[0]);
}
export function toOutletPayload(outlet) {
return { ...outlet };
}
export function toTerminalPayload(terminal) {
return { ...terminal };
}