Merge pull request 'feature/cash_bookings' (#55) from feature/cash_bookings into master
Reviewed-by: Jannik Seiler <seil0@mosad.xyz>
This commit is contained in:
commit
6b8bf25e0e
|
@ -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();
|
||||
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();
|
||||
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.");
|
||||
}
|
||||
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;
|
||||
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")
|
||||
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>
|
||||
|
@ -98,4 +103,4 @@
|
|||
</main>
|
||||
<footer th:replace="fragments/footer :: footer"></footer>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
Reference in New Issue