package app.model;

import javax.swing.table.*;
import java.sql.*;


/**
 * Loan.java
 *
 * Selve låneklassen inneholder lånet.
 * Her opprettes nedbetalingsplan.
 *
 * @author Hilde Vestøl (106288)
 * @version 0.9
 */

 

public class Loan extends AbstractTableModel {

    /* Har lagt inn konstanter for lettere tilgang til å endre verdier
     * og for lettere lesing av koden.
     * Gjort public static for bruk i andre klasser
     */

    public static final int TYPE_ANNUITET = 1;  
    public static final int TYPE_SERIELL = 2;  
    
    public static final int TERMIN_ÅRLIG = 1;
    public static final int TERMIN_HALVÅR = 2;
    public static final int TERMIN_KVARTAL = 4;
    public static final int TERMIN_MND = 12;
    
    /* Konstanter for lettere lesing/endring. Disse er
     * private, og kun til bruk i denne klassen
     */

    private final int GEBYR_ÅRLIG = 150;
    private final int GEBYR_HALVÅR = 100;
    private final int GEBYR_KVARTAL = 75;
    private final int GEBYR_MND = 50;
    
    private final int MAX_LØPETID = 40;
    
    private Nedbetalingsplan nedbetalingsplan;
    
    private boolean lånetErEndret = false;
    
    private int     låneNr;         //1000 - 9999
    private int     lånebeløp;      //skal være hele kr, derfor int
    private int     løpetid;        //maks 40 år
    private int     årligeTerminer; // 1, 2, 4, 12
    private int     lånetype;       //1 for annuitet, 2 for seriell
    private double  rentesats;      //tall mellom 1-100, gjøres til prosent
    
  /*************************************************************************
   * Konstruktør                                                           *
   * Sjekk av inndata skjer i egne metoder for enklere oversikt over koden *
   *************************************************************************/

    
    //En tom konstruktør. Verdiene settes i set-metodene.
    public Loan () {
        this.nedbetalingsplan = new Nedbetalingsplan(this);
    }
    
    /**
     * Konstruktør som kun tar i låneID.
     *
     * Jeg ser på database som en del av modellen. Derfor har jeg laget
     * en egen klasse DatabaseTilkobling i model pakken, og jeg kaller
     * statiske metoder derfra i Loan.
     *
     * På den måten kan controlleren min fortsatt kun "prate" med
     * Loan og Vindu. Og modell og view er adskilt (etter min definisjon).
     *
     * @param låneID
     * @throws SQLException
     * @throws LoanException  
     */

    public Loan(int låneID) throws SQLException, LoanException {
        DatabaseTilkobling.findFromDB( låneID, this );
        this.nedbetalingsplan = new Nedbetalingsplan(this);
        lånetErEndret = false;
    }
    
    /**
     * Konstruktør som tar inn alle parametere ett lån trenger.
     *
     * @param låneNr
     * @param lånebeløp
     * @param løpetid
     * @param årligeTerminer
     * @param lånetype
     * @param rentesats
     * @throws LoanException
     */

    public Loan (int låneNr, int lånebeløp, int løpetid, int årligeTerminer,
                 int lånetype, double rentesats) throws LoanException {
        setLåneNr(låneNr);
        setLånebeløp(lånebeløp);
        setLøpetid(løpetid);
        setÅrligeTerminer(årligeTerminer);
        setLånetype(lånetype);
        setRentesats(rentesats);
        this.nedbetalingsplan = new Nedbetalingsplan(this);
    }
    
    
    /**
     * En metode for å lagre lånet i en database.
     * Bruker klassen DatabaseTilkobling
     * @return
     */

    public boolean save() {
        try {
            DatabaseTilkobling.saveToDB(this);
            lånetErEndret = false;
            return true;
        }
        catch (Exception e) {
            System.out.println("Feil i save(): " + e);
            return false;
        }
     }
    
    /**
     *
     * @param lånenr
     * @throws SQLException
     */

    public static void delete(int lånenr) throws SQLException {
        DatabaseTilkobling.deleteFromDB(lånenr);
    }
    

  /*************************************************************************
   * Hjelpemetododer                                                       *
   *************************************************************************/

 
    /**
     * @return
     */

    @Override
    public String toString() {
        String låneTypeTxt = "";
        if (lånetype == TYPE_ANNUITET)
            låneTypeTxt =  "Annuitet";
        else
            låneTypeTxt = "Seriell";
        
        return "Lånenr: " + låneNr + "\nLånebeløp: " + lånebeløp
                + "\nLøpetid: " + løpetid
                + "\nÅrlige Terminer: " + årligeTerminer
                + "\nLånetype :" + låneTypeTxt
                + "\nRentesats: " + rentesats + "%" ;
    }   

