#!/bin/bash
# vim: set ft=sh
set -euo pipefail

psql ${DATABASE_NAME:-"disclosure-backend"} << SQL
/*
** View to capture all expenditures for ballot measures.
** Some committees formed to support/oppose a measure do
** do not report their expenditures as supporting/opposing
** the measure.
*/
DROP VIEW IF EXISTS "Measure_Expenditures";
CREATE VIEW "Measure_Expenditures" AS
  -- Map Expenduitures to the correct measure in the correct election.
-- The forms rarely have the election date field filled out.
WITH all_expend AS
  (
  SELECT
  "Filer_ID",
  "Filer_NamL",
  "Bal_Name",
  "Bal_Num",
  "Sup_Opp_Cd",
  "Amount",
  "Expn_Code",
  "Expn_Date",
  "Payee_NamL" as "Recipient_Or_Description",
  'E name' as "Form",
  "Tran_ID"
  FROM
  "E-Expenditure"
  UNION

  SELECT
  "Filer_ID",
  "Filer_NamL",
  "Bal_Name",
  "Bal_Num",
  "Sup_Opp_Cd",
  "Amount",
  'IND' as "Expn_Code",
  "Exp_Date" as "Expn_Date",
  "Expn_Dscr" as "Recipient_Or_Description",
  '496' as "Form",
  "Tran_ID"
  FROM
  "496"
  )
  -- Map names to numbers as ballot numbers are often missing
SELECT
  cast (expend."Filer_ID" as character varying),
  expend."Filer_NamL",
  election_name,
  "Bal_Name",
  "Measure_Number",
  "Sup_Opp_Cd",
  "Amount",
  "Expn_Code",
  "Expn_Date",
  "Recipient_Or_Description",
  "Form",
  "Tran_ID"
from all_expend  expend
  JOIN committees committee
      ON expend."Filer_ID"::varchar = committee."Filer_ID"::varchar
      AND ("Start_Date" IS NULL OR "Expn_Date" >= "Start_Date")
      AND ("End_Date" IS NULL OR "Expn_Date" <= "End_Date")
  JOIN name_to_number
      ON LOWER("Bal_Name") = LOWER("Measure_Name")
      AND election_name = "Ballot_Measure_Election"
  WHERE "Bal_Num" is NULL
UNION ALL
  -- If we have the number, still map to correct election and lookup name if needed.
SELECT
  cast (expend."Filer_ID" as character varying),
  expend."Filer_NamL",
  election_name,
  CASE
    WHEN "Bal_Name" IS NULL THEN "Measure_Name"
    ELSE "Bal_Name"
    END AS "Bal_Name",
  "Measure_Number",
  "Sup_Opp_Cd",
  "Amount",
  "Expn_Code",
  "Expn_Date",
  "Recipient_Or_Description",
  "Form",
  "Tran_ID"
from all_expend expend
  JOIN committees committee
      ON expend."Filer_ID"::varchar = committee."Filer_ID"::varchar
      AND ("Start_Date" IS NULL OR "Expn_Date" >= "Start_Date")
      AND ("End_Date" IS NULL OR "Expn_Date" <= "End_Date")
  JOIN (
    SELECT election_name, "Measure_Number", MAX("Measure_Name") as "Measure_Name"
    FROM name_to_number
    GROUP BY election_name, "Measure_Number"
  ) measure
    ON "Ballot_Measure_Election" = election_name
    AND "Bal_Num" = "Measure_Number"
    WHERE "Bal_Num" IS NOT NULL
    ;
;

