diff --git a/docs/SqlDatabase/ER-Diagram v5.png b/docs/SqlDatabase/ER-Diagram v5.png new file mode 100644 index 0000000..df22994 Binary files /dev/null and b/docs/SqlDatabase/ER-Diagram v5.png differ diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/Readers/DonationSelect.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/Readers/DonationSelect.java index 5990fc3..2258013 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/Readers/DonationSelect.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/Readers/DonationSelect.java @@ -8,13 +8,20 @@ import ntnu.systemutvikling.team6.models.Charity; import ntnu.systemutvikling.team6.models.Donation; import ntnu.systemutvikling.team6.models.registry.DonationRegistry; +import ntnu.systemutvikling.team6.models.user.User; /** * Data access class responsible for reading donation data from the database. * - *

Retrieves donations along with their associated charity information by performing an INNER - * JOIN between the {@code Donations} and {@code Charities} tables. Only donations that have a - * matching charity record are returned. + *

Retrieves donations along with their associated {@link Charity} by performing an INNER JOIN + * between the {@code Donations} and {@code Charities} tables. Only donations with a matching + * charity record are included. Donor ({@link User}) and {@code CharityVanity} details are + * intentionally excluded to keep this query lightweight — join those separately if richer data is + * needed. + * + *

Note: {@code CharityVanity} fields (name, link, description, logo) are NOT fetched here since + * they live in a separate table. The {@link Charity} objects returned will only contain the core + * fields present in the {@code Charities} table. */ public class DonationSelect { @@ -50,18 +57,12 @@ public DonationRegistry getDonationFromDB() { String sql_query = """ SELECT - d.UUID_Donations, - d.amount, - d.date, - c.UUID_charities, - c.org_number, - c.charity_name, - c.charity_link, - c.pre_approved, - c.status + d.UUID_Donations, d.amount, d.isAnonymous, d.date, d.charity_id, d.user_id, + c.UUID_charities, c.org_number, c,pre_approved, c.status + u.UUID_user, u.user_name, u.user_email, u.user_password, u.role FROM Donations d - JOIN Charities c - ON d.Charities_UUID_charities = c.UUID_charities + INNER JOIN Charities c ON d.charity_id = c.UUID_charities + INNER JOIN User u ON d.user_id = u.UUID_user """; Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql_query); @@ -72,17 +73,24 @@ public DonationRegistry getDonationFromDB() { new Charity( rs.getString("UUID_charities"), rs.getString("org_number"), - rs.getString("charity_name"), - rs.getString("charity_link"), rs.getBoolean("pre_approved"), rs.getString("status")); + User user = + new User( + rs.getString("UUID_user"), + rs.getString("user_name"), + rs.getString("user_email"), + rs.getString("user_password"), + rs.getString("role")); Donation donation = new Donation( rs.getString("UUID_Donations"), rs.getDouble("amount"), rs.getDate("date").toLocalDate(), - charity); + charity, + user, + rs.getBoolean("isAnonymous")); registry.addDonation(donation); } } catch (SQLException e) { diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Charity.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Charity.java index 774c721..e019aea 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Charity.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Charity.java @@ -47,16 +47,16 @@ public class Charity { private byte[] logoBlob; /** - * Minimal contructor JUST FOR DONATIONSSELECT. - * Just cause donation object needs to only contain information about receiver {@code Chairty } and donator {@code User}, and not necessarily Urls, logos, and etc. + * Minimal contructor JUST FOR DONATIONSSELECT. Just cause donation object needs to only contain + * information about receiver {@code Chairty } and donator {@code User}, and not necessarily Urls, + * logos, and etc. * - * @param uuid from DonationSelect - * @param org_number matches from DonationSelect - * @param is_pre_approved name matches from DonationSelect - * @param status name matches from DonationSelect + * @param uuid from DonationSelect + * @param org_number matches from DonationSelect + * @param is_pre_approved name matches from DonationSelect + * @param status name matches from DonationSelect */ - public Charity( - String uuid, String org_number, Boolean is_pre_approved, String status){ + public Charity(String uuid, String org_number, Boolean is_pre_approved, String status) { this.UUID = java.util.UUID.fromString(uuid); this.org_number = org_number.replaceAll("\\s", ""); this.is_pre_approved = is_pre_approved; @@ -86,7 +86,8 @@ public Charity( /** * Contructor for creating a new charity. Taylored to match data given from DATABASE. Expects - * paramaters that will fill all attributes. EXECPT for feedbacks and categories (which is done right after). + * paramaters that will fill all attributes. EXECPT for feedbacks and categories (which is done + * right after). * * @param org_number matches from innsamlingkontrollen * @param name matches from innsamlingkontrollen diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Donation.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Donation.java index 3882548..443891b 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Donation.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Donation.java @@ -20,7 +20,6 @@ public class Donation { /* The user/donor that made the donation */ private User donor; - /** Is the donation made anonymously? This can be null if the donation was made anonymously. */ private boolean isAnonymous; @@ -45,20 +44,20 @@ public Donation(double amount, LocalDate date, Charity charity, User donor) { /** * Constructor for creating a donation reed from the database. * - * @param donationId the stored UUID string for this donation; must not be {@code null} - * @param amount the donated amount - * @param date the date the donation was made; must not be {@code null} - * @param charity the receiving charity; must not be {@code null} - * @param donor the donating user, or {@code null} if anonymous + * @param donationId the stored UUID string for this donation; must not be {@code null} + * @param amount the donated amount + * @param date the date the donation was made; must not be {@code null} + * @param charity the receiving charity; must not be {@code null} + * @param donor the donating user, or {@code null} if anonymous * @param isAnonymous whether the donation was recorded as anonymous */ public Donation( - String donationId, - double amount, - LocalDate date, - Charity charity, - User donor, - boolean isAnonymous) { + String donationId, + double amount, + LocalDate date, + Charity charity, + User donor, + boolean isAnonymous) { this.donationID = UUID.fromString(donationId); this.amount = amount; this.date = date; @@ -73,7 +72,7 @@ public boolean isAnonymous() { } public UUID getCharityId() { - return charityId; + return charity.getUUID(); } public double getAmount() { diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/FullCharityScrape.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/FullCharityScrape.java index 76a4f4e..a69e3a9 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/FullCharityScrape.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/FullCharityScrape.java @@ -3,8 +3,6 @@ import java.io.IOException; import java.net.URISyntaxException; import java.net.http.HttpClient; -import java.util.function.Function; - import ntnu.systemutvikling.team6.models.Charity; import ntnu.systemutvikling.team6.models.registry.CharityRegistry; import ntnu.systemutvikling.team6.scraper.scraperComponents.APICharityScraper; @@ -47,8 +45,8 @@ public FullCharityScrape() throws URISyntaxException { *

Phase 1 — API scrape: Calls {@link APICharityScraper#checkConnection()} to verify * availability, then fetches and parses the JSON payload into a {@link CharityRegistry}. * - *

Phase 2 — URL scrape: Iterates over every {@link Charity} in the registry and uses - * a {@link URLCharityScraper} to enrich each entry with its description, logo URL, logo blob, + *

Phase 2 — URL scrape: Iterates over every {@link Charity} in the registry and uses a + * {@link URLCharityScraper} to enrich each entry with its description, logo URL, logo blob, * categories, and key values scraped from the charity's own web page. * *

If {@link APICharityScraper#checkConnection()} throws an exception, it propagates to the @@ -61,7 +59,7 @@ public FullCharityScrape() throws URISyntaxException { */ public CharityRegistry getAPIAndURLCharityData() throws IOException, InterruptedException { try { - if (!apiScraper.checkConnection()){ + if (!apiScraper.checkConnection()) { throw new RuntimeException("Connection check returned false"); } } catch (Exception e) { @@ -71,30 +69,36 @@ public CharityRegistry getAPIAndURLCharityData() throws IOException, Interrupted CharityRegistry charityRegistry = apiScraper.parseJSON(apiScraper.getJSONData()); int charityCounter = 0; - for (Charity charity : charityRegistry.getAllCharities()) { - System.out.println(charity.getName()); - } - // Scrapes description, logo, categories, and key values from IK - for (Charity charity : charityRegistry.getAllCharities()) { - charityCounter++; + for (Charity charity : charityRegistry.getAllCharities()) { + System.out.println(charity.getName()); + } + // Scrapes description, logo, categories, and key values from IK + for (Charity charity : charityRegistry.getAllCharities()) { + charityCounter++; - System.out.println( - "Scraping charity vanity details: " - + charityCounter - + " of " - + charityRegistry.getAllCharities().size()); - try { - URLCharityScraper urlScraper = new URLCharityScraper(charity.getURL()); - urlScraper.scrapeCharityPage(); + System.out.println( + "Scraping charity vanity details: " + + charityCounter + + " of " + + charityRegistry.getAllCharities().size()); + try { + URLCharityScraper urlScraper = new URLCharityScraper(charity.getURL()); + urlScraper.scrapeCharityPage(); - charity.setDescription(urlScraper.getDescription()); - charity.setCategory(urlScraper.getCategories()); - charity.setLogoURL(urlScraper.getLogoURL()); - charity.setKeyValues(urlScraper.getKeyValues()); - byte[] logoBlob = LogoDownloader.downloadImageAsBlob(charity.getLogoURL()); - charity.setLogoBlob(logoBlob); - } catch (Exception e){ - throw new RuntimeException("Failed to Scrape for: [" + charityCounter +"]: "+ charity.getName() + ": " + e.getMessage()); + charity.setDescription(urlScraper.getDescription()); + charity.setCategory(urlScraper.getCategories()); + charity.setLogoURL(urlScraper.getLogoURL()); + charity.setKeyValues(urlScraper.getKeyValues()); + byte[] logoBlob = LogoDownloader.downloadImageAsBlob(charity.getLogoURL()); + charity.setLogoBlob(logoBlob); + } catch (Exception e) { + throw new RuntimeException( + "Failed to Scrape for: [" + + charityCounter + + "]: " + + charity.getName() + + ": " + + e.getMessage()); } } return charityRegistry;