  /*************************************************************************
   * Metodene gitt i oppgaveteksten                                        *
   *************************************************************************/

     
    /**
     * Oppretter en nedbetalingsplan, og lager en terminListe
     *
     * @return nedbetalingsplanen.
     */

    public Nedbetalingsplan lagPlan() {
        //Sender seg selv inn i en nedbetalingsplan
        nedbetalingsplan = new Nedbetalingsplan(this);
        nedbetalingsplan.lagTerminliste();
        return nedbetalingsplan;
    } //end lagPlan
    
    
    /**
     * en getter for terinGebyret. Selv ville jeg nok kalt denne
     * getTerminGebyr(), men det stod terminGebyr() i oppgaven.
     *
     * @return en int med det faktiske gebyret, for valgt type-termin
     * @throws LoanException
     */

    public int terminGebyr() throws LoanException {
        switch(årligeTerminer) {
            case TERMIN_ÅRLIG:      return GEBYR_ÅRLIG;
            case TERMIN_HALVÅR:     return GEBYR_HALVÅR;
            case TERMIN_KVARTAL:    return GEBYR_KVARTAL;
            case TERMIN_MND:        return GEBYR_MND;
            default:
                throw new LoanException("Valgt antall terminer per år, "
                        + "er ugyldig, eller er ikke gitt termingebyr");
                /* Det å kaste exception her virker kanskje dumt da dette
                 * også sjekkes i sjekkÅrligeTerminer()
                 * Grunnen til at denne er her er for å sikre koden om
                 * noen f.eks. legger inn muligheten for å ha
                 * terminer hver andre måned, endre switch/case i
                 * sjekkÅrligeTerminer(), men glemmer å legge inn
                 * gebyr, så vil det komme opp en feilmelding */

        }
        
    } //end terminGebyr()
    
    
  /*************************************************************************
   * Get     metoder                                                       *
     ************************************************************************
     * @return
     */

    
    public int getLåneNR()              { return låneNr; }
    
    /**
     *
     * @return  lånetype
     */

     public int getLånetype()           { return lånetype; }
     
     /**
      *
      * @return lånebløp
      */

     public int getLånebeløp()          { return lånebeløp; }
     
     /**
      *
      * @return løpetid
      */

     public int getLøpetid()            { return løpetid; }
     
     /**
      *
      * @return årligeTerminer
      */

     public int getÅrligeTerminer()     { return årligeTerminer; }
     
     /**
      *
      * @return rentesats
      */

     public double getRentesats()       { return rentesats; }
     
     /**
      *
      * @return nedbetalingsplan
      */

     public Nedbetalingsplan getPlan()  { return nedbetalingsplan; }

     
  /************************************************************************
   * set      metoder                                                     *
   * Egne metoder for å sette verdier til de forskjellige variablene      *
   * Bruker sjekk-metodene for å sjekke verdiene                          *                       
   ************************************************************************/

      
    /**
     *
     * @param låneNr
     * @return låneNr
     * @throws LoanException
     * @throws NumberFormatException  
     */

    public int setLåneNr( String låneNr )
                                throws LoanException, NumberFormatException {
        return setLåneNr(Integer.parseInt(låneNr));
    }
    
    /**
     *
     * @param låneNr
     * @return låneNr
     * @throws LoanException
     */

    public int setLåneNr(int låneNr) throws LoanException {
        if (låneNr >= 1000 && låneNr <= 9999) {
            lånetErEndret = true;
            this.låneNr = låneNr;
            return låneNr;
        } else {
            throw new LoanException("Ugyldig låneNr");
        }
    }
    

    
    /**
     *
     * @param lånebeløp
     * @throws LoanException
     * @throws NumberFormatException
     */

    public void setLånebeløp( String lånebeløp )
                                throws LoanException, NumberFormatException {
        setLånebeløp(Integer.parseInt(lånebeløp));
    }
    
    /**
     *
     * @param lånebeløp
     * @throws LoanException
     */

    public void setLånebeløp(int lånebeløp) throws LoanException{
        if (lånebeløp > 0) {
            lånetErEndret = true;
            this.lånebeløp = lånebeløp;
        } else {
            throw new LoanException("Lånebeløpet må være større enn 0");
        }
    }
    
    
    /**
     *
     * @param løpetid
     * @throws LoanException
     * @throws NumberFormatException
     */

    public void setLøpetid(String løpetid)
                                throws LoanException, NumberFormatException {
        setLøpetid(Integer.parseInt(løpetid));
    }
    
    /**
     *
     * @param løpetid
     * @throws LoanException
     */

    public void setLøpetid(int løpetid) throws LoanException {
        if (løpetid > 0 && løpetid <= MAX_LØPETID) {
            lånetErEndret = true;
            this.løpetid = løpetid;
        } else {
            throw new LoanException("Løpetid må være større enn 0 og maks 40");
        }
        
    }
    
    
    /**
     *
     * @param term
     * @throws LoanException
     */

