diff --git a/prototype/src/main/java/org/hso/ecommerce/action/booking/CreateBookingAction.java b/prototype/src/main/java/org/hso/ecommerce/action/booking/CreateBookingAction.java index f01e6a3..edde2cb 100644 --- a/prototype/src/main/java/org/hso/ecommerce/action/booking/CreateBookingAction.java +++ b/prototype/src/main/java/org/hso/ecommerce/action/booking/CreateBookingAction.java @@ -10,6 +10,7 @@ public class CreateBookingAction { public CreateBookingAction(BookingAccountEntry source, BookingAccountEntry destination, BookingReason reason, int amountCent) { booking = new Booking(); + booking.created = new java.sql.Timestamp(System.currentTimeMillis()); booking.reason = reason; booking.amountCent = amountCent; diff --git a/prototype/src/main/java/org/hso/ecommerce/app/RequestController.java b/prototype/src/main/java/org/hso/ecommerce/app/RequestController.java index 9175a59..3039bb9 100644 --- a/prototype/src/main/java/org/hso/ecommerce/app/RequestController.java +++ b/prototype/src/main/java/org/hso/ecommerce/app/RequestController.java @@ -75,21 +75,6 @@ public class RequestController { return "redirect:/"; } - @GetMapping("/intern/") - public String intern() { - return "intern/index"; - } - - @GetMapping("/intern/customers/") - public String internCustomers() { - return "intern/customers/index"; - } - - @GetMapping("/intern/customers/{id}") - public String internCustomersId() { - return "intern/customers/id"; - } - @GetMapping("/intern/customerOrders/") public String internCustomerOrder() { return "intern/customerOrders/index"; @@ -100,23 +85,4 @@ public class RequestController { return "intern/customerOrders/id"; } - @GetMapping("/intern/accounting/") - public String accounting() { - return "intern/accounting/index"; - } - - @GetMapping("/intern/accounting/vat") - public String accountingVat() { - return "intern/accounting/vat"; - } - - @GetMapping("/intern/accounting/main") - public String accountingIntern() { - return "intern/accounting/main"; - } - - @GetMapping("/intern/accounting/addManual") - public String accountingAddManual() { - return "intern/accounting/addManual"; - } } diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/BookingController.java b/prototype/src/main/java/org/hso/ecommerce/controller/BookingController.java deleted file mode 100644 index d35093e..0000000 --- a/prototype/src/main/java/org/hso/ecommerce/controller/BookingController.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.hso.ecommerce.controller; - -import org.springframework.stereotype.Controller; - -@Controller -//@RequestMapping("...") -public class BookingController { -} diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/intern/InternIndexController.java b/prototype/src/main/java/org/hso/ecommerce/controller/intern/InternIndexController.java index 65b3dba..43fe2d9 100644 --- a/prototype/src/main/java/org/hso/ecommerce/controller/intern/InternIndexController.java +++ b/prototype/src/main/java/org/hso/ecommerce/controller/intern/InternIndexController.java @@ -1,8 +1,34 @@ package org.hso.ecommerce.controller.intern; +import java.util.Optional; + +import org.hso.ecommerce.controller.intern.accounting.AccountingController; +import org.hso.ecommerce.entities.booking.BookingAccountEntry; +import org.hso.ecommerce.repos.booking.BookingAccountEntryRepository; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; @Controller -//@RequestMapping("...") +@RequestMapping("/intern") public class InternIndexController { + + @Autowired + private final BookingAccountEntryRepository bookingAccountEntryRepository = null; + + @GetMapping("/") + public String intern(Model model) { + Optional mainAccount = bookingAccountEntryRepository.getByMain(); + int mainAccountBalance = mainAccount.map(entry -> entry.newSumCent).orElse(0); + Optional vatAccount = bookingAccountEntryRepository.getByVat(); + int vatAccountBalance = vatAccount.map(entry -> entry.newSumCent).orElse(0); + + model.addAttribute("mainAccountBalance", AccountingController.fmtEuro(mainAccountBalance)); + model.addAttribute("vatAccountBalance", AccountingController.fmtEuro(vatAccountBalance)); + + return "intern/index"; + } + } diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/intern/accounting/AccountingController.java b/prototype/src/main/java/org/hso/ecommerce/controller/intern/accounting/AccountingController.java new file mode 100644 index 0000000..c7f9b75 --- /dev/null +++ b/prototype/src/main/java/org/hso/ecommerce/controller/intern/accounting/AccountingController.java @@ -0,0 +1,223 @@ +package org.hso.ecommerce.controller.intern.accounting; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.List; + +import org.hso.ecommerce.entities.booking.Booking; +import org.hso.ecommerce.entities.booking.BookingAccountEntry; +import org.hso.ecommerce.entities.booking.BookingReason; +import org.hso.ecommerce.repos.booking.BookingRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class AccountingController { + + @Autowired + private BookingRepository bookingRepository = null; + + /** + * A description used to render the html template for the overview of all bookings + */ + static class TemplateBooking { + public String datetime; + public String amount; + public String source; + public String sourceAddr; + public String sourceBalance; + public String destination; + public String destinationAddr; + public String destinationBalance; + public String reason; + public String reference; + public String referenceAddr; + } + + /** + * A description used to render the html template for bookings on a specific account + */ + public static class ShortTemplateBooking { + public String datetime; + public String amount; + public String source; + public String sourceAddr; + public String balance; + public String reason; + public String reference; + public String referenceAddr; + } + + public static class ShortTemplateBookingResult { + public final String balance; + public final List bookings; + + public ShortTemplateBookingResult(String balance, List bookings) { + this.balance = balance; + this.bookings = bookings; + } + } + + /** + * Used to check which side of the booking (source or destination) is the account we are currently looking at. + */ + public interface AccountFilter { + boolean matches(BookingAccountEntry account); + } + + /** + * Renders template information for the bookings of one specific account. + * + * @param bookings The (already fetched) booking entities to display + * @param currentAccount A filter matching the account that is to be displayed + * @return A collection result containing the final balance and all booking entries. + */ + public ShortTemplateBookingResult buildShortTemplate(List bookings, AccountFilter currentAccount) { + List templateBookings = new ArrayList<>(); + for (Booking booking : bookings) { + ShortTemplateBooking tb = new ShortTemplateBooking(); + tb.datetime = new SimpleDateFormat("dd.MM.yyyy HH:mm").format(booking.created); + tb.reason = booking.reason.comment; + tb.reference = describeReference(booking.reason); + tb.referenceAddr = linkToReference(booking.reason); + if (booking.destination != null && currentAccount.matches(booking.destination)) { + // Money was transferred onto the account we are looking at. + tb.amount = fmtEuro(booking.amountCent); + if (booking.source != null) { + tb.source = describeAccount(booking.source); + tb.sourceAddr = linkAddrOfAccount(booking.source); + } else { + tb.source = "-"; + tb.sourceAddr = null; + } + tb.balance = fmtEuro(booking.destination.newSumCent); + } else if (booking.source != null && currentAccount.matches(booking.source)) { + // Money was transferred away from the account we are looking at. + tb.amount = fmtEuro(-booking.amountCent); // Negative because of the transfer away + if (booking.destination != null) { + tb.source = describeAccount(booking.destination); // 'source' means 'the other account' in this case + tb.sourceAddr = linkAddrOfAccount(booking.destination); + } else { + tb.source = "-"; + tb.sourceAddr = null; + } + tb.balance = fmtEuro(booking.source.newSumCent); + } else { + throw new RuntimeException( + "This booking should not appear in this list, because neither source nor destination is the account we are looking at."); + } + templateBookings.add(tb); + } + + String balance = templateBookings.isEmpty() ? fmtEuro(0) : templateBookings.get(0).balance; + return new ShortTemplateBookingResult(balance, templateBookings); + } + + public static String fmtEuro(long amountCent) { + return String.format("%.2f EUR", amountCent / 100.0); + } + + private String describeAccount(BookingAccountEntry account) { + if (account.isMainAccount) { + return "Hauptkonto"; + } else if (account.isVATAccount) { + return "Mehrwertsteuer"; + } else if (account.supplierAccount != null) { + return "Lieferant " + account.supplierAccount.id; + } else if (account.userAccount != null) { + return "Kunde " + account.userAccount.id; + } else { + return "- unbekannt -"; + } + } + + private String linkAddrOfAccount(BookingAccountEntry account) { + if (account.isMainAccount) { + return "/intern/accounting/main"; + } else if (account.isVATAccount) { + return "/intern/accounting/vat"; + } else if (account.supplierAccount != null) { + return "/intern/suppliers/" + account.supplierAccount.id; + } else if (account.userAccount != null) { + return "/intern/customers/" + account.userAccount.id; + } else { + return null; + } + } + + private String describeReference(BookingReason reason) { + if (reason.customerOrder != null) { + return reason.customerOrder.id + ""; + } else if (reason.customerPayment != null) { + return "Bezahlung mit Kreditkarte " + reason.customerPayment.payment.creditCardNumber; + } else if (reason.supplierOrder != null) { + return "Lieferanten-Bestellung " + reason.supplierOrder.id; + } else { + return "-"; + } + } + + private String linkToReference(BookingReason reason) { + if (reason.customerOrder != null) { + return "/intern/customerOrders/" + reason.customerOrder.id; + } else { + return null; + } + } + + @GetMapping("/intern/accounting/") + public String accounting(Model model) { + List bookings = bookingRepository.allBookingsReverseChronologically(); + List templateBookings = new ArrayList<>(); + for (Booking booking : bookings) { + TemplateBooking tb = new TemplateBooking(); + tb.datetime = new SimpleDateFormat("dd.MM.yyyy HH:mm").format(booking.created); + tb.amount = fmtEuro(booking.amountCent); + if (booking.source != null) { + tb.source = describeAccount(booking.source); + tb.sourceAddr = linkAddrOfAccount(booking.source); + tb.sourceBalance = fmtEuro(booking.source.newSumCent); + } else { + tb.source = "-"; + tb.sourceAddr = null; + tb.sourceBalance = "-"; + } + if (booking.destination != null) { + tb.destination = describeAccount(booking.destination); + tb.destinationAddr = linkAddrOfAccount(booking.destination); + tb.destinationBalance = fmtEuro(booking.destination.newSumCent); + } else { + tb.destination = "-"; + tb.destinationAddr = null; + tb.destinationBalance = "-"; + } + tb.reason = booking.reason.comment; + tb.reference = describeReference(booking.reason); + tb.referenceAddr = linkToReference(booking.reason); + templateBookings.add(tb); + } + + model.addAttribute("bookings", templateBookings); + return "intern/accounting/index"; + } + + @GetMapping("/intern/accounting/vat") + public String accountingVat(Model model) { + List bookings = bookingRepository.vatBookingsReverseChronologically(); + ShortTemplateBookingResult result = buildShortTemplate(bookings, account -> account.isVATAccount); + model.addAttribute("balance", result.balance); + model.addAttribute("bookings", result.bookings); + return "intern/accounting/vat"; + } + + @GetMapping("/intern/accounting/main") + public String accountingIntern(Model model) { + List bookings = bookingRepository.mainBookingsReverseChronologically(); + ShortTemplateBookingResult result = buildShortTemplate(bookings, account -> account.isMainAccount); + model.addAttribute("balance", result.balance); + model.addAttribute("bookings", result.bookings); + return "intern/accounting/main"; + } +} diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/intern/accounting/ManualAccountingController.java b/prototype/src/main/java/org/hso/ecommerce/controller/intern/accounting/ManualAccountingController.java new file mode 100644 index 0000000..fd820b1 --- /dev/null +++ b/prototype/src/main/java/org/hso/ecommerce/controller/intern/accounting/ManualAccountingController.java @@ -0,0 +1,270 @@ +package org.hso.ecommerce.controller.intern.accounting; + +import java.util.Optional; + +import org.hso.ecommerce.action.booking.CreateBookingAction; +import org.hso.ecommerce.entities.booking.Booking; +import org.hso.ecommerce.entities.booking.BookingAccountEntry; +import org.hso.ecommerce.entities.booking.BookingReason; +import org.hso.ecommerce.repos.booking.BookingAccountEntryRepository; +import org.hso.ecommerce.repos.booking.BookingRepository; +import org.hso.ecommerce.repos.supplier.SupplierRepository; +import org.hso.ecommerce.repos.user.UserRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PostMapping; + +@Controller +public class ManualAccountingController { + + @Autowired + final BookingRepository bookingRepository = null; + + @Autowired + final BookingAccountEntryRepository bookingAccountEntryRepository = null; + + @Autowired + final UserRepository userRepository = null; + + @Autowired + final SupplierRepository supplierRepository = null; + + /** + * Collection for the form values used to create a manual booking + */ + public static class ManualAccounting { + String amount; + String source; + String sourceCustomer; + String sourceSupplier; + String destination; + String destinationCustomer; + String destinationSupplier; + String reason; + String reasonText; + + /** + * Default constructor with default values for the form + */ + public ManualAccounting() { + amount = "0.00"; + reason = "Manual"; + } + + public String getAmount() { + return amount; + } + + public void setAmount(String amount) { + this.amount = amount; + } + + public String getSource() { + return source; + } + + public void setSource(String source) { + this.source = source; + } + + public String getSourceCustomer() { + return sourceCustomer; + } + + public void setSourceCustomer(String sourceCustomer) { + this.sourceCustomer = sourceCustomer; + } + + public String getSourceSupplier() { + return sourceSupplier; + } + + public void setSourceSupplier(String sourceSupplier) { + this.sourceSupplier = sourceSupplier; + } + + public String getDestination() { + return destination; + } + + public void setDestination(String destination) { + this.destination = destination; + } + + public String getDestinationCustomer() { + return destinationCustomer; + } + + public void setDestinationCustomer(String destinationCustomer) { + this.destinationCustomer = destinationCustomer; + } + + public String getDestinationSupplier() { + return destinationSupplier; + } + + public void setDestinationSupplier(String destinationSupplier) { + this.destinationSupplier = destinationSupplier; + } + + public String getReason() { + return reason; + } + + public void setReason(String reason) { + this.reason = reason; + } + + public String getReasonText() { + return reasonText; + } + + public void setReasonText(String reasonText) { + this.reasonText = reasonText; + } + } + + /** + * An exception to represent errors that can be shown to the user + */ + public static class InvalidFormDataException extends Exception { + public InvalidFormDataException(String msg) { + super(msg); + } + + private static final long serialVersionUID = 1L; + } + + private boolean sameAccountBothSides(ManualAccounting formData) { + // No need to check for NumberFormatException because the numbers were already parsed before. + if (!formData.getSource().equals(formData.getDestination())) { + return false; + } else if (formData.getSource().equals("Cust") + && Long.parseLong(formData.getSourceCustomer()) != Long.parseLong(formData.getDestinationCustomer())) { + return false; + } else if (formData.getSource().equals("Sup") + && Long.parseLong(formData.getSourceSupplier()) != Long.parseLong(formData.getDestinationSupplier())) { + return false; + } else { + return true; + } + } + + public Booking createBooking(ManualAccounting formData) throws InvalidFormDataException { + if (formData.getSource() == null) { + throw new InvalidFormDataException("Bitte wählen Sie ein Quellkonto aus."); + } else if (formData.getDestination() == null) { + throw new InvalidFormDataException("Bitte wählen Sie ein Zielkonto aus."); + } + BookingAccountEntry source = getAccountFromFormData(formData.getSource(), formData.getSourceCustomer(), + formData.getSourceSupplier()); + BookingAccountEntry destination = getAccountFromFormData(formData.getDestination(), + formData.getDestinationCustomer(), formData.getDestinationSupplier()); + + if (sameAccountBothSides(formData)) { + throw new InvalidFormDataException("Quell- und Zielkonto dürfen nicht das selbe sein."); + } + + double doubleAmount; + try { + doubleAmount = Double.parseDouble(formData.amount); + } catch (NumberFormatException e) { + throw new InvalidFormDataException("Der angegebene Betrag ist ungültig."); + } + int amountCent = (int) Math.round(doubleAmount * 100); + + BookingReason reason = new BookingReason(); + if (formData.getReason().equals("Start")) { + reason.isStartBooking = true; + } else if (formData.getReason().equals("Manual")) { + reason.isManuel = true; + } else { + throw new RuntimeException("Invalid form value for the booking reason: " + formData.getReason()); + } + reason.comment = formData.reasonText; + + CreateBookingAction action = new CreateBookingAction(source, destination, reason, amountCent); + return action.finish(); + } + + /** + * Retrieve the corresponding account based on user-input + * + * @param account The chosen value on the radio buttons + * @param customer The given customer id from the corresponding text field + * @param supplier the given supplier id from the corresponding text field + * @return The account entry that can be used to create the new booking + * @throws InvalidFormDataException If the user provided incorrect data in any way + */ + private BookingAccountEntry getAccountFromFormData(String account, String customer, String supplier) + throws InvalidFormDataException { + if (account.equals("None")) { + return null; + } else if (account.equals("Main")) { + return bookingAccountEntryRepository.getByMain().orElseGet(BookingAccountEntry::newMain); + } else if (account.equals("Vat")) { + return bookingAccountEntryRepository.getByVat().orElseGet(BookingAccountEntry::newVat); + } else if (account.equals("Cust")) { + long userId; + try { + userId = Long.parseLong(customer); + } catch (NumberFormatException e) { + throw new InvalidFormDataException("Die angegebene Kunden-Nr. ist ungültig."); + } + Optional bookingAccount = bookingAccountEntryRepository.getByUser(userId); + if (!bookingAccount.isPresent()) { + bookingAccount = userRepository.findById(userId).map((user) -> BookingAccountEntry.newUser(user)); + } + if (bookingAccount.isPresent()) { + return bookingAccount.get(); + } else { + throw new InvalidFormDataException("Der Kunde Nr. " + userId + " konnte nicht gefunden werden."); + } + } else if (account.equals("Sup")) { + long supplierId; + try { + supplierId = Long.parseLong(supplier); + } catch (NumberFormatException e) { + throw new InvalidFormDataException("Die angegebene Lieferanten-Nr. ist ungültig."); + } + Optional bookingAccount = bookingAccountEntryRepository.getBySupplier(supplierId); + if (!bookingAccount.isPresent()) { + bookingAccount = supplierRepository.findById(supplierId) + .map((sup) -> BookingAccountEntry.newSupplier(sup)); + } + if (bookingAccount.isPresent()) { + return bookingAccount.get(); + } else { + throw new InvalidFormDataException( + "Der Lieferant Nr. " + supplierId + " konnte nicht gefunden werden."); + } + } else { + throw new RuntimeException("Invalid form value for an account: " + account); + } + } + + @GetMapping("/intern/accounting/addManual") + public String accountingAddManual(Model model) { + model.addAttribute("form_vals", new ManualAccounting()); + return "intern/accounting/addManual"; + } + + @PostMapping("/intern/accounting/addManual") + public String accountingAddManualSubmit(Model model, @ModelAttribute ManualAccounting formData) { + Booking booking; + try { + booking = createBooking(formData); + bookingRepository.save(booking); + model.addAttribute("info", "Die Buchung wurde erfolgreich erstellt."); + model.addAttribute("form_vals", new ManualAccounting()); // Reply with empty form on success + } catch (InvalidFormDataException e) { + model.addAttribute("error", e.getMessage()); + model.addAttribute("form_vals", formData); + } + return "intern/accounting/addManual"; + } + +} diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/intern/customers/CustomersIndexController.java b/prototype/src/main/java/org/hso/ecommerce/controller/intern/customers/CustomersIndexController.java index a15b927..cbda950 100644 --- a/prototype/src/main/java/org/hso/ecommerce/controller/intern/customers/CustomersIndexController.java +++ b/prototype/src/main/java/org/hso/ecommerce/controller/intern/customers/CustomersIndexController.java @@ -1,8 +1,46 @@ package org.hso.ecommerce.controller.intern.customers; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; + +import org.hso.ecommerce.controller.intern.accounting.AccountingController; +import org.hso.ecommerce.controller.intern.accounting.AccountingController.ShortTemplateBookingResult; +import org.hso.ecommerce.entities.booking.Booking; +import org.hso.ecommerce.repos.booking.BookingRepository; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; @Controller -//@RequestMapping("...") +@RequestMapping("/intern/customers") public class CustomersIndexController { + + @Autowired + private BookingRepository bookingRepository = null; + + @Autowired + private AccountingController accountingController = null; + + @GetMapping("/") + public String internCustomers() { + return "intern/customers/index"; + } + + @GetMapping("/{customerId}") + public String internCustomersId(HttpServletRequest request, @PathVariable(required = true) long customerId) { + + // Table of bookings + List bookings = bookingRepository.customerBookingsReverseChronologically(customerId); + ShortTemplateBookingResult result = accountingController.buildShortTemplate( + bookings, + account -> account.userAccount != null && account.userAccount.id == customerId); + request.setAttribute("balance", result.balance); + request.setAttribute("bookings", result.bookings); + + return "intern/customers/id"; + } + } diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/intern/suppliers/SupplierIndexController.java b/prototype/src/main/java/org/hso/ecommerce/controller/intern/suppliers/SupplierIndexController.java index 8f8c1fc..e8881fd 100644 --- a/prototype/src/main/java/org/hso/ecommerce/controller/intern/suppliers/SupplierIndexController.java +++ b/prototype/src/main/java/org/hso/ecommerce/controller/intern/suppliers/SupplierIndexController.java @@ -4,13 +4,13 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; -import java.util.Optional; +import org.hso.ecommerce.controller.intern.accounting.AccountingController; +import org.hso.ecommerce.controller.intern.accounting.AccountingController.ShortTemplateBooking; +import org.hso.ecommerce.controller.intern.accounting.AccountingController.ShortTemplateBookingResult; import org.hso.ecommerce.entities.booking.Booking; -import org.hso.ecommerce.entities.booking.BookingAccountEntry; import org.hso.ecommerce.entities.supplier.Supplier; import org.hso.ecommerce.entities.supplier.SupplierOrder; -import org.hso.ecommerce.repos.booking.BookingAccountEntryRepository; import org.hso.ecommerce.repos.booking.BookingRepository; import org.hso.ecommerce.repos.supplier.SupplierOrderRepository; import org.hso.ecommerce.repos.supplier.SupplierRepository; @@ -32,10 +32,10 @@ public class SupplierIndexController { private final SupplierOrderRepository supplierOrderRepository = null; @Autowired - private final BookingAccountEntryRepository bookingAccountEntryRepository = null; + private final BookingRepository bookingRepository = null; @Autowired - private final BookingRepository bookingRepository = null; + private final AccountingController accountingController = null; @GetMapping("suppliers") public String listSuppliers(Model model) { @@ -62,22 +62,13 @@ public class SupplierIndexController { orders.add(new UImodelSupplierDetailOrders(supplierOrder)); } - // get latest supplier booking - Optional supplierBooking = bookingAccountEntryRepository.getBySupplier(supplierId); - - // get account balance - String supplierBalance = ((supplierBooking.isPresent()) - ? String.format("%.2f", ((float) supplierBooking.get().newSumCent / 100)) - : "0,00"); - - // add bookings from supplier to UImodel - List bookings = new ArrayList(); - for (Booking booking : bookingRepository.getBySupplier(supplierId)) { - bookings.add(new UImodelSupplierDetailBookings(booking)); - } + // Table of bookings + List bookings = bookingRepository.supplierBookingsReverseChronologically(supplierId); + ShortTemplateBookingResult bookingResult = accountingController.buildShortTemplate(bookings, + account -> account.supplierAccount != null && account.supplierAccount.id == supplierId); UImodelSupplierDetail total = new UImodelSupplierDetail(supplierRepository.findSupplierById(supplierId).name, - supplierBalance, orders, bookings); + bookingResult.balance, orders, bookingResult.bookings); model.addAttribute("SupplierDetail", total); @@ -100,10 +91,11 @@ public class SupplierIndexController { public String name; public String balance; public List orders; - public List bookings; + public List bookings; public UImodelSupplierDetail(String name, String balance, List orders, - List bookings) { + List bookings + ) { this.name = name; this.balance = balance; this.orders = orders; diff --git a/prototype/src/main/java/org/hso/ecommerce/entities/booking/Booking.java b/prototype/src/main/java/org/hso/ecommerce/entities/booking/Booking.java index e61ea07..64ef1cd 100644 --- a/prototype/src/main/java/org/hso/ecommerce/entities/booking/Booking.java +++ b/prototype/src/main/java/org/hso/ecommerce/entities/booking/Booking.java @@ -1,6 +1,7 @@ package org.hso.ecommerce.entities.booking; import javax.persistence.*; +import javax.validation.constraints.NotNull; @Entity @Table(name = "bookings") @@ -14,6 +15,9 @@ public class Booking { // always >= 0 public int amountCent; + @NotNull + public java.sql.Timestamp created; + @ManyToOne(optional = true, cascade = CascadeType.ALL) public BookingAccountEntry source; diff --git a/prototype/src/main/java/org/hso/ecommerce/repos/booking/BookingRepository.java b/prototype/src/main/java/org/hso/ecommerce/repos/booking/BookingRepository.java index fe01783..e72ae6a 100644 --- a/prototype/src/main/java/org/hso/ecommerce/repos/booking/BookingRepository.java +++ b/prototype/src/main/java/org/hso/ecommerce/repos/booking/BookingRepository.java @@ -10,8 +10,19 @@ import org.springframework.stereotype.Repository; @Repository public interface BookingRepository extends JpaRepository { - // Return a list with all bookings entries, sorted by id - @Query(value = "SELECT * FROM bookings as b INNER JOIN booking_account_entries ON b.destination_id=booking_account_entries.id OR b.source_id=booking_account_entries.id WHERE booking_account_entries.supplier_account_id = :supplier ORDER BY b.id DESC", nativeQuery = true) - List getBySupplier(Long supplier); + @Query("SELECT b FROM Booking b ORDER BY b.id DESC") + List allBookingsReverseChronologically(); + + @Query("SELECT b FROM Booking b LEFT JOIN b.source s LEFT JOIN b.destination d WHERE s.isMainAccount = 1 OR d.isMainAccount = 1 ORDER BY b.id DESC") + List mainBookingsReverseChronologically(); + + @Query("SELECT b FROM Booking b LEFT JOIN b.source s LEFT JOIN b.destination d WHERE s.isVATAccount = 1 OR d.isVATAccount = 1 ORDER BY b.id DESC") + List vatBookingsReverseChronologically(); + + @Query("SELECT b FROM Booking b LEFT JOIN b.source s LEFT JOIN b.destination d WHERE s.userAccount.id = :customerId OR d.userAccount.id = :customerId ORDER BY b.id DESC") + List customerBookingsReverseChronologically(long customerId); + + @Query("SELECT b FROM Booking b LEFT JOIN b.source s LEFT JOIN b.destination d WHERE s.supplierAccount.id = :supplierId OR d.supplierAccount.id = :supplierId ORDER BY b.id DESC") + List supplierBookingsReverseChronologically(long supplierId); } diff --git a/prototype/src/main/resources/templates/intern/accounting/addManual.html b/prototype/src/main/resources/templates/intern/accounting/addManual.html index d872206..9161dc7 100644 --- a/prototype/src/main/resources/templates/intern/accounting/addManual.html +++ b/prototype/src/main/resources/templates/intern/accounting/addManual.html @@ -20,10 +20,10 @@
-
+
-  EUR +  EUR
@@ -31,26 +31,26 @@
- +
- +
- +
- + - +
- + - +
@@ -59,26 +59,26 @@
- +
- +
- +
- + - +
- + - +
@@ -87,13 +87,13 @@
- - + +
- - - + + +
diff --git a/prototype/src/main/resources/templates/intern/accounting/index.html b/prototype/src/main/resources/templates/intern/accounting/index.html index 206e218..7d832fa 100644 --- a/prototype/src/main/resources/templates/intern/accounting/index.html +++ b/prototype/src/main/resources/templates/intern/accounting/index.html @@ -49,48 +49,21 @@ Referenz - - 10.09.2019 14:10 - 119,00 EUR - - - - - Kunde 5080 - 0 EUR - Kunden-Bezahlung - Bezahlung mit Kreditkarte XXXXX480 - + + + - - 10.09.2019 13:45 - 19,00 EUR - Hauptkonto - 331,00 EUR - Mehrwertsteuer - 1510,95 EUR - Kunden-Bestellung - 2504 - + + + - - 10.09.2019 13:45 - 100,00 EUR - Kunde 5080 - -100,00 EUR - Hauptkonto - 350,00 EUR - Kunden-Bestellung - 2504 - + + + - - 19.08.2019 12:31 - 250,00 EUR - - - - - Hauptkonto - 250,00 EUR - Startkapital - - + + + diff --git a/prototype/src/main/resources/templates/intern/accounting/main.html b/prototype/src/main/resources/templates/intern/accounting/main.html index 7532df5..ed7345c 100644 --- a/prototype/src/main/resources/templates/intern/accounting/main.html +++ b/prototype/src/main/resources/templates/intern/accounting/main.html @@ -25,7 +25,7 @@

Kontostand

-

331,00 EUR

+

@@ -42,33 +42,18 @@ - - - + + - + + - - + - - - - - - - - - - - - - - - + +
Grund Referenz
10.09.2019 13:45-19,00 EUR
+ - Mehrwertsteuer331,00 EUR - Kunden-Bestellung2504
-
10.09.2019 13:45100,00 EURKunde 5080350,00 EURKunden-Bestellung2504
19.08.2019 12:31250,00 EUR -250,00 EURStartkapital - +
diff --git a/prototype/src/main/resources/templates/intern/accounting/vat.html b/prototype/src/main/resources/templates/intern/accounting/vat.html index 1f43097..806141c 100644 --- a/prototype/src/main/resources/templates/intern/accounting/vat.html +++ b/prototype/src/main/resources/templates/intern/accounting/vat.html @@ -26,7 +26,7 @@

Kontostand

-

1510.95 EUR

+

@@ -43,13 +43,18 @@ - - - - - - - + + + +
Grund Referenz
10.09.2019 13:4519,00 EURHauptkonto1510,95 EURKunden-Bestellung2504
+ + + + + + + +
diff --git a/prototype/src/main/resources/templates/intern/customers/id.html b/prototype/src/main/resources/templates/intern/customers/id.html index 33ba95b..4b41c22 100644 --- a/prototype/src/main/resources/templates/intern/customers/id.html +++ b/prototype/src/main/resources/templates/intern/customers/id.html @@ -146,7 +146,7 @@

Buchungen

Kontostand

-

0,00 EUR

+

@@ -164,21 +164,18 @@ - - - - - - - - - - - - - - - + + + +
Grund Referenz
10.09.2019 14:10119,00 EUR -0 EURKunden-BezahlungBezahlung mit Kreditkarte XXXXXXXX480
10.09.2019 13:45-100,00 EURHauptkonto-100,00 EURKunden-Bestellung2504
+ + + + + + + +

diff --git a/prototype/src/main/resources/templates/intern/index.html b/prototype/src/main/resources/templates/intern/index.html index dff0ab0..95997d7 100644 --- a/prototype/src/main/resources/templates/intern/index.html +++ b/prototype/src/main/resources/templates/intern/index.html @@ -88,12 +88,12 @@

Hauptkonto

-

4080,00 EUR

+

Umsatzsteuerkonto

-

-505,00 EUR

+

diff --git a/prototype/src/main/resources/templates/intern/suppliers/id.html b/prototype/src/main/resources/templates/intern/suppliers/id.html index 9577868..117eb0c 100644 --- a/prototype/src/main/resources/templates/intern/suppliers/id.html +++ b/prototype/src/main/resources/templates/intern/suppliers/id.html @@ -67,7 +67,7 @@

Buchungen

Kontostand

-

+

@@ -84,12 +84,17 @@ - - - - - - + + +
+ + + + + + + +
@@ -98,4 +103,4 @@

- \ No newline at end of file +