feat(F-189): completed feature
This commit is contained in:
94
project/migrations/056_pos_return_lines.js
Normal file
94
project/migrations/056_pos_return_lines.js
Normal file
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* F-189 — POS returns per-line counters + pos_returns table.
|
||||
*
|
||||
* 1. Adds `orders_items.returned_quantity integer NOT NULL DEFAULT 0` with
|
||||
* `CHECK (returned_quantity >= 0 AND returned_quantity <= quantity)`.
|
||||
* 2. Creates `pos_returns` as the historical ledger of returns with a unique
|
||||
* `(order_id, idempotency_key)` index for replay.
|
||||
* 3. Allows `'return'` in `inventory_movements.operation` so cashiers can
|
||||
* see the movement in inventory history.
|
||||
*
|
||||
* @param {import('node-pg-migrate').MigrationBuilder} pgm
|
||||
*/
|
||||
|
||||
export const up = (pgm) => {
|
||||
// ── orders_items.returned_quantity ─────────────────────────────────────
|
||||
pgm.sql(`
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'orders_items' AND column_name = 'returned_quantity'
|
||||
) THEN
|
||||
ALTER TABLE orders_items
|
||||
ADD COLUMN returned_quantity integer NOT NULL DEFAULT 0;
|
||||
END IF;
|
||||
END $$
|
||||
`);
|
||||
pgm.sql(`ALTER TABLE orders_items DROP CONSTRAINT IF EXISTS orders_items_returned_quantity_check`);
|
||||
pgm.sql(`
|
||||
ALTER TABLE orders_items
|
||||
ADD CONSTRAINT orders_items_returned_quantity_check
|
||||
CHECK (returned_quantity >= 0 AND returned_quantity <= quantity)
|
||||
`);
|
||||
|
||||
// ── inventory_movements.operation — allow 'return' ─────────────────────
|
||||
pgm.sql(`ALTER TABLE inventory_movements DROP CONSTRAINT IF EXISTS inventory_movements_operation_check`);
|
||||
pgm.sql(`
|
||||
ALTER TABLE inventory_movements
|
||||
ADD CONSTRAINT inventory_movements_operation_check
|
||||
CHECK (operation IN ('reserve','release','confirm','set_available','return'))
|
||||
`);
|
||||
|
||||
// ── pos_returns ─────────────────────────────────────────────────────────
|
||||
pgm.createTable('pos_returns', {
|
||||
id: { type: 'uuid', primaryKey: true, default: pgm.func('gen_random_uuid()') },
|
||||
order_id: { type: 'uuid', notNull: true, references: 'orders_orders(id)', onDelete: 'RESTRICT' },
|
||||
idempotency_key: { type: 'text', notNull: true },
|
||||
terminal_id: { type: 'uuid', notNull: true, references: 'pos_terminals(id)', onDelete: 'RESTRICT' },
|
||||
cash_session_id: { type: 'uuid', notNull: true, references: 'pos_cash_sessions(id)', onDelete: 'RESTRICT' },
|
||||
store_id: { type: 'uuid', notNull: true, references: 'pos_stores(id)', onDelete: 'RESTRICT' },
|
||||
user_id: { type: 'uuid', notNull: true, references: 'backoffice_users(id)', onDelete: 'RESTRICT' },
|
||||
total_cents: { type: 'integer', notNull: true, check: 'total_cents > 0' },
|
||||
status: {
|
||||
type: 'text',
|
||||
notNull: true,
|
||||
check: "status IN ('refund','partial_refund')",
|
||||
},
|
||||
reason: { type: 'text', notNull: true },
|
||||
created_at: { type: 'timestamptz', notNull: true, default: pgm.func('now()') },
|
||||
});
|
||||
pgm.sql(`
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS pos_returns_idempotency_unique_idx
|
||||
ON pos_returns (order_id, idempotency_key)
|
||||
`);
|
||||
pgm.createIndex('pos_returns', ['store_id', 'created_at'], {
|
||||
name: 'pos_returns_store_created_idx',
|
||||
});
|
||||
pgm.createIndex('pos_returns', 'terminal_id', {
|
||||
name: 'pos_returns_terminal_idx',
|
||||
where: 'terminal_id IS NOT NULL',
|
||||
});
|
||||
};
|
||||
|
||||
export const down = (pgm) => {
|
||||
pgm.dropTable('pos_returns', { ifExists: true });
|
||||
pgm.sql(`ALTER TABLE inventory_movements DROP CONSTRAINT IF EXISTS inventory_movements_operation_check`);
|
||||
pgm.sql(`
|
||||
ALTER TABLE inventory_movements
|
||||
ADD CONSTRAINT inventory_movements_operation_check
|
||||
CHECK (operation IN ('reserve','release','confirm','set_available'))
|
||||
`);
|
||||
pgm.sql(`ALTER TABLE orders_items DROP CONSTRAINT IF EXISTS orders_items_returned_quantity_check`);
|
||||
pgm.sql(`
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'orders_items' AND column_name = 'returned_quantity'
|
||||
) THEN
|
||||
ALTER TABLE orders_items DROP COLUMN returned_quantity;
|
||||
END IF;
|
||||
END $$
|
||||
`);
|
||||
};
|
||||
Reference in New Issue
Block a user