Versio 2.0.0

Signed-off-by: laurimaaninka <lauri.maaninka@gmail.com>
This commit is contained in:
2026-04-12 23:53:23 +03:00
parent 6601a588c2
commit 88983b2e43
7 changed files with 166 additions and 44 deletions
+4 -2
View File
@@ -1,5 +1,7 @@
# 2.0.0-wip # 2.0.0
- Asiakkaalle laskutusosoite? - Asiakkaalle lisätty tietoihin laskutusosoite ja yhteyshenkilön yhteystiedot
- Tiedot nousevat kuljetusraportille laskutusta varten
- Lisätty ohjelmaan linkki muutoslokiin
# 1.1.1 # 1.1.1
- Integroitu versionumenointi projektiin - Integroitu versionumenointi projektiin
+1 -1
View File
@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>fi.lpam.ruokamanageri</groupId> <groupId>fi.lpam.ruokamanageri</groupId>
<artifactId>Ruokamanageri</artifactId> <artifactId>Ruokamanageri</artifactId>
<version>2.0.0-wip</version> <version>2.0.0</version>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>25</maven.compiler.source> <maven.compiler.source>25</maven.compiler.source>
@@ -6,21 +6,34 @@ import java.sql.*;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.ArrayList; import java.util.ArrayList;
@SuppressWarnings("ClassCanBeRecord") @SuppressWarnings({"ClassCanBeRecord", "DuplicatedCode"})
public class RaporttiRivi { public class RaporttiRivi {
private final String nimi; private final String nimi;
private final LocalDate alkuPvm, loppuPvm; private final LocalDate pvm;
private final int salaatit, pääruoat, jälkiruoat; private final int salaatit, pääruoat, jälkiruoat;
private final String lisätiedot; private final String lisätiedot;
private final String yhteyshenkilönNimi, laskutusOsoite, yhteyshenkilönPuhelinnumero, yhteyshenkilönSähköposti;
public RaporttiRivi(String nimi, LocalDate alkuPvm, LocalDate loppuPvm, int salaatit, int pääruoat, int jälkiruoat, String lisätiedot) { public RaporttiRivi(String nimi,
LocalDate pvm,
int salaatit,
int pääruoat,
int jälkiruoat,
String lisätiedot,
String yhteyshenkilönNimi,
String laskutusOsoite,
String yhteyshenkilönPuhelinnumero,
String yhteyshenkilönSähköposti) {
this.nimi = nimi; this.nimi = nimi;
this.alkuPvm = alkuPvm; this.pvm = pvm;
this.loppuPvm = loppuPvm;
this.salaatit = salaatit; this.salaatit = salaatit;
this.pääruoat = pääruoat; this.pääruoat = pääruoat;
this.jälkiruoat = jälkiruoat; this.jälkiruoat = jälkiruoat;
this.lisätiedot = lisätiedot; this.lisätiedot = lisätiedot;
this.yhteyshenkilönNimi = yhteyshenkilönNimi;
this.laskutusOsoite = laskutusOsoite;
this.yhteyshenkilönPuhelinnumero = yhteyshenkilönPuhelinnumero;
this.yhteyshenkilönSähköposti = yhteyshenkilönSähköposti;
} }
public static ArrayList<RaporttiRivi> haeRaportti(LocalDate alkuPvm, LocalDate loppuPvm, boolean tarkka) { public static ArrayList<RaporttiRivi> haeRaportti(LocalDate alkuPvm, LocalDate loppuPvm, boolean tarkka) {
@@ -29,40 +42,82 @@ public class RaporttiRivi {
ResultSet rs; ResultSet rs;
if (tarkka) { if (tarkka) {
//Jokainen kuljetus saa oman rivin //Jokainen kuljetus saa oman rivin
PreparedStatement stmt = tietokanta.prepareStatement("select nimi, kuljetusPäivämäärä, salaatit, pääruoat, jälkiruoat, lisätieto from kuljetukset where kuljetusPäivämäärä between ? and ? order by nimi"); PreparedStatement stmt = tietokanta.prepareStatement("""
select kuljetukset.asiakasID,
kuljetukset.nimi,
kuljetukset.kuljetusPäivämäärä,
kuljetukset.salaatit,
kuljetukset.pääruoat,
kuljetukset.jälkiruoat,
kuljetukset.lisätieto,
asiakkaat.yhteyshenkilönNimi,
asiakkaat.laskutusosoite,
asiakkaat.yhteyshenkilönPuhelinnumero,
asiakkaat.yhteyshenkilönSähköposti
from kuljetukset
left join asiakkaat on kuljetukset.asiakasID=asiakkaat.id
where kuljetusPäivämäärä between ? and ?
order by kuljetukset.nimi
""");
stmt.setDate(1, Date.valueOf(alkuPvm)); stmt.setDate(1, Date.valueOf(alkuPvm));
stmt.setDate(2, Date.valueOf(loppuPvm)); stmt.setDate(2, Date.valueOf(loppuPvm));
rs = stmt.executeQuery(); rs = stmt.executeQuery();
while (rs.next()) { while (rs.next()) {
int i = 2;
RaporttiRivi uusi = new RaporttiRivi( RaporttiRivi uusi = new RaporttiRivi(
rs.getString(1), rs.getString(i++),
rs.getDate(2).toLocalDate(), rs.getDate(i++).toLocalDate(),
rs.getDate(2).toLocalDate(), rs.getInt(i++),
rs.getInt(3), rs.getInt(i++),
rs.getInt(4), rs.getInt(i++),
rs.getInt(5), rs.getString(i++),
rs.getString(6) rs.getString(i++),
rs.getString(i++),
rs.getString(i++),
rs.getString(i++)
); );
raportti.add(uusi); raportti.add(uusi);
} }
} else { } else {
//Kuljetukset summataan yhteen riviin per vastaanottaja //Kuljetukset summataan yhteen riviin per vastaanottaja
PreparedStatement stmt = tietokanta.prepareStatement("select nimi, kuljetusPäivämäärä, sum(salaatit), sum(pääruoat), sum(jälkiruoat), group_concat(lisätieto, '\n') from kuljetukset where kuljetusPäivämäärä between ? and ? group by nimi order by nimi;"); PreparedStatement stmt = tietokanta.prepareStatement("""
stmt.setDate(1, Date.valueOf(alkuPvm)); select kuljetukset.asiakasID,
stmt.setDate(2, Date.valueOf(loppuPvm)); kuljetukset.nimi,
kuljetukset.kuljetusPäivämäärä,
sum(kuljetukset.salaatit),
sum(kuljetukset.pääruoat),
sum(kuljetukset.jälkiruoat),
group_concat(kuljetukset.lisätieto, ?),
asiakkaat.yhteyshenkilönNimi,
asiakkaat.laskutusosoite,
asiakkaat.yhteyshenkilönPuhelinnumero,
asiakkaat.yhteyshenkilönSähköposti
from kuljetukset
left join asiakkaat on kuljetukset.asiakasID=asiakkaat.id
where kuljetusPäivämäärä between ? and ?
group by kuljetukset.nimi
order by kuljetukset.nimi
""");
stmt.setString(1, "\n");
stmt.setDate(2, Date.valueOf(alkuPvm));
stmt.setDate(3, Date.valueOf(loppuPvm));
rs = stmt.executeQuery(); rs = stmt.executeQuery();
while (rs.next()) { while (rs.next()) {
int i = 2;
RaporttiRivi uusi = new RaporttiRivi( RaporttiRivi uusi = new RaporttiRivi(
rs.getString(1), rs.getString(i++),
alkuPvm, rs.getDate(i++).toLocalDate(),
loppuPvm, rs.getInt(i++),
rs.getInt(3), rs.getInt(i++),
rs.getInt(4), rs.getInt(i++),
rs.getInt(5), rs.getString(i++),
rs.getString(6) rs.getString(i++),
rs.getString(i++),
rs.getString(i++),
rs.getString(i++)
); );
raportti.add(uusi); raportti.add(uusi);
} }
@@ -76,19 +131,25 @@ public class RaporttiRivi {
} }
@Override @Override
public String toString() { public String toString() {
return this.nimi + ":\nSal: " + this.salaatit + ", Pr: " + this.pääruoat + ", Jr: " + this.jälkiruoat + "\nLisätiedot:\n" + this.lisätiedot.strip();
String laskutustiedot = "\n" + yhteyshenkilönNimi +
"\n" + laskutusOsoite +
"\n" + yhteyshenkilönPuhelinnumero +
"\n" + yhteyshenkilönSähköposti;
return nimi +
"\nSal: " + salaatit + ", Pr: " + pääruoat + ", Jr: " + jälkiruoat +
"\nLisätiedot:\n" +
getLisätiedot() +
laskutustiedot.replace("\nnull", "").strip();
} }
public String getNimi() { public String getNimi() {
return nimi; return nimi;
} }
public LocalDate getAlkuPvm() { public LocalDate getPvm() {
return alkuPvm; return pvm;
}
public LocalDate getLoppuPvm() {
return loppuPvm;
} }
public int getSalaatit() { public int getSalaatit() {
@@ -104,6 +165,23 @@ public class RaporttiRivi {
} }
public String getLisätiedot() { public String getLisätiedot() {
return lisätiedot; if (lisätiedot == null) return null;
return lisätiedot.strip().trim().stripLeading().stripTrailing();
}
public String getYhteyshenkilönNimi() {
return yhteyshenkilönNimi;
}
public String getLaskutusOsoite() {
return laskutusOsoite;
}
public String getYhteyshenkilönPuhelinnumero() {
return yhteyshenkilönPuhelinnumero;
}
public String getYhteyshenkilönSähköposti() {
return yhteyshenkilönSähköposti;
} }
} }
@@ -1,15 +1,24 @@
package fi.lpam.ruokamanageri.gui; package fi.lpam.ruokamanageri.gui;
import fi.lpam.ruokamanageri.Main;
import fi.lpam.ruokamanageri.dataluokat.Asiakas; import fi.lpam.ruokamanageri.dataluokat.Asiakas;
import fi.lpam.ruokamanageri.gui.elementit.MaaraTableColumn; import fi.lpam.ruokamanageri.gui.elementit.MaaraTableColumn;
import fi.lpam.ruokamanageri.gui.elementit.TabPohja; import fi.lpam.ruokamanageri.gui.elementit.TabPohja;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.KeyCode; import javafx.scene.input.KeyCode;
import javafx.scene.input.MouseEvent; import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*; import javafx.scene.layout.*;
import java.awt.*;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
@@ -33,19 +42,30 @@ public class Asiakashallinta extends TabPohja {
yläpalkinNapit.setSpacing(5); yläpalkinNapit.setSpacing(5);
yläpalkki.setRight(yläpalkinNapit); yläpalkki.setRight(yläpalkinNapit);
Button avaaVersioloki = new Button("Avaa muutosloki");
avaaVersioloki.setFont(buttonFont);
avaaVersioloki.setOnAction(_ -> {
try {
Desktop.getDesktop().browse(new URI("https://git.lpam.fi/laurimaaninka/Ruokamanageri/src/branch/master/CHANGELOG.md"));
} catch (IOException | URISyntaxException e) {
System.out.println(e.getMessage());
}
});
yläpalkinNapit.getChildren().add(avaaVersioloki);
Button poistaValittu = new Button("Poista"); Button poistaValittu = new Button("Poista");
poistaValittu.setOnAction(_ -> poistaValittu()); poistaValittu.setOnAction(_ -> poistaValittu());
poistaValittu.setFont(TabPohja.buttonFont); poistaValittu.setFont(buttonFont);
yläpalkinNapit.getChildren().add(poistaValittu); yläpalkinNapit.getChildren().add(poistaValittu);
Button muokkaaAsiakasta = new Button("Muokkaa"); Button muokkaaAsiakasta = new Button("Muokkaa");
muokkaaAsiakasta.setOnAction(_ -> muokkaaValittua()); muokkaaAsiakasta.setOnAction(_ -> muokkaaValittua());
muokkaaAsiakasta.setFont(TabPohja.buttonFont); muokkaaAsiakasta.setFont(buttonFont);
yläpalkinNapit.getChildren().add(muokkaaAsiakasta); yläpalkinNapit.getChildren().add(muokkaaAsiakasta);
Button uusiAsiakas = new Button("Uusi asiakas"); Button uusiAsiakas = new Button("Uusi asiakas");
uusiAsiakas.setOnAction(_ -> uusiAsiakas()); uusiAsiakas.setOnAction(_ -> uusiAsiakas());
uusiAsiakas.setFont(TabPohja.buttonFont); uusiAsiakas.setFont(buttonFont);
yläpalkinNapit.getChildren().add(uusiAsiakas); yläpalkinNapit.getChildren().add(uusiAsiakas);
tvAsiakkaat.setEditable(false); tvAsiakkaat.setEditable(false);
@@ -59,18 +59,21 @@ public class KuljetusRaportit extends TabPohja {
Button tulostaRaportti = new Button("Tulosta raportti"); Button tulostaRaportti = new Button("Tulosta raportti");
tulostaRaportti.setFont(buttonFont); tulostaRaportti.setFont(buttonFont);
tulostaRaportti.setOnAction(_ ->tulostaRaportti()); tulostaRaportti.setOnAction(_ ->tulostaRaportti());
yläpalkinNapit.getChildren().addAll(tarkka, new Label("Hae kuljetukset välillä:"), alkuPvm, new Label("-"), loppuPvm, haeKuljetukset, tulostaRaportti); yläpalkinNapit.getChildren().addAll(tarkka,
new Label("Hae kuljetukset välillä:"),
alkuPvm, new Label("-"), loppuPvm,
haeKuljetukset, tulostaRaportti);
root.setCenter(tableView); root.setCenter(tableView);
TableColumn<RaporttiRivi, String> tcNimi = new TableColumn<>("Nimi"); TableColumn<RaporttiRivi, String> tcNimi = new TableColumn<>("Nimi");
tcNimi.setMinWidth(150); tcNimi.setMinWidth(200);
tcNimi.setCellValueFactory(new PropertyValueFactory<>("nimi")); tcNimi.setCellValueFactory(new PropertyValueFactory<>("nimi"));
TableColumn<RaporttiRivi, LocalDate> tcPvm = new TableColumn<>("Päivämäärä"); TableColumn<RaporttiRivi, LocalDate> tcPvm = new TableColumn<>("Päivämäärä");
tcPvm.setMinWidth(150); tcPvm.setMinWidth(150);
tcPvm.setCellFactory(_ ->new PaivamaaraTableCell()); tcPvm.setCellFactory(_ ->new PaivamaaraTableCell());
tcPvm.setCellValueFactory(new PropertyValueFactory<>("loppuPvm")); tcPvm.setCellValueFactory(new PropertyValueFactory<>("pvm"));
TableColumn<RaporttiRivi, Integer> tcSalaatit = new TableColumn<>("Salaatit"); TableColumn<RaporttiRivi, Integer> tcSalaatit = new TableColumn<>("Salaatit");
tcSalaatit.setMinWidth(100); tcSalaatit.setMinWidth(100);
@@ -85,10 +88,27 @@ public class KuljetusRaportit extends TabPohja {
tcJälkiruoat.setCellValueFactory(new PropertyValueFactory<>("jälkiruoat")); tcJälkiruoat.setCellValueFactory(new PropertyValueFactory<>("jälkiruoat"));
TableColumn<RaporttiRivi, String> tcLisätiedot = new TableColumn<>("Lisätiedot"); TableColumn<RaporttiRivi, String> tcLisätiedot = new TableColumn<>("Lisätiedot");
tcLisätiedot.setMinWidth(500); tcLisätiedot.setMinWidth(300);
tcLisätiedot.setCellValueFactory(new PropertyValueFactory<>("lisätiedot")); tcLisätiedot.setCellValueFactory(new PropertyValueFactory<>("lisätiedot"));
tableView.getColumns().addAll(tcNimi, tcPvm, tcSalaatit, tcPääruoat, tcJälkiruoat, tcLisätiedot); TableColumn<RaporttiRivi, String> tcYhteyshenkilönNimi = new TableColumn<>("Yhteyshenkilön nimi");
tcYhteyshenkilönNimi.setMinWidth(200);
tcYhteyshenkilönNimi.setCellValueFactory(new PropertyValueFactory<>("yhteyshenkilönNimi"));
TableColumn<RaporttiRivi, String> tcLaskutusOsoite = new TableColumn<>("Laskutusosoite");
tcLaskutusOsoite.setMinWidth(200);
tcLaskutusOsoite.setCellValueFactory(new PropertyValueFactory<>("laskutusOsoite"));
TableColumn<RaporttiRivi, String> tcYhteyshenkilönPuhelinnumero = new TableColumn<>("Puhelinnumero");
tcYhteyshenkilönPuhelinnumero.setMinWidth(200);
tcYhteyshenkilönPuhelinnumero.setCellValueFactory(new PropertyValueFactory<>("yhteyshenkilönPuhelinnumero"));
TableColumn<RaporttiRivi, String> tcYhteyshenkilönSähköposti = new TableColumn<>("Sähköposti");
tcYhteyshenkilönSähköposti.setMinWidth(200);
tcYhteyshenkilönSähköposti.setCellValueFactory(new PropertyValueFactory<>("yhteyshenkilönSähköposti"));
tableView.getColumns().addAll(tcNimi, tcPvm, tcSalaatit, tcPääruoat, tcJälkiruoat, tcLisätiedot,
tcYhteyshenkilönNimi, tcLaskutusOsoite, tcYhteyshenkilönPuhelinnumero, tcYhteyshenkilönSähköposti);
tableView.setPlaceholder(new Label("Hae raportti")); tableView.setPlaceholder(new Label("Hae raportti"));
for (TableColumn<RaporttiRivi, ?> sarake : tableView.getColumns()) { for (TableColumn<RaporttiRivi, ?> sarake : tableView.getColumns()) {
sarake.setSortable(false); sarake.setSortable(false);
@@ -45,8 +45,9 @@ public class KuljetusListaTulostaja extends Tulostaja{
siirräOsoitinta(NIMEN_LEVEYS); siirräOsoitinta(NIMEN_LEVEYS);
sisältö.showText(kuljetus.getLisätieto()); sisältö.showText(kuljetus.getLisätieto());
uusiRivi(RIVI_KORKEUS*0.1F); uusiRivi(RIVI_KORKEUS*0.1F);
sisältö.showText("___________________________________________________________________"); sisältö.showText("___________________________________________________________________"); //67 alaviivaa (noin sivun leveys)
} }
tulosta(); tulosta();
} }
catch (IOException e) { catch (IOException e) {
@@ -4,13 +4,14 @@ import fi.lpam.ruokamanageri.dataluokat.RaporttiRivi;
import java.io.IOException; import java.io.IOException;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList; import java.util.ArrayList;
@SuppressWarnings("DuplicatedCode") @SuppressWarnings("DuplicatedCode")
public class KuljetusRaporttiTulostaja extends Tulostaja { public class KuljetusRaporttiTulostaja extends Tulostaja {
public void luoRaportti(ArrayList<RaporttiRivi> raporttiRivit, LocalDate alkuPvm, LocalDate loppuPvm) { public void luoRaportti(ArrayList<RaporttiRivi> raporttiRivit, LocalDate alkuPvm, LocalDate loppuPvm) {
try { try {
sisältö.showText("Raportti aikaväliltä " + alkuPvm + " - " + loppuPvm); sisältö.showText("Raportti aikaväliltä " + alkuPvm.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) + " - " + loppuPvm.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")));
uusiRivi(); uusiRivi();
uusiRivi(); uusiRivi();