DROP VIEW IF EXISTS combined_contributions;
DROP VIEW IF EXISTS candidate_contributions;
DROP VIEW IF EXISTS measure_contributions;
DROP VIEW IF EXISTS all_contributions;
CREATE VIEW  all_contributions AS
  SELECT "Filer_ID"::varchar, "Entity_Cd", "Tran_Amt1", "Tran_NamF",
    "Tran_NamL", "Tran_Date", "Tran_City", "Tran_State", "Tran_Zip4",
    "Tran_Occ", "Tran_Emp", "Committee_Type", "Cmte_ID", "Tran_ID"
  FROM "A-Contributions"
  UNION
  SELECT "Filer_ID"::varchar, "Entity_Cd", "Tran_Amt1", "Tran_NamF",
    "Tran_NamL", "Tran_Date", "Tran_City", "Tran_State", "Tran_Zip4",
    "Tran_Occ", "Tran_Emp", "Committee_Type", "Cmte_ID", "Tran_ID"
  FROM "C-Contributions"
  UNION
  SELECT
    "Filer_ID"::varchar,
    "Entity_Cd",
    "Amount" as "Tran_Amt1",
    "Enty_NamF" as "Tran_NamF",
    "Enty_NamL" as "Tran_NamL",
    "Ctrib_Date" as "Tran_Date",
    "Enty_City" as "Tran_City",
    "Enty_ST" as "Tran_State",
    "Enty_Zip4" as "Tran_Zip4",
    "Ctrib_Occ" as "Tran_Occ",
    "Ctrib_Emp" as "Tran_Emp",
    "Committee_Type", "Cmte_ID", "Tran_ID"
  FROM "497"
  WHERE "Form_Type" = 'F497P1';

CREATE VIEW candidate_contributions AS
  SELECT "Filer_ID", "Entity_Cd", "Tran_Amt1", "Tran_NamF",
      "Tran_NamL", "Tran_Date", "Tran_City", "Tran_State", "Tran_Zip4",
      "Tran_Occ", "Tran_Emp", elections.location, election_name,
      'Office'::VARCHAR as "Type", "Committee_Type"
FROM all_contributions
  JOIN candidates
  ON "FPPC"::varchar = all_contributions."Filer_ID"
  AND ("Start_Date" IS NULL OR "Tran_Date" >= "Start_Date")
  AND ("End_Date" IS NULL OR "Tran_Date" <= "End_Date")
  JOIN elections
  ON candidates.election_name = elections.name;

CREATE VIEW measure_contributions AS
  SELECT all_contributions."Filer_ID", "Entity_Cd", "Tran_Amt1", "Tran_NamF",
      "Tran_NamL", "Tran_Date", "Tran_City", "Tran_State", "Tran_Zip4",
      "Tran_Occ", "Tran_Emp", elections.location, elections.name AS election_name,
      'Measure'::VARCHAR as "Type", "Committee_Type"
FROM all_contributions
  JOIN (
    SELECT DISTINCT "Filer_ID", "Start_Date", "End_Date", "Ballot_Measure_Election"
    FROM committees
    WHERE "Ballot_Measure_Election" IS NOT NULL
  ) committees
  ON committees."Filer_ID" = all_contributions."Filer_ID"
  AND ("Start_Date" IS NULL OR "Tran_Date" >= "Start_Date")
  AND ("End_Date" IS NULL OR "Tran_Date" <= "End_Date")
  JOIN elections
  ON "Ballot_Measure_Election" = elections.name;

CREATE VIEW combined_contributions AS
  SELECT * from candidate_contributions
  UNION ALL
  SELECT * from measure_contributions;

