this is my basic front end, you can use that
10:27 24 May 2026

1. Ordine.java — il model principale

public class Ordine {
    private int id;
    private int tavoloNumero;
    private String stato;        // "ATTESO", "IN_PREPARAZIONE", "PRONTO", "CONSEGNATO"
    private String dataOra;
    private double totale;
    private List piatti;  // lista delle righe dell'ordine

    // Getters e setters
    public int getId() { return id; }
    public void setId(int id) { this.id = id; }

    public int getTavoloNumero() { return tavoloNumero; }
    public void setTavoloNumero(int tavoloNumero) { this.tavoloNumero = tavoloNumero; }

    public String getStato() { return stato; }
    public void setStato(String stato) { this.stato = stato; }

    public double getTotale() { return totale; }
    public void setTotale(double totale) { this.totale = totale; }

    public List getPiatti() { return piatti; }
    public void setPiatti(List piatti) { this.piatti = piatti; }
}

2. OrdinePiatto.java — una riga dell'ordine

public class OrdinePiatto {
    private int id;
    private int ordineId;
    private int piattoId;
    private String nomePiatto;    // comodo averlo già qui per mostrarlo
    private int quantita;
    private String note;
    private double prezzoUnitario;

    // Getters e setters
    public int getPiattoId() { return piattoId; }
    public void setPiattoId(int piattoId) { this.piattoId = piattoId; }

    public int getQuantita() { return quantita; }
    public void setQuantita(int quantita) { this.quantita = quantita; }

    public String getNote() { return note; }
    public void setNote(String note) { this.note = note; }

    public double getPrezzoUnitario() { return prezzoUnitario; }
    public void setPrezzoUnitario(double prezzoUnitario) { this.prezzoUnitario = prezzoUnitario; }

    public String getNomePiatto() { return nomePiatto; }
    public void setNomePiatto(String nomePiatto) { this.nomePiatto = nomePiatto; }
}

3. OrdineRepository.java — le query SQL

@Repository
public class OrdineRepository {

    @Autowired
    private JdbcTemplate jdbc;

    // Crea l'ordine e restituisce l'id generato
    public int save(Ordine o) {
        String sql = "INSERT INTO ordini (tavolo_numero, stato, data_ora, totale) VALUES (?, 'ATTESO', NOW(), ?)";
        KeyHolder keyHolder = new GeneratedKeyHolder();

        jdbc.update(connection -> {
            PreparedStatement ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
            ps.setInt(1, o.getTavoloNumero());
            ps.setDouble(2, o.getTotale());
            return ps;
        }, keyHolder);

        return keyHolder.getKey().intValue();  // restituisce l'id del nuovo ordine
    }

    // Inserisce ogni riga dell'ordine nella tabella ordine_piatti
    public void saveRighe(int ordineId, List piatti) {
        String sql = "INSERT INTO ordine_piatti (ordine_id, piatto_id, quantita, note, prezzo_unitario) VALUES (?, ?, ?, ?, ?)";
        for (OrdinePiatto riga : piatti) {
            jdbc.update(sql,
                ordineId,
                riga.getPiattoId(),
                riga.getQuantita(),
                riga.getNote(),
                riga.getPrezzoUnitario()
            );
        }
    }

    // GET tutti gli ordini (senza righe, solo la testata)
    public List findAll() {
        String sql = "SELECT * FROM ordini ORDER BY data_ora DESC";
        return jdbc.query(sql, (rs, rowNum) -> {
            Ordine o = new Ordine();
            o.setId(rs.getInt("id"));
            o.setTavoloNumero(rs.getInt("tavolo_numero"));
            o.setStato(rs.getString("stato"));
            o.setTotale(rs.getDouble("totale"));
            return o;
        });
    }

