use billing;

delimiter ;;

drop procedure if exists del_dupes;
create procedure del_dupes()
begin
  declare done int default false;
  declare cid, c int;
  declare s, e datetime;
  declare x cursor for select contract_id, start, end, count(*) ct
    from contract_balances group by contract_id, start, end having ct > 1;
  declare continue handler for sqlstate '02000' set done = true;

  open x;

  rl: loop
    fetch x into cid, s, e, c;
    if done then
      leave rl;
    end if;
    set c = c - 1;
    delete from contract_balances where contract_id = cid and start = s
      and end = e and cash_balance = 0 and cash_balance_interval = 0 and
      free_time_balance = 0 and free_time_balance_interval = 0
      and invoice_id is null limit c;
  end loop;

  close x;
end;;

delimiter ;
call del_dupes;
drop procedure del_dupes;



-- If this throws an error, then the contracts_balances table contains entries
-- that the above procedure could not delete, which are duplicate entries with
-- non-zero balances. Manual cleanup is required.

alter table contract_balances
  add unique key balance_interval (contract_id, start, end),
  drop key contractid_idx;