DROP VIEW IF EXISTS independent_candidate_expenditures;
CREATE VIEW independent_candidate_expenditures AS
  SELECT election_name, "FPPC" AS "Cand_ID", all_data."Filer_ID", committee."Filer_NamL", "Exp_Date" AS "Expn_Date", "Sup_Opp_Cd", "Amount"
  FROM (
    SELECT "Filer_ID"::varchar, "Filer_NamL", "Exp_Date", "Cand_NamF", "Cand_NamL", "Amount", "Sup_Opp_Cd", "Tran_ID"
    FROM "496"
    UNION
    SELECT "Filer_ID", "Filer_NamL", "Expn_Date" as "Exp_Date", "Cand_NamF", "Cand_NamL",
    "Amount", "Sup_Opp_Cd", "Tran_ID"
    FROM "D-Expenditure"
    WHERE "Expn_Code" = 'IND'
  ) AS all_data
  JOIN "candidates" c
  ON LOWER(TRIM(CONCAT("Cand_NamF", ' ', "Cand_NamL"))) = LOWER("Candidate")
    OR LOWER("Aliases") LIKE LOWER(CONCAT('%', TRIM(CONCAT("Cand_NamF", ' ', "Cand_NamL")), '%'))
  JOIN elections e
  ON c.election_name = e.name
  JOIN
  (
    -- TODO: possible join on "Ballot_Measure_Election"
    SELECT "Filer_ID", "Filer_NamL" 
    FROM (
      SELECT "Filer_ID", "Filer_NamL", ROW_NUMBER() OVER (PARTITION BY "Filer_ID" ORDER BY "Ballot_Measure_Election" DESC NULLS LAST) AS rn
      FROM committees
    ) AS c 
    WHERE rn=1
  ) committee
  ON committee."Filer_ID" = all_data."Filer_ID"
  WHERE (e."Start_Date" IS NULL OR "Exp_Date" >= e."Start_Date")
  AND (e."End_Date" IS NULL OR "Exp_Date" <= e."End_Date")
  AND "FPPC" IS NOT NULL
  AND "FPPC" IS NOT NULL
  AND "Cand_NamL" IS NOT NULL;

-- Remove summary data that is covered by a report that includes that time period
DROP VIEW IF EXISTS clean_summary CASCADE;
CREATE VIEW clean_summary AS
  SELECT * from "Summary" s
  WHERE
  NOT EXISTS
    (select t."Rpt_Date" from "Summary" t where s."Filer_ID" = t."Filer_ID"
    and t."From_Date" <= s."From_Date" and s."Thru_Date" <= t."Thru_Date"
    and (t."From_Date" <> s."From_Date" or s."Thru_Date" <> t."Thru_Date")
    )
;

DROP VIEW IF EXISTS candidate_summary;
CREATE VIEW candidate_summary AS
  SELECT election_name, "Candidate", s.*
  FROM clean_summary s, candidates c
  WHERE cast ("FPPC" as character varying) = "Filer_ID"
  AND ("Start_Date" IS NULL OR "From_Date" >= "Start_Date")
  AND ("End_Date" IS NULL OR "Thru_Date" <= "End_Date");

DROP VIEW IF EXISTS candidate_497;
CREATE VIEW candidate_497 AS
  SELECT election_name, "Candidate", l.*
  FROM "497" l, candidates c
  WHERE cast ("FPPC" as character varying) = "Filer_ID"
  AND ("Start_Date" IS NULL OR "Ctrib_Date" >= "Start_Date")
  AND ("End_Date" IS NULL OR "Ctrib_Date" <= "End_Date");

DROP VIEW IF EXISTS candidate_e_expenditure;
CREATE VIEW candidate_e_expenditure AS
  SELECT election_name, expend.*
  FROM "E-Expenditure" expend, candidates c
  WHERE expend."Filer_ID"::varchar = c."FPPC"::varchar
  AND ("Start_Date" IS NULL OR "Expn_Date" >= "Start_Date")
  AND ("End_Date" IS NULL OR "Expn_Date" <= "End_Date");

DROP VIEW IF EXISTS candidate_d_expenditure;
CREATE VIEW candidate_d_expenditure AS
  SELECT c.election_name, c."FPPC", expend.*
  FROM "D-Expenditure" expend, candidates c
  WHERE lower(c."Candidate") = lower(trim(concat(expend."Cand_NamF", ' ', expend."Cand_NamL")))
  AND ("Start_Date" IS NULL OR "Expn_Date" >= "Start_Date")
  AND ("End_Date" IS NULL OR "Expn_Date" <= "End_Date");

DROP VIEW IF EXISTS candidate_496;
CREATE VIEW candidate_496 AS
  SELECT c.election_name, c."FPPC", expend.*
  FROM "496" expend, candidates c
  WHERE lower(c."Candidate") = lower(trim(concat(expend."Cand_NamF", ' ', expend."Cand_NamL")))
  AND ("Start_Date" IS NULL OR "Exp_Date" >= "Start_Date")
  AND ("End_Date" IS NULL OR "Exp_Date" <= "End_Date");

SQL