    public void setÅrligeTerminer(int term) throws LoanException {
        switch(term) {
            case TERMIN_ÅRLIG:
            case TERMIN_HALVÅR:
            case TERMIN_KVARTAL:
            case TERMIN_MND:
                /* Trenger kun 1 return for alle case pga. at det er kun
                 * exception som skal kastes her hvis ingen av casene "matcher.
                 * Uansett hvilken av casene over denne return-setningen som
                 * er verdien til årligeTerminer vil
                 * return årligeTerminer "kjøres".
                 */

                this.årligeTerminer = term;
                lånetErEndret = true;
                break;
            default:
                throw new LoanException("Ugyldig valg av årlige terminer.");
        }
    }
    
    
    /**
     *
     * @param lånetype
     * @throws LoanException
     */

    public void setLånetype(int lånetype) throws LoanException {
        if (lånetype == TYPE_ANNUITET || lånetype == TYPE_SERIELL){
            lånetErEndret = true;
            this.lånetype = lånetype;
        } else {
            throw new LoanException("ugyldig lånetype");
        }
    }
    
    
    
    /**
     *
     * @param rente
     * @throws LoanException
     * @throws NumberFormatException
     */

    public void setRentesats(String rente)
                                throws LoanException, NumberFormatException {
        setRentesats(Double.parseDouble(rente));
    }
    
    /**
     *
     * @param rente
     * @throws LoanException
     */

    public void setRentesats(double rente) throws LoanException {
        /* Jeg tolker oppgaven til at man ikke kan sette renteprosent
         * høyere enn 25%.
         * Hadde først lovlig verdier opp til 100, og advarsel når
         * man gikk over 25%.
         */

        if (rente > 0 && rente < 25) {
            lånetErEndret = true;
            this.rentesats = rente;
        }
        else {
            throw new LoanException("Renten må være større enn 0 og maks 25");
        }
    }

    
    /**
     * Resetter verdiene i lånet. Denne metoden bør nok sterkt
     * revurderes.... skaper nok et stort sikkerhetshull i programmet
     * mitt. Grunnen var at jeg måtte nulle ut nedbetalingsplanen
     * for å kunne slette tabellen.
     */

    public void resetLån() {
        this.låneNr = 0;
        this.lånebeløp = 0;
        this.løpetid = 0;
        this.rentesats = 0.0;
        nedbetalingsplan = new Nedbetalingsplan(this);
    }
    
    /**
     * Returnerer true hvis lånet er endret, ellers false
     *
     * @return
     */

    public booleannetErEndret() {
        return lånetErEndret;
    }
    
    /**
     * Gir mulighet for å sette om lånetErEndret til true/false
     */

    public void setLånetErEndret() {
        lånetErEndret = true;
    }
    
    
  /*************************************************************************
   * AbstractTableModel                                                    *
   * Har lagt denne i lån for å kunne sende lånet direkte inn når jeg
   * Oppretter JTable i GUI.
   *************************************************************************/

    
    /**
     *
     * @param rad
     * @param kolonne
     * @return  
     */

    @Override
    public Object getValueAt(int rad, int kolonne) {
        Termin termin = getPlan().getTerminListe()[rad];
        switch(kolonne) {
            case 0: return termin.getTerminNR();
            case 1: return termin.getAvdrag();
            case 2: return termin.getRenter();
            case 3:
                try {
                    return termin.terminBeløp();
                } catch (LoanException ex) {
                    return null;
                }
            case 4: return termin.getRestgjeld();
            default: return null;
        }
    }
    
    /**
     * Returnerer antall kolonner
     * @return
     */

    @Override
    public int getColumnCount() {
        return 5; //terminNR, Avdrag, rentebeløp, terminbeløp, restgjeld
    }
    
    /**
     * returnerer antall rader.
     * Rader kommer fra nedbetalingsplan.
     * @return
     */

    @Override
    public int getRowCount() {
        if ( this.getPlan() != null  ){
            if ( this.getPlan().getTerminListe() != null )
                return this.getPlan().getTerminListe().length;
        }
        return 0;
    }
    
    /**
     * Kolonnenavnene
     * @param kolonne
     * @return
     */

    @Override
    public String getColumnName(int kolonne) {
        switch (kolonne) {
            case 0: return "TerminNR";
            case 1: return "Avdrag";
            case 2: return "Renter";
            case 3: return "Terminbeløp";
            case 4: return "Restgjeld";
            default: return "";
        }

    }
    
} // end class Loan

Kontaktinfo

Hilde Vestøl
98883064
hilde@vestol.net

kart