    // GET un ordine con tutte le sue righe (JOIN)
    public Ordine findById(int id) {
        // Prima prendi la testata
        String sqlOrdine = "SELECT * FROM ordini WHERE id = ?";
        Ordine ordine = jdbc.queryForObject(sqlOrdine, new Object[]{id}, (rs, rowNum) -> {
            Ordine o = new Ordine();
            o.setId(rs.getInt("id"));
            o.setTavoloNumero(rs.getInt("tavolo_numero"));
            o.setStato(rs.getString("stato"));
            o.setTotale(rs.getDouble("totale"));
            return o;
        });

        // Poi prendi le righe con JOIN su piatti per avere anche il nome
        String sqlRighe = "SELECT op.*, p.nome as nome_piatto " +
                          "FROM ordine_piatti op " +
                          "JOIN piatti p ON op.piatto_id = p.id " +
                          "WHERE op.ordine_id = ?";
        List righe = jdbc.query(sqlRighe, new Object[]{id}, (rs, rowNum) -> {
            OrdinePiatto riga = new OrdinePiatto();
            riga.setPiattoId(rs.getInt("piatto_id"));
            riga.setNomePiatto(rs.getString("nome_piatto"));
            riga.setQuantita(rs.getInt("quantita"));
            riga.setPrezzoUnitario(rs.getDouble("prezzo_unitario"));
            riga.setNote(rs.getString("note"));
            return riga;
        });

        ordine.setPiatti(righe);
        return ordine;
    }

    // Aggiorna solo lo stato
    public int updateStato(int id, String stato) {
        String sql = "UPDATE ordini SET stato = ? WHERE id = ?";
        return jdbc.update(sql, stato, id);
    }

    // Elimina ordine e le sue righe (prima le righe, poi la testata)
    public void delete(int id) {
        jdbc.update("DELETE FROM ordine_piatti WHERE ordine_id = ?", id);
        jdbc.update("DELETE FROM ordini WHERE id = ?", id);
    }
}

KeyHolder è il modo per ottenere l'id autogenerato dopo un INSERT — ti serve per poi salvare le righe collegate.


4. OrdineService.java

@Service
public class OrdineService {

    @Autowired
    private OrdineRepository ordineRepository;

    public List getAll() {
        return ordineRepository.findAll();
    }

    public Ordine getById(int id) {
        return ordineRepository.findById(id);
    }

    public void create(Ordine ordine) {
        // Calcola il totale sommando prezzo * quantita di ogni riga
        double totale = 0;
        for (OrdinePiatto riga : ordine.getPiatti()) {
            totale += riga.getPrezzoUnitario() * riga.getQuantita();
        }
        ordine.setTotale(totale);

        // Salva la testata e prendi l'id generato
        int nuovoId = ordineRepository.save(ordine);

        // Salva le righe con quell'id
        ordineRepository.saveRighe(nuovoId, ordine.getPiatti());
    }

    public void updateStato(int id, String stato) {
        ordineRepository.updateStato(id, stato);
    }

    public void delete(int id) {
        ordineRepository.delete(id);
    }
}

5. OrdineController.java

@RestController
@RequestMapping("/api/ordini")
@CrossOrigin(origins = "*")
public class OrdineController {

    @Autowired
    private OrdineService ordineService;

    @GetMapping
    public List getAll() {
        return ordineService.getAll();
    }

    @GetMapping("/{id}")
    public Ordine getById(@PathVariable int id) {
        return ordineService.getById(id);
    }

    @PostMapping
    public ResponseEntity create(@RequestBody Ordine ordine) {
        ordineService.create(ordine);
        return ResponseEntity.status(201).body("Ordine creato");
    }

    @PutMapping("/{id}/stato")
    public ResponseEntity updateStato(@PathVariable int id, @RequestBody Map body) {
        ordineService.updateStato(id, body.get("stato"));
        return ResponseEntity.ok("Stato aggiornato");
    }

    @DeleteMapping("/{id}")
    public ResponseEntity delete(@PathVariable int id) {
        ordineService.delete(id);
        return ResponseEntity.ok("Ordine eliminato");
    }
}

Map nel PUT dello stato ti permette di ricevere un JSON semplice tipo {"stato": "PRONTO"} senza dover creare una classe apposita.


Il JSON che Angular dovrà mandare per creare un ordine è:

{
  "tavoloNumero": 5,
  "piatti": [
    { "piattoId": 1, "quantita": 2, "prezzoUnitario": 8.50, "note": "" },
    { "piattoId": 3, "quantita": 1, "prezzoUnitario": 12.00, "note": "senza cipolla" }
  ]
}

Vuoi che passiamo ora al frontend Angular, o prima vuoi lo script SQL per creare le tabelle?

java