mirror of
https://origin.cursor.com/mrdevmx/panels.git
synced 2026-10-09 18:23:22 +00:00
Reutiliza el catálogo de proveedores y agrega carga de facturas, conceptos de la semana, préstamos editables, finiquitos, dispersión, historial de personal, reportes y jornal de cotización. Co-authored-by: alberto.martinez <alberto.martinez@mrdev.mx>
160 lines
7.6 KiB
PL/PgSQL
160 lines
7.6 KiB
PL/PgSQL
--liquibase formatted sql
|
|
-- PANELS · core · datos fiscales de proveedores y filtro de listado
|
|
|
|
--changeset panel:core-042a-supplier-fiscal-cols endDelimiter:; splitStatements:true
|
|
ALTER TABLE core.suppliers
|
|
ADD COLUMN IF NOT EXISTS regimen_fiscal TEXT NOT NULL DEFAULT '';
|
|
|
|
--changeset panel:core-042b-fn-supplier-list splitStatements:false
|
|
CREATE OR REPLACE FUNCTION core.fn_supplier_list(payload jsonb)
|
|
RETURNS jsonb
|
|
LANGUAGE plpgsql
|
|
SECURITY INVOKER
|
|
SET search_path = core
|
|
AS $$
|
|
DECLARE
|
|
v_tid integer := core._cost_tenant_id(payload);
|
|
v_status text := nullif(btrim(payload->>'status'), '');
|
|
v_q text := lower(coalesce(nullif(btrim(payload->>'q'), ''), ''));
|
|
v_rows jsonb;
|
|
BEGIN
|
|
SELECT COALESCE(jsonb_agg(to_jsonb(s) ORDER BY lower(s.name), s.id), '[]'::jsonb)
|
|
INTO v_rows
|
|
FROM suppliers s
|
|
WHERE s.tenant_id = v_tid
|
|
AND (v_status IS NULL OR s.status = v_status)
|
|
AND (
|
|
v_q = ''
|
|
OR lower(s.name) LIKE '%' || v_q || '%'
|
|
OR lower(s.legal_name) LIKE '%' || v_q || '%'
|
|
OR lower(s.rfc) LIKE '%' || v_q || '%'
|
|
);
|
|
RETURN core.rpc_ok(
|
|
jsonb_build_object('suppliers', v_rows, 'count', jsonb_array_length(v_rows)),
|
|
format('Catálogo de proveedores: %s registro(s) para tenant %s', jsonb_array_length(v_rows), v_tid),
|
|
jsonb_build_object('fn', 'fn_supplier_list', 'tenant_id', v_tid, 'count', jsonb_array_length(v_rows))
|
|
);
|
|
EXCEPTION WHEN OTHERS THEN
|
|
RETURN core.rpc_from_exception('fn_supplier_list', SQLSTATE, SQLERRM);
|
|
END;
|
|
$$;
|
|
|
|
--changeset panel:core-042c-fn-supplier-create splitStatements:false
|
|
CREATE OR REPLACE FUNCTION core.fn_supplier_create(payload jsonb)
|
|
RETURNS jsonb
|
|
LANGUAGE plpgsql
|
|
SECURITY INVOKER
|
|
SET search_path = core
|
|
AS $$
|
|
DECLARE
|
|
v_tid integer := core._cost_tenant_id(payload);
|
|
v_name text := coalesce(nullif(btrim(payload->>'name'), ''), '');
|
|
v_legal text := coalesce(nullif(btrim(payload->>'legal_name'), ''), '');
|
|
v_rfc text := upper(regexp_replace(coalesce(payload->>'rfc', ''), '\s+', '', 'g'));
|
|
v_email text := coalesce(nullif(btrim(payload->>'email'), ''), '');
|
|
v_phone text := coalesce(nullif(btrim(payload->>'phone'), ''), '');
|
|
v_address text := coalesce(nullif(btrim(payload->>'address'), ''), '');
|
|
v_city text := coalesce(nullif(btrim(payload->>'city'), ''), '');
|
|
v_state text := coalesce(nullif(btrim(payload->>'state'), ''), '');
|
|
v_zip text := coalesce(nullif(btrim(payload->>'postal_code'), ''), '');
|
|
v_regimen text := coalesce(nullif(btrim(payload->>'regimen_fiscal'), ''), '');
|
|
v_notes text := coalesce(nullif(btrim(payload->>'notes'), ''), '');
|
|
v_status text := coalesce(nullif(btrim(payload->>'status'), ''), 'activo');
|
|
v_id bigint;
|
|
v_row jsonb;
|
|
BEGIN
|
|
IF v_name = '' THEN
|
|
RETURN core.rpc_err('VALIDATION', 'fn_supplier_create: el nombre del proveedor es obligatorio',
|
|
jsonb_build_object('fn', 'fn_supplier_create', 'field', 'name'));
|
|
END IF;
|
|
IF v_rfc <> '' AND char_length(v_rfc) NOT IN (12, 13) THEN
|
|
RETURN core.rpc_err('VALIDATION', format('fn_supplier_create: RFC %s no tiene 12 o 13 caracteres', v_rfc),
|
|
jsonb_build_object('fn', 'fn_supplier_create', 'field', 'rfc'));
|
|
END IF;
|
|
IF v_status NOT IN ('activo', 'inactivo') THEN
|
|
RETURN core.rpc_err('VALIDATION', 'fn_supplier_create: status debe ser activo o inactivo',
|
|
jsonb_build_object('fn', 'fn_supplier_create', 'field', 'status'));
|
|
END IF;
|
|
INSERT INTO suppliers (
|
|
tenant_id, name, legal_name, rfc, email, phone, address, city, state, postal_code,
|
|
regimen_fiscal, notes, status
|
|
) VALUES (
|
|
v_tid, v_name, v_legal, v_rfc, v_email, v_phone, v_address, v_city, v_state, v_zip,
|
|
v_regimen, v_notes, v_status
|
|
) RETURNING id INTO v_id;
|
|
SELECT to_jsonb(s) INTO v_row FROM suppliers s WHERE id = v_id;
|
|
RETURN core.rpc_created(
|
|
jsonb_build_object('supplier', v_row),
|
|
format('Proveedor %s registrado', v_name),
|
|
jsonb_build_object('fn', 'fn_supplier_create', 'id', v_id, 'tenant_id', v_tid)
|
|
);
|
|
EXCEPTION
|
|
WHEN unique_violation THEN
|
|
RETURN core.rpc_err('CONFLICT', format('Ya existe un proveedor con RFC %s en este tenant', v_rfc),
|
|
jsonb_build_object('fn', 'fn_supplier_create', 'rfc', v_rfc));
|
|
WHEN OTHERS THEN
|
|
RETURN core.rpc_from_exception('fn_supplier_create', SQLSTATE, SQLERRM);
|
|
END;
|
|
$$;
|
|
|
|
--changeset panel:core-042d-fn-supplier-update splitStatements:false
|
|
CREATE OR REPLACE FUNCTION core.fn_supplier_update(payload jsonb)
|
|
RETURNS jsonb
|
|
LANGUAGE plpgsql
|
|
SECURITY INVOKER
|
|
SET search_path = core
|
|
AS $$
|
|
DECLARE
|
|
v_id bigint := NULLIF(payload->>'id', '')::bigint;
|
|
v_tid integer := core._cost_tenant_id(payload);
|
|
v_rfc text;
|
|
v_status text;
|
|
v_row jsonb;
|
|
BEGIN
|
|
IF v_id IS NULL THEN
|
|
RETURN core.rpc_err('VALIDATION', 'fn_supplier_update: id es obligatorio',
|
|
jsonb_build_object('fn', 'fn_supplier_update', 'field', 'id'));
|
|
END IF;
|
|
IF NOT EXISTS (SELECT 1 FROM suppliers WHERE id = v_id AND tenant_id = v_tid) THEN
|
|
RETURN core.rpc_err('NOT_FOUND', format('fn_supplier_update: proveedor id=%s no encontrado', v_id),
|
|
jsonb_build_object('fn', 'fn_supplier_update', 'id', v_id));
|
|
END IF;
|
|
v_rfc := upper(regexp_replace(coalesce(payload->>'rfc', ''), '\s+', '', 'g'));
|
|
IF payload ? 'rfc' AND v_rfc <> '' AND char_length(v_rfc) NOT IN (12, 13) THEN
|
|
RETURN core.rpc_err('VALIDATION', format('fn_supplier_update: RFC %s no tiene 12 o 13 caracteres', v_rfc),
|
|
jsonb_build_object('fn', 'fn_supplier_update', 'field', 'rfc'));
|
|
END IF;
|
|
v_status := nullif(btrim(payload->>'status'), '');
|
|
IF payload ? 'status' AND v_status NOT IN ('activo', 'inactivo') THEN
|
|
RETURN core.rpc_err('VALIDATION', 'fn_supplier_update: status debe ser activo o inactivo',
|
|
jsonb_build_object('fn', 'fn_supplier_update', 'field', 'status'));
|
|
END IF;
|
|
UPDATE suppliers SET
|
|
name = CASE WHEN payload ? 'name' THEN coalesce(nullif(btrim(payload->>'name'), ''), name) ELSE name END,
|
|
legal_name = CASE WHEN payload ? 'legal_name' THEN coalesce(nullif(btrim(payload->>'legal_name'), ''), '') ELSE legal_name END,
|
|
rfc = CASE WHEN payload ? 'rfc' THEN v_rfc ELSE rfc END,
|
|
email = CASE WHEN payload ? 'email' THEN coalesce(nullif(btrim(payload->>'email'), ''), '') ELSE email END,
|
|
phone = CASE WHEN payload ? 'phone' THEN coalesce(nullif(btrim(payload->>'phone'), ''), '') ELSE phone END,
|
|
address = CASE WHEN payload ? 'address' THEN coalesce(nullif(btrim(payload->>'address'), ''), '') ELSE address END,
|
|
city = CASE WHEN payload ? 'city' THEN coalesce(nullif(btrim(payload->>'city'), ''), '') ELSE city END,
|
|
state = CASE WHEN payload ? 'state' THEN coalesce(nullif(btrim(payload->>'state'), ''), '') ELSE state END,
|
|
postal_code = CASE WHEN payload ? 'postal_code' THEN coalesce(nullif(btrim(payload->>'postal_code'), ''), '') ELSE postal_code END,
|
|
regimen_fiscal = CASE WHEN payload ? 'regimen_fiscal' THEN coalesce(nullif(btrim(payload->>'regimen_fiscal'), ''), '') ELSE regimen_fiscal END,
|
|
notes = CASE WHEN payload ? 'notes' THEN coalesce(nullif(btrim(payload->>'notes'), ''), '') ELSE notes END,
|
|
status = CASE WHEN payload ? 'status' THEN v_status ELSE status END,
|
|
updated_at = now()
|
|
WHERE id = v_id AND tenant_id = v_tid;
|
|
SELECT to_jsonb(s) INTO v_row FROM suppliers s WHERE id = v_id;
|
|
RETURN core.rpc_ok(
|
|
jsonb_build_object('supplier', v_row),
|
|
format('Proveedor id=%s actualizado', v_id),
|
|
jsonb_build_object('fn', 'fn_supplier_update', 'id', v_id)
|
|
);
|
|
EXCEPTION
|
|
WHEN unique_violation THEN
|
|
RETURN core.rpc_err('CONFLICT', 'Ya existe otro proveedor con ese RFC en este tenant',
|
|
jsonb_build_object('fn', 'fn_supplier_update', 'id', v_id));
|
|
WHEN OTHERS THEN
|
|
RETURN core.rpc_from_exception('fn_supplier_update', SQLSTATE, SQLERRM);
|
|
END;
|
|
$$;
|