feature/cash_bookings #55
@ -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;
|
||||
|
||||
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +0,0 @@
|
||||
package org.hso.ecommerce.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
|
||||
@Controller
|
||||
//@RequestMapping("...")
|
||||
public class BookingController {
|
||||
}
|
@ -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<BookingAccountEntry> mainAccount = bookingAccountEntryRepository.getByMain();
|
||||
int mainAccountBalance = mainAccount.map(entry -> entry.newSumCent).orElse(0);
|
||||
Optional<BookingAccountEntry> 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";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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<ShortTemplateBooking> bookings;
|
||||
|
||||
public ShortTemplateBookingResult(String balance, List<ShortTemplateBooking> 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<Booking> bookings, AccountFilter currentAccount) {
|
||||
List<ShortTemplateBooking> 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<Booking> bookings = bookingRepository.allBookingsReverseChronologically();
|
||||
|
||||
List<TemplateBooking> 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<Booking> bookings = bookingRepository.vatBookingsReverseChronologically();
|
||||
Seil0
commented
Statt Statt `request` wird eigentlich `model` verwendet.
|
||||
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<Booking> bookings = bookingRepository.mainBookingsReverseChronologically();
|
||||
Seil0
commented
Statt Statt `request` wird eigentlich `model` verwendet.
|
||||
ShortTemplateBookingResult result = buildShortTemplate(bookings, account -> account.isMainAccount);
|
||||
model.addAttribute("balance", result.balance);
|
||||
model.addAttribute("bookings", result.bookings);
|
||||
return "intern/accounting/main";
|
||||
}
|
||||
}
|
@ -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.");
|
||||
Seil0
commented
.or() ist erst ab Java 9 verfügbar .or() ist erst ab Java 9 verfügbar
|
||||
}
|
||||
Optional<BookingAccountEntry> 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;
|
||||
Seil0
commented
.or() ist erst ab Java 9 verfügbar .or() ist erst ab Java 9 verfügbar
|
||||
try {
|
||||
supplierId = Long.parseLong(supplier);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new InvalidFormDataException("Die angegebene Lieferanten-Nr. ist ungültig.");
|
||||
}
|
||||
Optional<BookingAccountEntry> 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";
|
||||
}
|
||||
|
||||
}
|
@ -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")
|
||||
Seil0
commented
Wird das nicht in feature/customers gemacht? Wird das nicht in feature/customers gemacht?
Lukas
commented
Ich hab die Anzeige der Buchungen in der Kundenübersicht implementiert. Ich hab die Anzeige der Buchungen in der Kundenübersicht implementiert.
Dieser Branch ist auch schon mit feature/customers zusammengeführt.
|
||||
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<Booking> 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";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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<BookingAccountEntry> 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<UImodelSupplierDetailBookings> bookings = new ArrayList<UImodelSupplierDetailBookings>();
|
||||
for (Booking booking : bookingRepository.getBySupplier(supplierId)) {
|
||||
bookings.add(new UImodelSupplierDetailBookings(booking));
|
||||
}
|
||||
// Table of bookings
|
||||
List<Booking> 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<UImodelSupplierDetailOrders> orders;
|
||||
public List<UImodelSupplierDetailBookings> bookings;
|
||||
public List<ShortTemplateBooking> bookings;
|
||||
|
||||
public UImodelSupplierDetail(String name, String balance, List<UImodelSupplierDetailOrders> orders,
|
||||
List<UImodelSupplierDetailBookings> bookings) {
|
||||
List<ShortTemplateBooking> bookings
|
||||
) {
|
||||
this.name = name;
|
||||
this.balance = balance;
|
||||
this.orders = orders;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -10,8 +10,19 @@ import org.springframework.stereotype.Repository;
|
||||
@Repository
|
||||
public interface BookingRepository extends JpaRepository<Booking, Long> {
|
||||
|
||||
// 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<Booking> getBySupplier(Long supplier);
|
||||
@Query("SELECT b FROM Booking b ORDER BY b.id DESC")
|
||||
List<Booking> 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<Booking> 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<Booking> 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<Booking> 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<Booking> supplierBookingsReverseChronologically(long supplierId);
|
||||
|
||||
}
|
||||
|
@ -20,10 +20,10 @@
|
||||
<main class="sidebar-layout content-width">
|
||||
<nav th:replace="fragments/intern :: sidebar"></nav>
|
||||
<div class="content-width">
|
||||
<form class="detailgrid">
|
||||
<form th:action="@{/intern/accounting/addManual}" th:object="${form_vals}" method="post" class="detailgrid">
|
||||
<div class="s">
|
||||
<label for="amount">Betrag</label>
|
||||
<input type="number" step="0.01" name="amount" value="0.00"/> EUR
|
||||
<input type="number" step="0.01" id="amount" th:field="*{amount}" /> EUR
|
||||
</div>
|
||||
<div class="spacer"></div>
|
||||
|
||||
@ -31,26 +31,26 @@
|
||||
<fieldset>
|
||||
<label for="source">Von Konto:</label>
|
||||
<fieldset>
|
||||
<input type="radio" id="s-no" name="destination" value="None" required>
|
||||
<input type="radio" id="s-no" th:field="*{source}" value="None" required>
|
||||
<label for="s-no">Kein Konto</label>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<input type="radio" id="s-main" name="destination" value="Main" required>
|
||||
<input type="radio" id="s-main" th:field="*{source}" value="Main" required>
|
||||
<label for="s-main">Hauptkonto</label>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<input type="radio" id="s-vat" name="destination" value="Vat" required>
|
||||
<input type="radio" id="s-vat" th:field="*{source}" value="Vat" required>
|
||||
<label for="s-vat">Mehrwertsteuerkonto</label>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<input type="radio" id="s-cust" name="destination" value="Cust" required>
|
||||
<input type="radio" id="s-cust" th:field="*{source}" value="Cust" required>
|
||||
<label for="s-cust">Kundenkonto</label>
|
||||
<input placeholder="Kunden Nr." type="text" name="destination-customer" value=""/>
|
||||
<input placeholder="Kunden Nr." type="text" th:field="*{sourceCustomer}" value=""/>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<input type="radio" id="s-sup" name="destination" value="Sup" required>
|
||||
<input type="radio" id="s-sup" th:field="*{source}" value="Sup" required>
|
||||
<label for="s-sup">Lieferanten Konto</label>
|
||||
<input placeholder="Lieferanten Nr." type="text" name="destination-sup" value=""/>
|
||||
<input placeholder="Lieferanten Nr." type="text" th:field="*{sourceSupplier}" value=""/>
|
||||
</fieldset>
|
||||
</fieldset>
|
||||
</div>
|
||||
@ -59,26 +59,26 @@
|
||||
<fieldset>
|
||||
<label for="destination">Nach Konto:</label>
|
||||
<fieldset>
|
||||
<input type="radio" id="d-no" name="destination" value="None" required>
|
||||
<input type="radio" id="d-no" th:field="*{destination}" value="None" required>
|
||||
<label for="d-no">Kein Konto</label>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<input type="radio" id="d-main" name="destination" value="Main" required>
|
||||
<input type="radio" id="d-main" th:field="*{destination}" value="Main" required>
|
||||
<label for="d-main">Hauptkonto</label>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<input type="radio" id="d-vat" name="destination" value="Vat" required>
|
||||
<input type="radio" id="d-vat" th:field="*{destination}" value="Vat" required>
|
||||
<label for="d-vat">Mehrwertsteuerkonto</label>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<input type="radio" id="d-cust" name="destination" value="Cus" required>
|
||||
<input type="radio" id="d-cust" th:field="*{destination}" value="Cust" required>
|
||||
<label for="d-cust">Kundenkonto</label>
|
||||
<input placeholder="Kunden Nr." type="text" name="destination-customer" value=""/>
|
||||
<input placeholder="Kunden Nr." type="text" th:field="*{destinationCustomer}" value=""/>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<input type="radio" id="d-sup" name="destination" value="Sup" required>
|
||||
<input type="radio" id="d-sup" th:field="*{destination}" value="Sup" required>
|
||||
<label for="d-sup">Lieferanten Konto</label>
|
||||
<input placeholder="Lieferanten Nr." type="text" name="destination-sup" value=""/>
|
||||
<input placeholder="Lieferanten Nr." type="text" th:field="*{destinationSupplier}" value=""/>
|
||||
</fieldset>
|
||||
</fieldset>
|
||||
</div>
|
||||
@ -87,13 +87,13 @@
|
||||
<fieldset>
|
||||
<label for="reason">Buchungsgrund:</label>
|
||||
<fieldset>
|
||||
<input type="radio" name="reason" value="Start">
|
||||
<label for="d-sup">Startbuchung</label>
|
||||
<input type="radio" id="r-start" th:field="*{reason}" value="Start">
|
||||
<label for="r-start">Startbuchung</label>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<input type="radio" name="reason" value="Manual" checked>
|
||||
<label for="d-sup">Manuell</label>
|
||||
<input placeholder="Grund" class="full-width" type="text" name="reason-man" value=""/>
|
||||
<input type="radio" id="r-manual" th:field="*{reason}" value="Manual">
|
||||
<label for="r-manual">Manuell</label>
|
||||
<input placeholder="Grund" class="full-width" type="text" th:field="*{reasonText}" value=""/>
|
||||
</fieldset>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
@ -49,48 +49,21 @@
|
||||
<th>Referenz</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>10.09.2019 14:10</td>
|
||||
<td>119,00 EUR</td>
|
||||
<td> -</td>
|
||||
<td> -</td>
|
||||
<td><a th:href="@{/intern/customers/5000}">Kunde 5080</a></td>
|
||||
<td>0 EUR</td>
|
||||
<td>Kunden-Bezahlung</td>
|
||||
<td>Bezahlung mit Kreditkarte XXXXX480</td>
|
||||
</tr>
|
||||
<tr th:each="booking: ${bookings}">
|
||||
<td th:text="${booking.datetime}" />
|
||||
<td th:text="${booking.amount}" />
|
||||
|
||||
<tr>
|
||||
<td>10.09.2019 13:45</td>
|
||||
<td>19,00 EUR</td>
|
||||
<td><a th:href="@{/intern/accounting/main}">Hauptkonto</a></td>
|
||||
<td>331,00 EUR</td>
|
||||
<td><a th:href="@{/intern/accounting/vat}">Mehrwertsteuer</a></td>
|
||||
<td>1510,95 EUR</td>
|
||||
<td>Kunden-Bestellung</td>
|
||||
<td><a th:href="@{/intern/customerOrders/450}">2504</a></td>
|
||||
</tr>
|
||||
<td th:if="${booking.sourceAddr}"><a th:href="@{${booking.sourceAddr}}" th:text="${booking.source}" /></td>
|
||||
<td th:unless="${booking.sourceAddr}" th:text="${booking.source}" />
|
||||
<td th:text="${booking.sourceBalance}" />
|
||||
|
||||
<tr>
|
||||
<td>10.09.2019 13:45</td>
|
||||
<td>100,00 EUR</td>
|
||||
<td><a th:href="@{/intern/customers/5000}">Kunde 5080</a></td>
|
||||
<td>-100,00 EUR</td>
|
||||
<td><a th:href="@{/intern/accounting/main}">Hauptkonto</a></td>
|
||||
<td>350,00 EUR</td>
|
||||
<td>Kunden-Bestellung</td>
|
||||
<td><a th:href="@{/intern/customerOrders/450}">2504</a></td>
|
||||
</tr>
|
||||
<td th:if="${booking.destinationAddr}"><a th:href="@{${booking.destinationAddr}}" th:text="${booking.destination}" /></td>
|
||||
<td th:unless="${booking.destinationAddr}" th:text="${booking.destination}" />
|
||||
<td th:text="${booking.destinationBalance}" />
|
||||
|
||||
<tr>
|
||||
<td>19.08.2019 12:31</td>
|
||||
<td>250,00 EUR</td>
|
||||
<td> -</td>
|
||||
<td> -</td>
|
||||
<td><a th:href="@{/intern/accounting/main}">Hauptkonto</a></td>
|
||||
<td>250,00 EUR</td>
|
||||
<td>Startkapital</td>
|
||||
<td> -</td>
|
||||
<td th:text="${booking.reason}" />
|
||||
<td th:if="${booking.referenceAddr}"><a th:href="@{${booking.referenceAddr}}" th:text="${booking.reference}" /></td>
|
||||
<td th:unless="${booking.referenceAddr}" th:text="${booking.reference}" />
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
@ -25,7 +25,7 @@
|
||||
<nav th:replace="fragments/intern :: sidebar"></nav>
|
||||
<div class="content-width">
|
||||
<h3> Kontostand </h3>
|
||||
<h2> 331,00 EUR </h2>
|
||||
<h2 th:text="${balance}" />
|
||||
<p>
|
||||
<table id="main-table">
|
||||
<tr>
|
||||
@ -42,33 +42,18 @@
|
||||
<th>Grund</th>
|
||||
<th>Referenz</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>10.09.2019 13:45</td>
|
||||
<td>-19,00 EUR</td>
|
||||
<tr th:each="booking: ${bookings}">
|
||||
<td th:text="${booking.datetime}" />
|
||||
<td th:text="${booking.amount}" />
|
||||
|
||||
<td><a th:href="@{/intern/accounting/vat}">Mehrwertsteuer</a></td>
|
||||
<td>331,00 EUR</td>
|
||||
<td th:if="${booking.sourceAddr}"><a th:href="@{${booking.sourceAddr}}" th:text="${booking.source}" /></td>
|
||||
<td th:unless="${booking.sourceAddr}" th:text="${booking.source}" />
|
||||
|
||||
<td>Kunden-Bestellung</td>
|
||||
<td><a th:href="@{/intern/customerOrders/450}">2504</a></td>
|
||||
</tr>
|
||||
<td th:text="${booking.balance}" />
|
||||
|
||||
<tr>
|
||||
<td>10.09.2019 13:45</td>
|
||||
<td>100,00 EUR</td>
|
||||
<td><a th:href="@{/intern/customers/5000}">Kunde 5080</a></td>
|
||||
<td>350,00 EUR</td>
|
||||
<td>Kunden-Bestellung</td>
|
||||
<td><a th:href="@{/intern/customerOrders/450}">2504</a></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>19.08.2019 12:31</td>
|
||||
<td>250,00 EUR</td>
|
||||
<td> -</td>
|
||||
<td>250,00 EUR</td>
|
||||
<td>Startkapital</td>
|
||||
<td> -</td>
|
||||
<td th:text="${booking.reason}" />
|
||||
<td th:if="${booking.referenceAddr}"><a th:href="@{${booking.referenceAddr}}" th:text="${booking.reference}" /></td>
|
||||
<td th:unless="${booking.referenceAddr}" th:text="${booking.reference}" />
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
@ -26,7 +26,7 @@
|
||||
<nav th:replace="fragments/intern :: sidebar"></nav>
|
||||
<div class="content-width">
|
||||
<h3> Kontostand </h3>
|
||||
<h2> 1510.95 EUR </h2>
|
||||
<h2 th:text="${balance}" />
|
||||
<p>
|
||||
<table id="main-table">
|
||||
<tr>
|
||||
@ -43,13 +43,18 @@
|
||||
<th>Grund</th>
|
||||
<th>Referenz</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>10.09.2019 13:45</td>
|
||||
<td>19,00 EUR</td>
|
||||
<td><a th:href="@{/intern/accounting/main}">Hauptkonto</a></td>
|
||||
<td>1510,95 EUR</td>
|
||||
<td>Kunden-Bestellung</td>
|
||||
<td><a th:href="@{/intern/customerOrders/450}">2504</a></td>
|
||||
<tr th:each="booking: ${bookings}">
|
||||
<td th:text="${booking.datetime}" />
|
||||
<td th:text="${booking.amount}" />
|
||||
|
||||
<td th:if="${booking.sourceAddr}"><a th:href="@{${booking.sourceAddr}}" th:text="${booking.source}" /></td>
|
||||
<td th:unless="${booking.sourceAddr}" th:text="${booking.source}" />
|
||||
|
||||
<td th:text="${booking.balance}" />
|
||||
|
||||
<td th:text="${booking.reason}" />
|
||||
<td th:if="${booking.referenceAddr}"><a th:href="@{${booking.referenceAddr}}" th:text="${booking.reference}" /></td>
|
||||
<td th:unless="${booking.referenceAddr}" th:text="${booking.reference}" />
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
@ -146,7 +146,7 @@
|
||||
<h2>Buchungen</h2>
|
||||
<div>
|
||||
<h4> Kontostand </h4>
|
||||
<h3> 0,00 EUR </h3>
|
||||
<h3 th:text="${balance}" />
|
||||
</div>
|
||||
<p>
|
||||
<table id="main-table">
|
||||
@ -164,21 +164,18 @@
|
||||
<th>Grund</th>
|
||||
<th>Referenz</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>10.09.2019 14:10</td>
|
||||
<td>119,00 EUR</td>
|
||||
<td> -</td>
|
||||
<td>0 EUR</td>
|
||||
<td>Kunden-Bezahlung</td>
|
||||
<td>Bezahlung mit Kreditkarte XXXXXXXX480</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>10.09.2019 13:45</td>
|
||||
<td>-100,00 EUR</td>
|
||||
<td><a th:href="@{/intern/accounting/main}">Hauptkonto</a></td>
|
||||
<td>-100,00 EUR</td>
|
||||
<td>Kunden-Bestellung</td>
|
||||
<td><a th:href="@{/intern/customerOrders/450}">2504</a></td>
|
||||
<tr th:each="booking: ${bookings}">
|
||||
<td th:text="${booking.datetime}" />
|
||||
<td th:text="${booking.amount}" />
|
||||
|
||||
<td th:if="${booking.sourceAddr}"><a th:href="@{${booking.sourceAddr}}" th:text="${booking.source}" /></td>
|
||||
<td th:unless="${booking.sourceAddr}" th:text="${booking.source}" />
|
||||
|
||||
<td th:text="${booking.balance}" />
|
||||
|
||||
<td th:text="${booking.reason}" />
|
||||
<td th:if="${booking.referenceAddr}"><a th:href="@{${booking.referenceAddr}}" th:text="${booking.reference}" /></td>
|
||||
<td th:unless="${booking.referenceAddr}" th:text="${booking.reference}" />
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
|
@ -88,12 +88,12 @@
|
||||
<div class="grid xl">
|
||||
<section class="primary hero">
|
||||
<h3>Hauptkonto</h3>
|
||||
<h2>4080,00 EUR</h2>
|
||||
<h2 th:text="${mainAccountBalance}" />
|
||||
</section>
|
||||
|
||||
<section class="primary hero">
|
||||
<h3>Umsatzsteuerkonto</h3>
|
||||
<h2>-505,00 EUR</h2>
|
||||
<h2 th:text="${vatAccountBalance}" />
|
||||
</section>
|
||||
|
||||
<section class="spacer"></section>
|
||||
|
@ -67,7 +67,7 @@
|
||||
<h2>Buchungen</h2>
|
||||
<div>
|
||||
<h4> Kontostand </h4>
|
||||
<h3><span th:text="${SupplierDetail.balance}"></span> €</h3>
|
||||
<h3 th:text="${SupplierDetail.balance}" />
|
||||
</div>
|
||||
<p>
|
||||
<table id="booking-table">
|
||||
@ -84,12 +84,17 @@
|
||||
<tbody>
|
||||
<tr>
|
||||
<tr th:each="booking : ${SupplierDetail.bookings}">
|
||||
<td><span th:text="${booking.dateBooking}"></span></td>
|
||||
<td><span th:text="${booking.price}"></span> €</td>
|
||||
<td><a th:href="@{/intern/accounting/main}" th:text="${booking.srcName}" ></a></td>
|
||||
<td><span th:text="${booking.balance}"></span> €</td>
|
||||
<td><span th:text="${booking.reason}"></span></td>
|
||||
<td><a th:href="${'/intern/supplierOrders/#q=' + booking.orderID}" th:text="${booking.orderID}" class="button smaller"></a></td>
|
||||
<td th:text="${booking.datetime}" />
|
||||
<td th:text="${booking.amount}" />
|
||||
|
||||
<td th:if="${booking.sourceAddr}"><a th:href="@{${booking.sourceAddr}}" th:text="${booking.source}" /></td>
|
||||
<td th:unless="${booking.sourceAddr}" th:text="${booking.source}" />
|
||||
|
||||
<td th:text="${booking.balance}" />
|
||||
|
||||
<td th:text="${booking.reason}" />
|
||||
<td th:if="${booking.referenceAddr}"><a th:href="@{${booking.referenceAddr}}" th:text="${booking.reference}" /></td>
|
||||
<td th:unless="${booking.referenceAddr}" th:text="${booking.reference}" />
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
Statt
request
wird eigentlichmodel
verwendet.