merged feature/customer_orders with master
This commit is contained in:
commit
266bba095a
|
@ -1,6 +1,15 @@
|
|||
INSERT INTO article_offers ("manufacturer", "article_number", "price_per_unit_net", "title", "vat_percent", "should_be_advertised")
|
||||
VALUES ("McDonalds", "1", 4242, "McPizza", 7, 1);
|
||||
/*
|
||||
* add a supplier first
|
||||
*/
|
||||
|
||||
INSERT INTO article_offers ("manufacturer", "article_number", "price_per_unit_net", "title", "vat_percent", "should_be_advertised", "cheapest_supplier_id")
|
||||
VALUES ("McDonalds", "1", 4242, "McPizza", 7, 1, 1);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* There is no need for the add article, you can add one form the UI on the offerd article page
|
||||
*/
|
||||
INSERT INTO articles ("related_id", "shop_price_per_unit_net_cent", "warehouse_units_per_slot", "should_reorder", "reorder_max_price", "title", "description", "image_id")
|
||||
VALUES (1, 19.99, 10, 1, 15, "Huge Hamburger", "This huge Hamburger is awesome!", NULL);
|
||||
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
INSERT INTO suppliers ("api_url", "name", "uuid")
|
||||
VALUES ("https://api.com", "Conrad", "fdfdfg4gdfgdf4gfg");
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
INSERT INTO supplier_orders ("created", "delivered", "number_of_units", "price_per_unit_net_cent", "total_price_net", "ordered_id", "supplier_id")
|
||||
VALUES ('0', '0', '42', '42', '42', '1', '1');
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -30,9 +30,10 @@ public class UpdateOffersAction {
|
|||
public List<ArticleOffer> finish() {
|
||||
HashMap<ArticleIdentifier, ArticleOffer> availableOffers = mapOffers();
|
||||
|
||||
// Reset all advertise-flags first. They are set again below.
|
||||
// Reset all advertise-flags and supplier relations first. They are set again below.
|
||||
for (ArticleOffer offer : availableOffers.values()) {
|
||||
offer.shouldBeAdvertised = false;
|
||||
offer.cheapestSupplier = null;
|
||||
}
|
||||
|
||||
for (Entry<ArticleIdentifier, Offer> cheapestOffer : cheapestOffer.entrySet()) {
|
||||
|
@ -47,7 +48,10 @@ public class UpdateOffersAction {
|
|||
}
|
||||
Article currentOfferedArticle = cheapestOffer.getValue().apiSupplier.findArticle(manufacturer,
|
||||
articleNumber);
|
||||
currentOffer.title = currentOfferedArticle.title;
|
||||
currentOffer.vatPercent = currentOfferedArticle.vatPercent;
|
||||
currentOffer.cheapestSupplier = cheapestOffer.getValue().dbSupplier;
|
||||
currentOffer.pricePerUnitNet = currentOfferedArticle.pricePerUnitNet;
|
||||
|
||||
// Set advertise-flag if any supplier wants it to be set
|
||||
if (currentOfferedArticle.shouldBeAdvertised) {
|
||||
|
|
|
@ -74,9 +74,15 @@ public class CreateOrderAction {
|
|||
CustomerPayment payment = createPayment();
|
||||
|
||||
List<Booking> bookingList = new ArrayList<>();
|
||||
bookingList.add(new CreateBookingAction(latestUserBooking, latestMainBooking, new BookingReason(order), order.totalGrossCent).finish());
|
||||
bookingList.add(new CreateBookingAction(null, latestUserBooking, new BookingReason(payment), order.totalGrossCent).finish());
|
||||
bookingList.add(new CreateBookingAction(latestMainBooking, latestVatBooking, new BookingReason(order), order.totalVatCent).finish());
|
||||
Booking purchaseBooking = new CreateBookingAction(
|
||||
latestUserBooking, latestMainBooking, new BookingReason(order), order.totalGrossCent).finish();
|
||||
Booking paymentBooking = new CreateBookingAction(
|
||||
null, purchaseBooking.source /* userAccount */, new BookingReason(payment), order.totalGrossCent).finish();
|
||||
Booking vatBooking = new CreateBookingAction(
|
||||
purchaseBooking.destination /* mainAccount */, latestVatBooking, new BookingReason(order), order.totalVatCent).finish();
|
||||
bookingList.add(purchaseBooking);
|
||||
bookingList.add(paymentBooking);
|
||||
bookingList.add(vatBooking);
|
||||
|
||||
WarehouseBooking warehouseBooking = createWarehouseBooking(order);
|
||||
|
||||
|
@ -103,7 +109,7 @@ public class CreateOrderAction {
|
|||
|
||||
bookingPosition.article = item.article;
|
||||
bookingPosition.amount = -remove;
|
||||
bookingPosition.slotEntry = slot.copyAddAmount(-remove);
|
||||
bookingPosition.slotEntry = slot.copyAddAmount(-remove, item.article);
|
||||
bookingPosition.booking = booking;
|
||||
|
||||
booking.positions.add(bookingPosition);
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
package org.hso.ecommerce.action.shop;
|
||||
|
||||
import org.hso.ecommerce.entities.shop.Article;
|
||||
import org.hso.ecommerce.repos.shop.ArticleRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class SearchByTermAction {
|
||||
|
||||
public static List<Article> searchByTerm(String sourceTerm, ArticleRepository repository) {
|
||||
|
||||
List<String> terms = Arrays.asList(sourceTerm.split(" "));
|
||||
List<Article> resultArticles = new ArrayList<>();
|
||||
|
||||
terms.forEach(term -> {
|
||||
List<Article> titleArticles = repository.getArticlesByTermInTitle(term); //search in Title
|
||||
titleArticles.forEach(article -> {
|
||||
if(!resultArticles.contains(article)){
|
||||
resultArticles.add(article);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
terms.forEach(term -> {
|
||||
List<Article> descArticles = repository.getArticlesByTermInDescription(term); //search by Term
|
||||
descArticles.forEach(article -> {
|
||||
if(!resultArticles.contains(article)){
|
||||
resultArticles.add(article);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
return resultArticles;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
package org.hso.ecommerce.action.user;
|
||||
|
||||
import org.hso.ecommerce.entities.booking.PaymentMethod;
|
||||
import org.hso.ecommerce.entities.user.User;
|
||||
import org.hso.ecommerce.repos.user.UserRepository;
|
||||
|
||||
public class UpdateUserSettingsAction {
|
||||
|
||||
private User user;
|
||||
private UserRepository repository;
|
||||
|
||||
public UpdateUserSettingsAction(User user, UserRepository repository) {
|
||||
this.user = user;
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
public UpdateResult updateEmail(String newMail) {
|
||||
UpdateResult result = new UpdateResult(false);
|
||||
if (!newMail.contains("@")) {
|
||||
result.errorString = "Ändern der Email-Addresse nicht möglich. Bitte versuchen Sie es erneut.";
|
||||
} else {
|
||||
this.user.email = newMail;
|
||||
this.repository.save(this.user);
|
||||
result.updated = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public UpdateResult updatePassword(String oldPassword, String password1, String password2) {
|
||||
UpdateResult result = new UpdateResult(false);
|
||||
if (this.user.validatePassword(oldPassword)) {
|
||||
if (password1.equals(password2)) {
|
||||
if (!password1.equals(oldPassword)) {
|
||||
this.user.setPassword(password1);
|
||||
this.repository.save(this.user);
|
||||
result.updated = true;
|
||||
} else {
|
||||
result.errorString = "Das neue Passwort entspricht dem alten Passwort.";
|
||||
}
|
||||
} else {
|
||||
result.errorString = "Die beiden neuen Passwörter stimmen nicht überein. Bitte versuchen Sie es erneut.";
|
||||
}
|
||||
} else {
|
||||
result.errorString = "Das eingegebene alte Passwort stimmt nicht mit dem momentan gespeicherten Passwort überein. Bitte versuchen Sie es erneut.";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public UpdateResult updateShippingInfo(String salutation, String name, String address) {
|
||||
this.user.salutation = salutation;
|
||||
this.user.name = name;
|
||||
this.user.defaultDeliveryAddress.addressString = address;
|
||||
this.repository.save(this.user);
|
||||
return new UpdateResult(true);
|
||||
}
|
||||
|
||||
public UpdateResult updatePaymentInfo(String creditCardNumber) {
|
||||
UpdateResult result = new UpdateResult(false);
|
||||
if (creditCardNumber.matches("[0-9]+")) {
|
||||
this.user.defaultPayment = PaymentMethod.fromCreditCardNumber(creditCardNumber);
|
||||
this.repository.save(this.user);
|
||||
result.updated = true;
|
||||
} else {
|
||||
result.errorString = "Kreditkartennummer darf nur Zahlen enthalten. Bitte versuchen Sie es erneut.";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public class UpdateResult {
|
||||
public boolean updated; //if true worked, if false not worked
|
||||
public String errorString;
|
||||
|
||||
public UpdateResult(boolean updated, String errorString) {
|
||||
this.updated = updated;
|
||||
this.errorString = errorString;
|
||||
}
|
||||
|
||||
public UpdateResult(boolean updated) {
|
||||
this.updated = updated;
|
||||
this.errorString = "";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
package org.hso.ecommerce.action.warehouse;
|
||||
|
||||
import org.hso.ecommerce.entities.warehouse.WarehouseBookingPositionSlotEntry;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
public class CalculateWarehouseStatsAction {
|
||||
|
||||
private List<WarehouseBookingPositionSlotEntry> entryList;
|
||||
|
||||
public CalculateWarehouseStatsAction(List<WarehouseBookingPositionSlotEntry> everyCurrentEntry) {
|
||||
this.entryList = everyCurrentEntry;
|
||||
}
|
||||
|
||||
public WarehouseStats finish() {
|
||||
int numArticles = calculateNumArticles();
|
||||
double efficiency = calculateEfficiency();
|
||||
double ratioUsedSlots = calculateRatioSlotsUsed();
|
||||
|
||||
return new WarehouseStats(numArticles, efficiency, ratioUsedSlots);
|
||||
}
|
||||
|
||||
private double calculateRatioSlotsUsed() {
|
||||
int used = 0;
|
||||
|
||||
for (WarehouseBookingPositionSlotEntry entry : entryList) {
|
||||
if (entry.newSumSlot > 0) {
|
||||
used++;
|
||||
}
|
||||
}
|
||||
|
||||
return ((double) used) / entryList.size();
|
||||
}
|
||||
|
||||
private double calculateEfficiency() {
|
||||
double e = 0;
|
||||
|
||||
for (WarehouseBookingPositionSlotEntry entry : entryList) {
|
||||
if (entry.newSumSlot > 0) {
|
||||
e += entry.newSumSlot / (double) entry.article.warehouseUnitsPerSlot;
|
||||
} else {
|
||||
e += 0;
|
||||
}
|
||||
}
|
||||
|
||||
return e / entryList.size();
|
||||
}
|
||||
|
||||
private int calculateNumArticles() {
|
||||
HashSet<Long> articleIds = new HashSet<>();
|
||||
|
||||
for (WarehouseBookingPositionSlotEntry entry : entryList) {
|
||||
if (entry.newSumSlot > 0) {
|
||||
articleIds.add(entry.article.id);
|
||||
}
|
||||
}
|
||||
|
||||
return articleIds.size();
|
||||
}
|
||||
|
||||
private static class WarehouseStats {
|
||||
public int numArticles;
|
||||
public double efficiency;
|
||||
public double ratioUsedSlots;
|
||||
|
||||
WarehouseStats(int numArticles, double efficiency, double ratioUsedSlots) {
|
||||
this.numArticles = numArticles;
|
||||
this.efficiency = efficiency;
|
||||
this.ratioUsedSlots = ratioUsedSlots;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
package org.hso.ecommerce.action.warehouse;
|
||||
|
||||
import org.hso.ecommerce.entities.booking.BookingReason;
|
||||
import org.hso.ecommerce.entities.shop.Article;
|
||||
import org.hso.ecommerce.entities.warehouse.WarehouseBooking;
|
||||
import org.hso.ecommerce.entities.warehouse.WarehouseBookingPosition;
|
||||
import org.hso.ecommerce.entities.warehouse.WarehouseBookingPositionSlotEntry;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Date;
|
||||
import java.util.Optional;
|
||||
|
||||
public class CreateManuelBookingAction {
|
||||
|
||||
private Article article;
|
||||
private int amount;
|
||||
private Optional<WarehouseBookingPositionSlotEntry> source;
|
||||
private Optional<WarehouseBookingPositionSlotEntry> destination;
|
||||
private String reason;
|
||||
|
||||
public CreateManuelBookingAction(Article article, int amount, Optional<WarehouseBookingPositionSlotEntry> source, Optional<WarehouseBookingPositionSlotEntry> destination, String reason) {
|
||||
this.article = article;
|
||||
this.amount = amount;
|
||||
this.source = source;
|
||||
this.destination = destination;
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
public WarehouseBooking finish() throws ArticleSlotConstraintFailedException {
|
||||
WarehouseBooking booking = new WarehouseBooking();
|
||||
booking.created = new Timestamp(new Date().getTime());
|
||||
booking.reason = new BookingReason(reason);
|
||||
|
||||
if (source.isPresent()) {
|
||||
|
||||
if (source.get().article.id != article.id) {
|
||||
throw new ArticleSlotConstraintArticleTypeFailedException();
|
||||
}
|
||||
|
||||
WarehouseBookingPosition bookingPosition = new WarehouseBookingPosition();
|
||||
bookingPosition.booking = booking;
|
||||
|
||||
bookingPosition.article = article;
|
||||
bookingPosition.amount = -amount;
|
||||
bookingPosition.slotEntry = source.get().copyAddAmount(-amount, article);
|
||||
|
||||
if (bookingPosition.slotEntry.newSumSlot < 0 || bookingPosition.slotEntry.newSumSlot > article.warehouseUnitsPerSlot) {
|
||||
throw new ArticleSlotConstraintFailedException("The quantity of article can only be set in bounds.");
|
||||
}
|
||||
|
||||
booking.positions.add(bookingPosition);
|
||||
}
|
||||
|
||||
if (destination.isPresent()) {
|
||||
|
||||
if (destination.get().article.id != article.id && destination.get().newSumSlot > 0) {
|
||||
throw new ArticleSlotConstraintArticleTypeFailedException();
|
||||
}
|
||||
|
||||
WarehouseBookingPosition bookingPosition = new WarehouseBookingPosition();
|
||||
bookingPosition.booking = booking;
|
||||
|
||||
bookingPosition.article = article;
|
||||
bookingPosition.amount = amount;
|
||||
bookingPosition.slotEntry = destination.get().copyAddAmount(amount, article);
|
||||
|
||||
if (bookingPosition.slotEntry.newSumSlot < 0 || bookingPosition.slotEntry.newSumSlot > article.warehouseUnitsPerSlot) {
|
||||
throw new ArticleSlotConstraintFailedException("The quantity of article can only be set in bounds.");
|
||||
}
|
||||
|
||||
booking.positions.add(bookingPosition);
|
||||
}
|
||||
|
||||
return booking;
|
||||
}
|
||||
|
||||
public static class ArticleSlotConstraintFailedException extends Exception {
|
||||
public ArticleSlotConstraintFailedException(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
public ArticleSlotConstraintFailedException() {
|
||||
super("The quantity of article can only be set in bounds.");
|
||||
}
|
||||
}
|
||||
|
||||
public static class ArticleSlotConstraintArticleTypeFailedException extends ArticleSlotConstraintFailedException {
|
||||
public ArticleSlotConstraintArticleTypeFailedException() {
|
||||
super("The Article in the slot entry does not match.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
package org.hso.ecommerce.action.warehouse;
|
||||
|
||||
import org.hso.ecommerce.entities.booking.BookingReason;
|
||||
import org.hso.ecommerce.entities.shop.Article;
|
||||
import org.hso.ecommerce.entities.supplier.SupplierOrder;
|
||||
import org.hso.ecommerce.entities.warehouse.WarehouseBooking;
|
||||
import org.hso.ecommerce.entities.warehouse.WarehouseBookingPosition;
|
||||
import org.hso.ecommerce.entities.warehouse.WarehouseBookingPositionSlotEntry;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public class SupplierOrderArrivedAction {
|
||||
|
||||
private final Article article;
|
||||
private final ArrayList<WarehouseBookingPositionSlotEntry> warehouseCandidates;
|
||||
private final SupplierOrder order;
|
||||
|
||||
public SupplierOrderArrivedAction(List<WarehouseBookingPositionSlotEntry> warehouseCandidates, SupplierOrder order, Article article) {
|
||||
this.warehouseCandidates = new ArrayList<>(warehouseCandidates);
|
||||
this.order = order;
|
||||
this.article = article;
|
||||
}
|
||||
|
||||
public Result finish() throws NoSpaceInWarehouseException {
|
||||
// Sort for most filled slot first;
|
||||
warehouseCandidates.sort((b, a) -> Integer.compare(a.newSumSlot, b.newSumSlot));
|
||||
|
||||
int needed = order.numberOfUnits;
|
||||
|
||||
WarehouseBooking booking = new WarehouseBooking();
|
||||
booking.created = new Timestamp(new Date().getTime());
|
||||
booking.reason = new BookingReason(order);
|
||||
|
||||
for (WarehouseBookingPositionSlotEntry entry : warehouseCandidates) {
|
||||
int canBeAdded = article.warehouseUnitsPerSlot - entry.newSumSlot;
|
||||
|
||||
if (canBeAdded == 0) {
|
||||
// this slot is full, skip
|
||||
continue;
|
||||
}
|
||||
|
||||
int willBeAdded = Math.min(canBeAdded, needed);
|
||||
needed -= willBeAdded;
|
||||
|
||||
WarehouseBookingPosition bookingPosition = new WarehouseBookingPosition();
|
||||
|
||||
bookingPosition.article = article;
|
||||
bookingPosition.amount = willBeAdded;
|
||||
bookingPosition.slotEntry = entry.copyAddAmount(willBeAdded, article);
|
||||
bookingPosition.booking = booking;
|
||||
|
||||
booking.positions.add(bookingPosition);
|
||||
|
||||
if (needed == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (needed > 0) {
|
||||
throw new NoSpaceInWarehouseException(article);
|
||||
}
|
||||
|
||||
order.delivered = new Timestamp(new Date().getTime());
|
||||
return new Result(order, booking);
|
||||
}
|
||||
|
||||
public static class Result extends Exception {
|
||||
|
||||
private final SupplierOrder order;
|
||||
private final WarehouseBooking booking;
|
||||
|
||||
public Result(SupplierOrder order, WarehouseBooking booking) {
|
||||
this.order = order;
|
||||
this.booking = booking;
|
||||
}
|
||||
|
||||
public SupplierOrder getOrder() {
|
||||
return order;
|
||||
}
|
||||
|
||||
public WarehouseBooking getBooking() {
|
||||
return booking;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class NoSpaceInWarehouseException extends Exception {
|
||||
private Article article;
|
||||
|
||||
public NoSpaceInWarehouseException(Article article) {
|
||||
super("The quantity of article '" + article.title + "' does not fit in warehouse.");
|
||||
this.article = article;
|
||||
}
|
||||
|
||||
public Article getArticle() {
|
||||
return article;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,176 +0,0 @@
|
|||
package org.hso.ecommerce.app;
|
||||
|
||||
import org.hso.ecommerce.entities.user.User;
|
||||
import org.hso.ecommerce.repos.user.UserRepository;
|
||||
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.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* TODO clean up this class
|
||||
*/
|
||||
@Controller
|
||||
public class RequestController {
|
||||
|
||||
@Autowired
|
||||
private final UserRepository userRepository = null;
|
||||
|
||||
static int notSoRandom = 0;
|
||||
|
||||
@GetMapping("/login")
|
||||
public String login() {
|
||||
return "login";
|
||||
}
|
||||
|
||||
@PostMapping("/login")
|
||||
public String loginPost(
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
@RequestParam("username") String username,
|
||||
@RequestParam("password") String password,
|
||||
HttpSession session
|
||||
) {
|
||||
String gto = (String) session.getAttribute("afterLogin");
|
||||
|
||||
Optional<User> user = userRepository.findByEmail(username);
|
||||
if (!user.isPresent()) {
|
||||
request.setAttribute("error", "Email Adresse falsch.");
|
||||
response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
|
||||
return "login";
|
||||
}
|
||||
|
||||
if (!user.get().validatePassword(password)) {
|
||||
request.setAttribute("error", "Passwort falsch.");
|
||||
response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
|
||||
return "login";
|
||||
}
|
||||
|
||||
if (!user.get().isActive) {
|
||||
request.setAttribute("error", "User ist deaktiviert.");
|
||||
response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
|
||||
return "login";
|
||||
}
|
||||
|
||||
session.setAttribute("userId", user.get().getId());
|
||||
|
||||
if (gto != null && gto.startsWith("/")) {
|
||||
return "redirect:" + gto;
|
||||
} else {
|
||||
return "redirect:/";
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/logout")
|
||||
public String logoutPost(HttpServletResponse response,
|
||||
HttpSession session
|
||||
) {
|
||||
session.removeAttribute("userId");
|
||||
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/suppliers/")
|
||||
public String internSuppliers() {
|
||||
return "intern/suppliers/index";
|
||||
}
|
||||
|
||||
@GetMapping("/intern/suppliers/{id}")
|
||||
public String internSuppliersId() {
|
||||
return "intern/suppliers/id";
|
||||
}
|
||||
|
||||
@GetMapping("/intern/supplierOrders/")
|
||||
public String internSupplierOrders() {
|
||||
return "intern/supplierOrders/index";
|
||||
}
|
||||
|
||||
@GetMapping("/intern/supplierOrders/{id}")
|
||||
public String internSupplierOrdersId() {
|
||||
return "intern/supplierOrders/id";
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@GetMapping("/intern/suppliersOffers")
|
||||
public String internSuppliersOffers() {
|
||||
return "intern/offeredArticles/index";
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
@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";
|
||||
}
|
||||
|
||||
@GetMapping("/intern/warehouse/")
|
||||
public String accountingWarehouse() {
|
||||
return "intern/warehouse/index";
|
||||
}
|
||||
|
||||
@GetMapping("/intern/warehouse/todo")
|
||||
public String accountingWarehouseTodo() {
|
||||
return "intern/warehouse/todo";
|
||||
}
|
||||
|
||||
@GetMapping("/intern/warehouse/addManual")
|
||||
public String accountingWarehouseAddManual() {
|
||||
return "intern/warehouse/addManual";
|
||||
}
|
||||
|
||||
@PostMapping("/intern/warehouse/progress/{id}")
|
||||
public String accountingWarehouseProgressIdPost(HttpServletResponse response) {
|
||||
if ((notSoRandom++) % 2 == 1) {
|
||||
return "redirect:/intern/warehouse/progress/450";
|
||||
} else {
|
||||
response.setStatus(409);
|
||||
return "intern/warehouse/error_progress_failed";
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/intern/warehouse/progress/{id}")
|
||||
public String accountingWarehouseProgressId() {
|
||||
return "intern/warehouse/id_progress";
|
||||
}
|
||||
|
||||
@GetMapping("/intern/warehouse/slots/")
|
||||
public String accountingWarehouseSlots() {
|
||||
return "intern/warehouse/slots/index";
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
package org.hso.ecommerce.app;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("user")
|
||||
public class UserRequestController {
|
||||
|
||||
@GetMapping("/")
|
||||
public String user() {
|
||||
return "redirect:/user/settings";
|
||||
}
|
||||
|
||||
@GetMapping("/settings")
|
||||
public String userSettings() {
|
||||
return "user/settings";
|
||||
}
|
||||
|
||||
@GetMapping("/orders/")
|
||||
public String userOrdeers() {
|
||||
return "user/orders/index";
|
||||
}
|
||||
|
||||
@GetMapping("/bonuspoints")
|
||||
public String userBonuspoints() {
|
||||
return "user/bonuspoints";
|
||||
}
|
||||
|
||||
@GetMapping("/notifications/")
|
||||
public String userNotifications() {
|
||||
return "user/notifications/index";
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
package org.hso.ecommerce.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
|
||||
@Controller
|
||||
//@RequestMapping("...")
|
||||
public class BookingController {
|
||||
}
|
|
@ -1,8 +1,69 @@
|
|||
package org.hso.ecommerce.controller;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.hso.ecommerce.entities.user.User;
|
||||
import org.hso.ecommerce.repos.user.UserRepository;
|
||||
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.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
@Controller
|
||||
//@RequestMapping("...")
|
||||
@RequestMapping("/")
|
||||
public class LoginController {
|
||||
|
||||
@Autowired
|
||||
private final UserRepository userRepository = null;
|
||||
|
||||
@GetMapping("login")
|
||||
public String login() {
|
||||
return "login";
|
||||
}
|
||||
|
||||
@PostMapping("login")
|
||||
public String loginPost(HttpServletRequest request, HttpServletResponse response,
|
||||
@RequestParam("username") String username, @RequestParam("password") String password, HttpSession session) {
|
||||
|
||||
String gto = (String) session.getAttribute("afterLogin");
|
||||
|
||||
Optional<User> user = userRepository.findByEmail(username);
|
||||
if (!user.isPresent()) {
|
||||
request.setAttribute("error", "Die Email Adresse falsch.");
|
||||
response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
|
||||
return "login";
|
||||
}
|
||||
|
||||
if (!user.get().validatePassword(password)) {
|
||||
request.setAttribute("error", "Das Passwort ist falsch.");
|
||||
response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
|
||||
return "login";
|
||||
}
|
||||
|
||||
if (!user.get().isActive) {
|
||||
request.setAttribute("error", "Dieses Konto ist deaktiviert..");
|
||||
response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
|
||||
return "login";
|
||||
}
|
||||
|
||||
session.setAttribute("userId", user.get().getId());
|
||||
|
||||
if (gto != null && gto.startsWith("/")) {
|
||||
return "redirect:" + gto;
|
||||
} else {
|
||||
return "redirect:/";
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("logout")
|
||||
public String logoutPost(HttpServletResponse response, HttpSession session) {
|
||||
session.removeAttribute("userId");
|
||||
return "redirect:/";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.hso.ecommerce.controller;
|
||||
|
||||
import org.hso.ecommerce.entities.booking.PaymentMethod;
|
||||
import org.hso.ecommerce.entities.shop.Address;
|
||||
import org.hso.ecommerce.entities.user.User;
|
||||
import org.hso.ecommerce.repos.user.UserRepository;
|
||||
|
@ -11,64 +12,71 @@ import org.springframework.web.bind.annotation.RequestParam;
|
|||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.util.Optional;
|
||||
|
||||
@Controller
|
||||
public class RegisterController {
|
||||
public class RegisterController {
|
||||
|
||||
@Autowired
|
||||
private final UserRepository userRepository = null;
|
||||
@Autowired
|
||||
private final UserRepository userRepository = null;
|
||||
|
||||
@PostMapping("/register")
|
||||
public String registerPost(
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
@RequestParam("username") String username,
|
||||
@RequestParam("password") String password,
|
||||
@RequestParam("password2") String password2,
|
||||
@RequestParam("salutation") String salutation,
|
||||
@RequestParam("name") String name,
|
||||
@RequestParam("address") String address,
|
||||
@RequestParam("type") String type,
|
||||
@RequestParam("ad") String ad
|
||||
)
|
||||
{
|
||||
Optional<User> user = userRepository.findByEmail(username);
|
||||
if (user.isPresent()) {
|
||||
request.setAttribute("error", "Email Adresse existiert bereits!");
|
||||
response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
|
||||
return "register";
|
||||
}
|
||||
@PostMapping("/register")
|
||||
public String registerPost(HttpServletRequest request, HttpServletResponse response,
|
||||
@RequestParam("username") String username, @RequestParam("password") String password,
|
||||
@RequestParam("password2") String password2, @RequestParam("salutation") String salutation,
|
||||
@RequestParam("name") String name, @RequestParam("address") String address,
|
||||
@RequestParam("type") String type, // TODO store
|
||||
@RequestParam("ad") String ad, // TODO store
|
||||
HttpSession session) {
|
||||
Optional<User> user = userRepository.findByEmail(username);
|
||||
if (user.isPresent()) {
|
||||
request.setAttribute("error", "Die Email Adresse existiert bereits.");
|
||||
response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
|
||||
return "register";
|
||||
}
|
||||
|
||||
if (!password.equals(password2)){
|
||||
request.setAttribute("error", "Passwörter sind nicht gleich");
|
||||
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
||||
return "register";
|
||||
}
|
||||
if (!password.equals(password2)) {
|
||||
request.setAttribute("error", "Die Passwörter stimmen nicht überein.");
|
||||
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
||||
return "register";
|
||||
}
|
||||
|
||||
//set values for new user
|
||||
User newUser = new User();
|
||||
newUser.email = username;
|
||||
newUser.setPassword(password);
|
||||
newUser.email = username;
|
||||
newUser.isEmployee = false;
|
||||
//TODO for salutation, type, ad are no attributes/fields in the class/database. Add when they are there.
|
||||
// set values for new user
|
||||
User newUser = new User();
|
||||
newUser.email = username;
|
||||
newUser.setPassword(password);
|
||||
newUser.email = username;
|
||||
newUser.isEmployee = false;
|
||||
newUser.salutation = salutation;
|
||||
newUser.defaultPayment = PaymentMethod.fromCreditCardNumber("");
|
||||
|
||||
newUser.isActive = true;
|
||||
newUser.created = new java.sql.Timestamp(System.currentTimeMillis());
|
||||
newUser.isActive = true;
|
||||
newUser.created = new java.sql.Timestamp(System.currentTimeMillis());
|
||||
|
||||
Address newAddress = new Address();
|
||||
newAddress.name = name;
|
||||
newAddress.addressString = address;
|
||||
newUser.defaultDeliveryAddress = newAddress;
|
||||
Address newAddress = new Address();
|
||||
newAddress.name = name;
|
||||
newAddress.addressString = address;
|
||||
newUser.defaultDeliveryAddress = newAddress;
|
||||
|
||||
userRepository.save(newUser); // save newUser
|
||||
userRepository.save(newUser); // save newUser
|
||||
|
||||
return "redirect:/login";
|
||||
}
|
||||
user = userRepository.findByEmail(username);
|
||||
session.setAttribute("userId", user.get().getId());
|
||||
|
||||
@GetMapping("/register")
|
||||
public String register() {
|
||||
return "register";
|
||||
}
|
||||
String gto = (String) session.getAttribute("afterLogin");
|
||||
|
||||
//login after register
|
||||
if (gto != null && gto.startsWith("/")) {
|
||||
return "redirect:" + gto;
|
||||
} else {
|
||||
return "redirect:/";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@GetMapping("/register")
|
||||
public String register() {
|
||||
return "register";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,127 @@
|
|||
package org.hso.ecommerce.controller;
|
||||
|
||||
import org.hso.ecommerce.action.user.UpdateUserSettingsAction;
|
||||
import org.hso.ecommerce.entities.shop.CustomerOrder;
|
||||
import org.hso.ecommerce.entities.user.User;
|
||||
import org.hso.ecommerce.repos.shop.CustomerOrderRepository;
|
||||
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.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.util.List;
|
||||
|
||||
@Controller
|
||||
//@RequestMapping("...")
|
||||
@RequestMapping("/user")
|
||||
public class UserController {
|
||||
|
||||
@Autowired
|
||||
private final UserRepository userRepository = null;
|
||||
|
||||
@Autowired
|
||||
private final CustomerOrderRepository customerOrderRepository = null;
|
||||
|
||||
@GetMapping("/")
|
||||
public String user() {
|
||||
return "redirect:/user/settings";
|
||||
}
|
||||
|
||||
@GetMapping("/settings")
|
||||
public String userSettings(Model model,
|
||||
HttpSession session
|
||||
) {
|
||||
long userId = (long) session.getAttribute("userId");
|
||||
User user = userRepository.findById(userId).get();
|
||||
model.addAttribute("user", user);
|
||||
|
||||
return "user/settings";
|
||||
}
|
||||
|
||||
@GetMapping("/orders/")
|
||||
public String userOrdeers(HttpSession session,
|
||||
Model model
|
||||
) {
|
||||
List<CustomerOrder> orders = customerOrderRepository.getOrdersByUserId((long) session.getAttribute("userId"));
|
||||
model.addAttribute("orders", orders);
|
||||
|
||||
return "user/orders/index";
|
||||
}
|
||||
|
||||
@PostMapping("/settings/changeMail")
|
||||
public String changeMail(HttpSession session,
|
||||
@RequestParam("email") String email,
|
||||
HttpServletRequest request
|
||||
) {
|
||||
User user = userRepository.findById((long) session.getAttribute("userId")).get();
|
||||
|
||||
UpdateUserSettingsAction cusa = new UpdateUserSettingsAction(user, userRepository);
|
||||
UpdateUserSettingsAction.UpdateResult result = cusa.updateEmail(email);
|
||||
if (result.updated == false) {
|
||||
request.setAttribute("error", result.errorString);
|
||||
return "user/settings";
|
||||
}
|
||||
|
||||
return "redirect:/user/settings";
|
||||
}
|
||||
|
||||
@PostMapping("/settings/changePwd")
|
||||
public String changePwd(HttpSession session,
|
||||
@RequestParam("old-password") String oldPassword,
|
||||
@RequestParam("password1") String password1,
|
||||
@RequestParam("password2") String password2,
|
||||
HttpServletRequest request
|
||||
) {
|
||||
User user = userRepository.findById((long) session.getAttribute("userId")).get();
|
||||
|
||||
UpdateUserSettingsAction cusa = new UpdateUserSettingsAction(user, userRepository);
|
||||
UpdateUserSettingsAction.UpdateResult result = cusa.updatePassword(oldPassword, password1, password2);
|
||||
if (result.updated == false) {
|
||||
request.setAttribute("error", result.errorString);
|
||||
return "user/settings";
|
||||
}
|
||||
|
||||
return "redirect:/user/settings";
|
||||
}
|
||||
|
||||
@PostMapping("/settings/changeAddress")
|
||||
public String changeAddress(HttpSession session,
|
||||
@RequestParam("salutation") String salutation,
|
||||
@RequestParam("name") String name,
|
||||
@RequestParam("address") String address,
|
||||
HttpServletRequest request
|
||||
) {
|
||||
User user = userRepository.findById((long) session.getAttribute("userId")).get();
|
||||
|
||||
UpdateUserSettingsAction cusa = new UpdateUserSettingsAction(user, userRepository);
|
||||
UpdateUserSettingsAction.UpdateResult result = cusa.updateShippingInfo(salutation, name, address);
|
||||
if (result.updated == false) {
|
||||
request.setAttribute("error", result.errorString);
|
||||
return "user/settings";
|
||||
}
|
||||
|
||||
return "redirect:/user/settings";
|
||||
}
|
||||
|
||||
@PostMapping("/settings/changePaymentInfo")
|
||||
public String changePaymentInfo(HttpSession session,
|
||||
@RequestParam("creditCardNumber") String creditCardNumber,
|
||||
HttpServletRequest request
|
||||
) {
|
||||
User user = userRepository.findById((long) session.getAttribute("userId")).get();
|
||||
|
||||
UpdateUserSettingsAction cusa = new UpdateUserSettingsAction(user, userRepository);
|
||||
UpdateUserSettingsAction.UpdateResult result = cusa.updatePaymentInfo(creditCardNumber);
|
||||
if (result.updated == false) {
|
||||
request.setAttribute("error", result.errorString);
|
||||
return "user/settings";
|
||||
}
|
||||
|
||||
return "redirect:/user/settings";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ import org.hso.ecommerce.repos.booking.BookingAccountEntryRepository;
|
|||
import org.hso.ecommerce.repos.booking.BookingRepository;
|
||||
import org.hso.ecommerce.repos.cronjob.BackgroundJobRepository;
|
||||
import org.hso.ecommerce.repos.shop.ArticleRepository;
|
||||
import org.hso.ecommerce.repos.shop.CustomerOderRepository;
|
||||
import org.hso.ecommerce.repos.shop.CustomerOrderRepository;
|
||||
import org.hso.ecommerce.repos.supplier.ArticleOfferRepository;
|
||||
import org.hso.ecommerce.repos.supplier.SupplierOrderRepository;
|
||||
import org.hso.ecommerce.repos.supplier.SupplierRepository;
|
||||
|
@ -230,7 +230,7 @@ class CronjobController {
|
|||
final ArticleOfferRepository articleOfferRepository = null;
|
||||
|
||||
@Autowired
|
||||
final CustomerOderRepository customerOrderRepository = null;
|
||||
final CustomerOrderRepository customerOrderRepository = null;
|
||||
|
||||
@Autowired
|
||||
final BookingRepository bookingRepository = null;
|
||||
|
|
|
@ -1,15 +1,5 @@
|
|||
package org.hso.ecommerce.controller.intern;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.hso.ecommerce.entities.shop.Article;
|
||||
import org.hso.ecommerce.entities.shop.Category;
|
||||
import org.hso.ecommerce.entities.shop.Image;
|
||||
|
@ -27,6 +17,16 @@ import org.springframework.web.bind.annotation.*;
|
|||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.servlet.view.RedirectView;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("intern/articles")
|
||||
public class InternArticleController {
|
||||
|
@ -62,16 +62,12 @@ public class InternArticleController {
|
|||
|
||||
@GetMapping("/{id}")
|
||||
public String internListedArticlesId(Model model, @PathVariable String id) {
|
||||
|
||||
int articleid = Integer.parseInt(id);
|
||||
|
||||
UImodelArticle total = new UImodelArticle();
|
||||
|
||||
total.addArticle(articleRepository.findArticleById(articleid),
|
||||
warehouseEntryRepository.getArticleStock(articleid).orElse(0));
|
||||
|
||||
model.addAttribute("ArticleID", total);
|
||||
|
||||
return "intern/listedArticles/id";
|
||||
}
|
||||
|
||||
|
@ -80,7 +76,7 @@ public class InternArticleController {
|
|||
@RequestParam(value = "title", required = true) String title,
|
||||
@RequestParam(value = "description", required = true) String description,
|
||||
@RequestParam(value = "units-per-slot", required = true) String warehouseUnitsPerSlot,
|
||||
@RequestParam(value = "price_netto", required = true) String pricenetto,
|
||||
@RequestParam(value = "priceNet", required = true) String pricenetto,
|
||||
@RequestParam(value = "reorderMaxPrice", required = true) String reorderMaxPrice,
|
||||
@RequestParam(value = "autobuy", required = true) Boolean shouldReorder,
|
||||
@RequestParam(value = "categorie", required = true) String categories,
|
||||
|
@ -148,9 +144,9 @@ public class InternArticleController {
|
|||
File tmpFile = new File(defaultImagePath);
|
||||
// test if default img file exits
|
||||
if (!tmpFile.exists()) {
|
||||
// fallback if the file not exists
|
||||
// fallback if the file not exists
|
||||
// create new file
|
||||
BufferedImage bufferedImage = new BufferedImage(422, 428, BufferedImage.TYPE_INT_RGB);
|
||||
BufferedImage bufferedImage = new BufferedImage(422, 428, BufferedImage.TYPE_INT_RGB);
|
||||
try {
|
||||
ImageIO.write(bufferedImage, "jpg", new File(defaultImagePath)); // save new file on disk
|
||||
} catch (IOException e) {
|
||||
|
@ -192,25 +188,21 @@ public class InternArticleController {
|
|||
public static class UImodelArticles {
|
||||
|
||||
public String imgPath;
|
||||
|
||||
public String title;
|
||||
|
||||
public String price;
|
||||
|
||||
public String price_netto;
|
||||
|
||||
public String priceNet;
|
||||
public String categorie;
|
||||
|
||||
public int stock;
|
||||
|
||||
public long offer_id;
|
||||
|
||||
public long offerID;
|
||||
public long id;
|
||||
|
||||
void addListedArticle(Article article, int stock) {
|
||||
this.imgPath = article.image.path;
|
||||
|
||||
if (article.image != null) {
|
||||
this.imgPath = article.image.path;
|
||||
}
|
||||
this.title = article.title;
|
||||
this.price_netto = String.format("%.2f", ((float) article.shopPricePerUnitNetCent / 100));
|
||||
this.priceNet = String.format("%.2f", ((float) article.shopPricePerUnitNetCent / 100));
|
||||
this.price = String.format("%.2f", ((float) article.getPriceGross() / 100));
|
||||
|
||||
StringBuilder result = new StringBuilder();
|
||||
|
@ -221,7 +213,7 @@ public class InternArticleController {
|
|||
this.categorie = result.toString();
|
||||
|
||||
this.stock = stock;
|
||||
this.offer_id = article.related.id;
|
||||
this.offerID = article.related.id;
|
||||
this.id = article.id;
|
||||
}
|
||||
}
|
||||
|
@ -231,116 +223,31 @@ public class InternArticleController {
|
|||
public String imgPath;
|
||||
public String title;
|
||||
public String price;
|
||||
public String price_netto;
|
||||
public String priceNet;
|
||||
public String reorderMaxPrice;
|
||||
public String categorie;
|
||||
public int stock;
|
||||
public long offer_id;
|
||||
public long offerID;
|
||||
public long id;
|
||||
public boolean shouldReorder;
|
||||
public String warehouseUnitsPerSlot;
|
||||
public String description;
|
||||
|
||||
public String getImgPath() {
|
||||
return imgPath;
|
||||
}
|
||||
|
||||
public void setImgPath(String imgPath) {
|
||||
this.imgPath = imgPath;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public void setPrice(String price) {
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
public String getPrice_netto() {
|
||||
return price_netto;
|
||||
}
|
||||
|
||||
public void setPrice_netto(String price_netto) {
|
||||
this.price_netto = price_netto;
|
||||
}
|
||||
|
||||
public String getReorderMaxPrice() {
|
||||
return reorderMaxPrice;
|
||||
}
|
||||
|
||||
public void setReorderMaxPrice(String reorderMaxPrice) {
|
||||
this.reorderMaxPrice = reorderMaxPrice;
|
||||
}
|
||||
public int vatPercent;
|
||||
|
||||
public String getCategorie() {
|
||||
return categorie;
|
||||
}
|
||||
|
||||
public void setCategorie(String categorie) {
|
||||
this.categorie = categorie;
|
||||
}
|
||||
|
||||
public int getStock() {
|
||||
return stock;
|
||||
}
|
||||
|
||||
public void setStock(int stock) {
|
||||
this.stock = stock;
|
||||
}
|
||||
|
||||
public long getOffer_id() {
|
||||
return offer_id;
|
||||
}
|
||||
|
||||
public void setOffer_id(long offer_id) {
|
||||
this.offer_id = offer_id;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public boolean isShouldReorder() {
|
||||
return shouldReorder;
|
||||
}
|
||||
|
||||
public void setShouldReorder(boolean shouldReorder) {
|
||||
this.shouldReorder = shouldReorder;
|
||||
}
|
||||
|
||||
public String getWarehouseUnitsPerSlot() {
|
||||
return warehouseUnitsPerSlot;
|
||||
}
|
||||
|
||||
public void setWarehouseUnitsPerSlot(String warehouseUnitsPerSlot) {
|
||||
this.warehouseUnitsPerSlot = warehouseUnitsPerSlot;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
void addArticle(Article article, int stock) {
|
||||
this.imgPath = article.image.path;
|
||||
if (article.image != null) {
|
||||
this.imgPath = article.image.path;
|
||||
}
|
||||
this.title = article.title;
|
||||
this.price_netto = String.format("%.2f", ((float) article.shopPricePerUnitNetCent / 100));
|
||||
this.priceNet = String.format("%.2f", ((float) article.shopPricePerUnitNetCent / 100));
|
||||
this.price = String.format("%.2f", ((float) article.getPriceGross() / 100));
|
||||
|
||||
StringBuilder result = new StringBuilder();
|
||||
|
@ -352,12 +259,13 @@ public class InternArticleController {
|
|||
this.categorie = result.toString();
|
||||
|
||||
this.stock = stock;
|
||||
this.offer_id = article.related.id;
|
||||
this.offerID = article.related.id;
|
||||
this.id = article.id;
|
||||
this.reorderMaxPrice = String.format("%.2f", ((float) article.reorderMaxPrice / 100));
|
||||
this.shouldReorder = article.shouldReorder;
|
||||
this.warehouseUnitsPerSlot = String.valueOf(article.warehouseUnitsPerSlot);
|
||||
this.description = article.description;
|
||||
this.vatPercent = article.related.vatPercent;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,8 +1,27 @@
|
|||
package org.hso.ecommerce.controller.intern;
|
||||
|
||||
import org.hso.ecommerce.repos.warehouse.WarehouseBookingRepository;
|
||||
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;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
@Controller
|
||||
//@RequestMapping("...")
|
||||
@RequestMapping("/intern/warehouse/")
|
||||
public class WarehouseController {
|
||||
|
||||
@Autowired
|
||||
private final WarehouseBookingRepository warehouseBookingRepository = null;
|
||||
|
||||
@GetMapping("/")
|
||||
public String accountingWarehouse(
|
||||
Model model,
|
||||
HttpServletRequest request
|
||||
) {
|
||||
model.addAttribute("bookings", warehouseBookingRepository.findAll());
|
||||
return "intern/warehouse/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";
|
||||
}
|
||||
|
||||
}
|
|
@ -4,7 +4,8 @@ import com.fasterxml.jackson.annotation.JsonCreator;
|
|||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import org.hso.ecommerce.api.RestServiceForDelivery;
|
||||
import org.hso.ecommerce.entities.shop.CustomerOrder;
|
||||
import org.hso.ecommerce.repos.shop.CustomerOderRepository;
|
||||
|
||||
import org.hso.ecommerce.repos.shop.CustomerOrderRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.format.datetime.DateFormatterRegistrar;
|
||||
import org.springframework.stereotype.Controller;
|
||||
|
@ -27,7 +28,7 @@ import java.util.stream.Collectors;
|
|||
public class CustomerOrderController {
|
||||
|
||||
@Autowired
|
||||
private final CustomerOderRepository customerOrderRepository = null;
|
||||
private final CustomerOrderRepository customerOrderRepository = null;
|
||||
@Autowired
|
||||
private final RestServiceForDelivery restServiceForDelivery = null;
|
||||
|
||||
|
|
|
@ -1,8 +1,120 @@
|
|||
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.entities.shop.CustomerOrder;
|
||||
import org.hso.ecommerce.entities.user.User;
|
||||
import org.hso.ecommerce.repos.booking.BookingRepository;
|
||||
import org.hso.ecommerce.repos.shop.CustomerOrderRepository;
|
||||
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.*;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Optional;
|
||||
|
||||
@Controller
|
||||
//@RequestMapping("...")
|
||||
@RequestMapping("/intern/customers")
|
||||
public class CustomersIndexController {
|
||||
|
||||
@Autowired
|
||||
private BookingRepository bookingRepository = null;
|
||||
|
||||
@Autowired
|
||||
private final CustomerOrderRepository customerOrderRepository = null;
|
||||
|
||||
@Autowired
|
||||
private final UserRepository userRepository = null;
|
||||
|
||||
@Autowired
|
||||
private AccountingController accountingController = null;
|
||||
|
||||
@GetMapping("")
|
||||
public String internCustomers(Model model) {
|
||||
List<User> users = userRepository.findAll();
|
||||
|
||||
model.addAttribute("users", users);
|
||||
|
||||
return "intern/customers/index";
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public String internCustomersId(Model model,
|
||||
@PathVariable("id") Long id,
|
||||
HttpServletResponse response,
|
||||
HttpServletRequest request
|
||||
) {
|
||||
Optional<User> optUser = userRepository.findById(id);
|
||||
if (!optUser.isPresent()) {
|
||||
request.setAttribute("error", "Der User wurde nicht gefunden.");
|
||||
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
||||
return "error/404";
|
||||
}
|
||||
User user = optUser.get();
|
||||
model.addAttribute("user", user);
|
||||
|
||||
List<CustomerOrder> orders = customerOrderRepository.getOrdersByUserId(id);
|
||||
model.addAttribute("orders", orders);
|
||||
|
||||
List<Booking> bookings = bookingRepository.customerBookingsReverseChronologically(id);
|
||||
ShortTemplateBookingResult result = accountingController.buildShortTemplate(
|
||||
bookings,
|
||||
account -> account.userAccount != null && account.userAccount.id == id);
|
||||
model.addAttribute("balance", result.balance);
|
||||
model.addAttribute("bookings", result.bookings);
|
||||
|
||||
return "intern/customers/id";
|
||||
}
|
||||
|
||||
@PostMapping("/{id}/changeState")
|
||||
public String changeState(@PathVariable("id") Long id,
|
||||
@RequestParam(value = "active", required = false) String active,
|
||||
@RequestParam(value = "ma", required = false) String ma
|
||||
) {
|
||||
User user = userRepository.findById(id).get();
|
||||
|
||||
if (active == null)
|
||||
user.isActive = false;
|
||||
else
|
||||
user.isActive = true;
|
||||
|
||||
if (ma == null)
|
||||
user.isEmployee = false;
|
||||
else
|
||||
user.isEmployee = true;
|
||||
|
||||
userRepository.save(user);
|
||||
|
||||
return "redirect:/intern/customers/" + id.toString();
|
||||
}
|
||||
|
||||
@PostMapping("/{id}/resetPassword")
|
||||
public String resetPassword(@PathVariable("id") Long id,
|
||||
@RequestParam("password") String password,
|
||||
@RequestParam("password2") String password2,
|
||||
HttpServletRequest request
|
||||
) {
|
||||
if (!password.equals(password2)) {
|
||||
request.setAttribute("error", "Passwörter stimmen nicht überein!");
|
||||
return "/intern/customers/id";
|
||||
}
|
||||
User user = userRepository.findById(id).get();
|
||||
if (!user.validatePassword(password)) {
|
||||
request.setAttribute("error", "Die Passwörter stimmen nicht mit dem Original überein!");
|
||||
return "/intern/customers/id";
|
||||
}
|
||||
user.setPassword("12345");
|
||||
userRepository.save(user);
|
||||
request.setAttribute("info", "Passwort wurde auf 12345 geändert!");
|
||||
|
||||
return "/intern/customers/id";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,157 @@
|
|||
package org.hso.ecommerce.controller.intern.suppliers;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
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.supplier.Supplier;
|
||||
import org.hso.ecommerce.entities.supplier.SupplierOrder;
|
||||
import org.hso.ecommerce.repos.booking.BookingRepository;
|
||||
import org.hso.ecommerce.repos.supplier.SupplierOrderRepository;
|
||||
import org.hso.ecommerce.repos.supplier.SupplierRepository;
|
||||
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.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
@Controller
|
||||
//@RequestMapping("...")
|
||||
@RequestMapping("/intern/")
|
||||
public class SupplierIndexController {
|
||||
|
||||
@Autowired
|
||||
private final SupplierRepository supplierRepository = null;
|
||||
|
||||
@Autowired
|
||||
private final SupplierOrderRepository supplierOrderRepository = null;
|
||||
|
||||
@Autowired
|
||||
private final BookingRepository bookingRepository = null;
|
||||
|
||||
@Autowired
|
||||
private final AccountingController accountingController = null;
|
||||
|
||||
@GetMapping("suppliers")
|
||||
public String listSuppliers(Model model) {
|
||||
|
||||
List<UImodelSuppliers> totals = new ArrayList<UImodelSuppliers>();
|
||||
|
||||
for (Supplier supplier : supplierRepository.findAll()) {
|
||||
UImodelSuppliers tmp = new UImodelSuppliers(supplier.id, supplier.name);
|
||||
totals.add(tmp);
|
||||
}
|
||||
|
||||
model.addAttribute("suppliers", totals);
|
||||
return "intern/suppliers/index";
|
||||
}
|
||||
|
||||
@GetMapping("/suppliers/{id}")
|
||||
public String supplierDetail(Model model, @PathVariable String id) {
|
||||
|
||||
long supplierId = Long.parseLong(id);
|
||||
|
||||
// add orders from supplier to UImodel
|
||||
List<UImodelSupplierDetailOrders> orders = new ArrayList<UImodelSupplierDetailOrders>();
|
||||
for (SupplierOrder supplierOrder : supplierOrderRepository.findOrderBySupplierID(supplierId)) {
|
||||
orders.add(new UImodelSupplierDetailOrders(supplierOrder));
|
||||
}
|
||||
|
||||
// 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,
|
||||
bookingResult.balance, orders, bookingResult.bookings);
|
||||
|
||||
model.addAttribute("SupplierDetail", total);
|
||||
|
||||
return "intern/suppliers/id";
|
||||
}
|
||||
|
||||
public class UImodelSuppliers {
|
||||
public long id;
|
||||
public String name;
|
||||
|
||||
public UImodelSuppliers(long id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class UImodelSupplierDetail {
|
||||
|
||||
public String name;
|
||||
public String balance;
|
||||
public List<UImodelSupplierDetailOrders> orders;
|
||||
public List<ShortTemplateBooking> bookings;
|
||||
|
||||
public UImodelSupplierDetail(String name, String balance, List<UImodelSupplierDetailOrders> orders,
|
||||
List<ShortTemplateBooking> bookings
|
||||
) {
|
||||
this.name = name;
|
||||
this.balance = balance;
|
||||
this.orders = orders;
|
||||
this.bookings = bookings;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class UImodelSupplierDetailOrders {
|
||||
public long id;
|
||||
public String dateOrder;
|
||||
public String articleName;
|
||||
public long articleId;
|
||||
public String priceNet;
|
||||
public String quantity;
|
||||
public String priceTotal;
|
||||
public boolean arrived;
|
||||
|
||||
public UImodelSupplierDetailOrders(SupplierOrder order) {
|
||||
this.id = order.id;
|
||||
this.articleName = order.ordered.title;
|
||||
this.articleId = order.ordered.id;
|
||||
this.priceNet = String.format("%.2f", ((float) order.pricePerUnitNetCent / 100));
|
||||
this.quantity = String.valueOf(order.numberOfUnits);
|
||||
this.priceTotal = String.format("%.2f", ((float) order.totalPriceNet / 100));
|
||||
|
||||
Date date = new Date();
|
||||
date.setTime(order.created.getTime());
|
||||
this.dateOrder = new SimpleDateFormat("dd.MM.yyyy").format(date);
|
||||
|
||||
if (order.delivered != null) {
|
||||
arrived = true;
|
||||
} else {
|
||||
arrived = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class UImodelSupplierDetailBookings {
|
||||
|
||||
public String dateBooking;
|
||||
public String price;
|
||||
public String srcName;
|
||||
public String balance;
|
||||
public String reason;
|
||||
public long orderID;
|
||||
|
||||
public UImodelSupplierDetailBookings(Booking booking) {
|
||||
Date date = new Date();
|
||||
date.setTime(booking.reason.supplierOrder.created.getTime());
|
||||
this.dateBooking = new SimpleDateFormat("dd.MM.yyyy").format(date);
|
||||
this.price = String.format("%.2f", ((float) booking.amountCent / 100));
|
||||
this.srcName = ((booking.source.isMainAccount) ? "Hauptkonto" : booking.source.supplierAccount.name);
|
||||
this.balance = String.format("%.2f", ((float) booking.destination.newSumCent / 100));
|
||||
this.reason = booking.reason.comment;
|
||||
this.orderID = booking.reason.supplierOrder.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,11 +26,11 @@ public class SupplierOfferController {
|
|||
@GetMapping("supplierOffers")
|
||||
public String internListedArticles(Model model) {
|
||||
|
||||
List<UImodelOfferedArticle> totals = new ArrayList<UImodelOfferedArticle>();
|
||||
List<UImodelOfferedArticle> totals = new ArrayList<>();
|
||||
|
||||
for (ArticleOffer article : offersRepository.findAll()) {
|
||||
UImodelOfferedArticle tmp = new UImodelOfferedArticle();
|
||||
tmp.addData(article, "supplierName01", 4884, articleRepository.findArticleIDByRelatedID(article.id)); //TODO display supplier name with link
|
||||
UImodelOfferedArticle tmp = new UImodelOfferedArticle(article,
|
||||
articleRepository.findArticleIDByRelatedID(article.id));
|
||||
totals.add(tmp);
|
||||
}
|
||||
|
||||
|
@ -40,106 +40,27 @@ public class SupplierOfferController {
|
|||
|
||||
public class UImodelOfferedArticle {
|
||||
|
||||
long offer_id;
|
||||
String title;
|
||||
String manufacturer;
|
||||
String articlenumber;
|
||||
String supplierName;
|
||||
int supplierId;
|
||||
String price;
|
||||
String ads;
|
||||
int listedArticleId;
|
||||
boolean offerIsListed; //true --> offered article is listed
|
||||
public long offerId;
|
||||
public String title;
|
||||
public String manufacturer;
|
||||
public String articleNumber;
|
||||
public String supplierName;
|
||||
public String price;
|
||||
public String ads;
|
||||
public int listedArticleId;
|
||||
public boolean offerIsListed; // true --> offered article is listed
|
||||
|
||||
public long getOffer_id() {
|
||||
return offer_id;
|
||||
}
|
||||
public UImodelOfferedArticle(ArticleOffer article, Optional<Integer> listedArticleId) {
|
||||
|
||||
public void setOffer_id(long offer_id) {
|
||||
this.offer_id = offer_id;
|
||||
}
|
||||
|
||||
public boolean isOfferIsListed() {
|
||||
return offerIsListed;
|
||||
}
|
||||
|
||||
public void setOfferIsListed(boolean offerIsListed) {
|
||||
this.offerIsListed = offerIsListed;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getManufacturer() {
|
||||
return manufacturer;
|
||||
}
|
||||
|
||||
public void setManufacturer(String manufacturer) {
|
||||
this.manufacturer = manufacturer;
|
||||
}
|
||||
|
||||
public String getArticlenumber() {
|
||||
return articlenumber;
|
||||
}
|
||||
|
||||
public void setArticlenumber(String articlenumber) {
|
||||
this.articlenumber = articlenumber;
|
||||
}
|
||||
|
||||
public String getSupplierName() {
|
||||
return supplierName;
|
||||
}
|
||||
|
||||
public void setSupplierName(String supplierName) {
|
||||
this.supplierName = supplierName;
|
||||
}
|
||||
|
||||
public int getSupplierId() {
|
||||
return supplierId;
|
||||
}
|
||||
|
||||
public void setSupplierId(int supplierId) {
|
||||
this.supplierId = supplierId;
|
||||
}
|
||||
|
||||
public String getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public void setPrice(String price) {
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
public String getAds() {
|
||||
return ads;
|
||||
}
|
||||
|
||||
public void setAds(String ads) {
|
||||
this.ads = ads;
|
||||
}
|
||||
|
||||
public int getListedArticleId() {
|
||||
return listedArticleId;
|
||||
}
|
||||
|
||||
public void setListedArticleId(int listedArticleId) {
|
||||
this.listedArticleId = listedArticleId;
|
||||
}
|
||||
|
||||
public void addData(ArticleOffer article, String supplierName, int supplierId,
|
||||
Optional<Integer> listedArticleId) {
|
||||
|
||||
this.offer_id = article.id;
|
||||
this.offerId = article.id;
|
||||
this.title = article.title;
|
||||
this.manufacturer = article.manufacturer;
|
||||
this.articlenumber = article.articleNumber;
|
||||
this.supplierName = supplierName;
|
||||
this.supplierId = supplierId;
|
||||
this.articleNumber = article.articleNumber;
|
||||
if (article.cheapestSupplier != null) {
|
||||
this.supplierName = article.cheapestSupplier.name;
|
||||
} else {
|
||||
this.supplierName = "-";
|
||||
}
|
||||
this.price = String.format("%.2f", ((float) article.pricePerUnitNet / 100));
|
||||
this.ads = (article.shouldBeAdvertised) ? "Ja" : "Nein";
|
||||
|
||||
|
|
|
@ -1,8 +1,135 @@
|
|||
package org.hso.ecommerce.controller.intern.suppliers;
|
||||
|
||||
import org.hso.ecommerce.action.warehouse.SupplierOrderArrivedAction;
|
||||
import org.hso.ecommerce.entities.shop.Article;
|
||||
import org.hso.ecommerce.entities.supplier.SupplierOrder;
|
||||
import org.hso.ecommerce.entities.warehouse.WarehouseBookingPositionSlotEntry;
|
||||
import org.hso.ecommerce.repos.shop.ArticleRepository;
|
||||
import org.hso.ecommerce.repos.supplier.SupplierOrderRepository;
|
||||
import org.hso.ecommerce.repos.warehouse.SlotRepository;
|
||||
import org.hso.ecommerce.repos.warehouse.WarehouseBookingPositionSlotEntryRepository;
|
||||
import org.hso.ecommerce.repos.warehouse.WarehouseBookingRepository;
|
||||
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.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Controller
|
||||
//@RequestMapping("...")
|
||||
@RequestMapping("/intern/")
|
||||
public class SupplierOrderController {
|
||||
|
||||
@Autowired
|
||||
private final SupplierOrderRepository supplierOrderRepository = null;
|
||||
|
||||
@Autowired
|
||||
private final ArticleRepository articleRepository = null;
|
||||
|
||||
@Autowired
|
||||
private final WarehouseBookingPositionSlotEntryRepository warehouseBookingPositionSlotEntryRepository = null;
|
||||
|
||||
@Autowired
|
||||
private final WarehouseBookingRepository warehouseBookingRepository = null;
|
||||
|
||||
@Autowired
|
||||
private final SlotRepository slotRepository = null;
|
||||
|
||||
@GetMapping("supplierOrders")
|
||||
public String listSuppliers(Model model) {
|
||||
|
||||
List<UImodelSupplierOrder> totals = new ArrayList<UImodelSupplierOrder>();
|
||||
|
||||
for (SupplierOrder order : supplierOrderRepository.findAll()) {
|
||||
final Article article = articleRepository.findArticleByArticleOffer(order.ordered).orElse(null);
|
||||
totals.add(new UImodelSupplierOrder(order, article));
|
||||
}
|
||||
|
||||
model.addAttribute("orders", totals);
|
||||
|
||||
return "intern/supplierOrders/index";
|
||||
}
|
||||
|
||||
@PostMapping("/supplierOrders/store/{id}")
|
||||
public String storeOrder(@PathVariable("id") Long supplierOrderID, Model model, HttpServletResponse response) {
|
||||
SupplierOrder order = supplierOrderRepository.findById(supplierOrderID).orElse(null);
|
||||
if (order == null) {
|
||||
model.addAttribute("error", "Die ausgewählte Lieferung konnte nicht gefunden werden.");
|
||||
response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
|
||||
return listSuppliers(model);
|
||||
}
|
||||
if (order.wasDelivered()) {
|
||||
model.addAttribute("error", "Die ausgewählte Lieferung wurde schon zugestellt.");
|
||||
response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
|
||||
return listSuppliers(model);
|
||||
}
|
||||
|
||||
|
||||
final Article article = articleRepository.findArticleByArticleOffer(order.ordered).orElse(null);
|
||||
if (article == null) {
|
||||
model.addAttribute("error", "Der bestellte Artikel wurde nicht angelegt, er hätte nicht bestellt werden dürfen.");
|
||||
response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
|
||||
return listSuppliers(model);
|
||||
}
|
||||
|
||||
// Hard to do efficiently, this should be fine.
|
||||
List<WarehouseBookingPositionSlotEntry> candidates = slotRepository
|
||||
.findAll()
|
||||
.stream()
|
||||
.map(slot ->
|
||||
warehouseBookingPositionSlotEntryRepository.getBySlotNum(slot.slotNum).orElseGet(() ->
|
||||
WarehouseBookingPositionSlotEntry.empty(article, slot)
|
||||
)
|
||||
)
|
||||
.filter(entry -> entry.article.id == article.id || entry.newSumSlot == 0)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
SupplierOrderArrivedAction action = new SupplierOrderArrivedAction(candidates, order, article);
|
||||
|
||||
try {
|
||||
SupplierOrderArrivedAction.Result result = action.finish();
|
||||
supplierOrderRepository.save(result.getOrder());
|
||||
warehouseBookingRepository.save(result.getBooking());
|
||||
} catch (SupplierOrderArrivedAction.NoSpaceInWarehouseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return "redirect:/intern/warehouse/todo";
|
||||
}
|
||||
|
||||
public class UImodelSupplierOrder {
|
||||
public long id;
|
||||
public String dateOrder;
|
||||
public String supplierName;
|
||||
public String articleName;
|
||||
public long articleId;
|
||||
public String priceNet;
|
||||
public String quantity;
|
||||
public String priceTotal;
|
||||
public boolean arrived;
|
||||
|
||||
public UImodelSupplierOrder(SupplierOrder order, Article article) {
|
||||
this.id = order.id;
|
||||
this.supplierName = order.supplier.name;
|
||||
this.articleName = article != null ? article.title : "error";
|
||||
this.articleId = article != null ? article.id : 0;
|
||||
this.priceNet = String.format("%.2f", ((float) order.pricePerUnitNetCent / 100));
|
||||
this.quantity = String.valueOf(order.numberOfUnits);
|
||||
this.priceTotal = String.format("%.2f", ((float) order.totalPriceNet / 100));
|
||||
|
||||
Date date = new Date();
|
||||
date.setTime(order.created.getTime());
|
||||
this.dateOrder = new SimpleDateFormat("dd.MM.yyyy").format(date);
|
||||
|
||||
arrived = order.delivered != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
package org.hso.ecommerce.controller.intern.warehouse;
|
||||
|
||||
import org.hso.ecommerce.action.warehouse.CreateManuelBookingAction;
|
||||
import org.hso.ecommerce.entities.shop.Article;
|
||||
import org.hso.ecommerce.entities.warehouse.Slot;
|
||||
import org.hso.ecommerce.entities.warehouse.WarehouseBookingPositionSlotEntry;
|
||||
import org.hso.ecommerce.repos.shop.ArticleRepository;
|
||||
import org.hso.ecommerce.repos.warehouse.SlotRepository;
|
||||
import org.hso.ecommerce.repos.warehouse.WarehouseBookingPositionSlotEntryRepository;
|
||||
import org.hso.ecommerce.repos.warehouse.WarehouseBookingRepository;
|
||||
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.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Optional;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/intern/warehouse/")
|
||||
public class ManuelBookingController {
|
||||
|
||||
@Autowired
|
||||
private final ArticleRepository articleRepository = null;
|
||||
|
||||
@Autowired
|
||||
private final SlotRepository slotRepository = null;
|
||||
|
||||
@Autowired
|
||||
private final WarehouseBookingPositionSlotEntryRepository warehouseBookingPositionSlotEntryRepository = null;
|
||||
|
||||
@Autowired
|
||||
private final WarehouseBookingRepository warehouseBookingRepository = null;
|
||||
|
||||
@GetMapping("addManual")
|
||||
public String warehouseAddManual(
|
||||
Model model
|
||||
) {
|
||||
|
||||
model.addAttribute("articles", articleRepository.findAll());
|
||||
model.addAttribute("slots", slotRepository.findAll());
|
||||
|
||||
return "intern/warehouse/addManual";
|
||||
}
|
||||
|
||||
@PostMapping("addManual")
|
||||
public String warehouseAddMaualPost(
|
||||
Model model,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
@RequestParam("articleId") String articleIdText,
|
||||
@RequestParam("amount") Integer amount,
|
||||
@RequestParam("reason") String reason,
|
||||
@RequestParam("sourceIsSlot") Boolean sourceIsSlot,
|
||||
@RequestParam("sourceSlot") Integer sourceSlotNum,
|
||||
@RequestParam("destinationIsSlot") Boolean destinationIsSlot,
|
||||
@RequestParam("destinationSlot") Integer destinationSlotNum
|
||||
) {
|
||||
|
||||
// The suggestions for articleId in the UI show articles names, seperated by a " - ".
|
||||
// The Number must be extracted first.
|
||||
long articleId = -1;
|
||||
try {
|
||||
articleId = Long.parseLong(articleIdText.split(" - ", 2)[0].trim());
|
||||
} catch (NumberFormatException e) {
|
||||
model.addAttribute("error", "Die Artikel Id konnte nicht erkannt werden.");
|
||||
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
||||
return "intern/warehouse/addManual";
|
||||
}
|
||||
|
||||
|
||||
Optional<Article> optionalArticle = articleRepository.findById(articleId);
|
||||
Article article = null;
|
||||
if (!optionalArticle.isPresent()) {
|
||||
model.addAttribute("error", "Der Artikel konnte nicht gefunden werden.");
|
||||
response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
|
||||
return "intern/warehouse/addManual";
|
||||
} else {
|
||||
article = optionalArticle.get();
|
||||
}
|
||||
|
||||
if (amount <= 0) {
|
||||
model.addAttribute("error", "Eine Anzahl <= 0 kann nicht verbucht werden.");
|
||||
response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
|
||||
return "intern/warehouse/addManual";
|
||||
}
|
||||
|
||||
if (sourceIsSlot == false && destinationIsSlot == false) {
|
||||
model.addAttribute("error", "Jede Buchung benötigt ein Ziel oder eine Quelle.");
|
||||
response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
|
||||
return "intern/warehouse/addManual";
|
||||
}
|
||||
|
||||
Optional<WarehouseBookingPositionSlotEntry> sourceSlot = Optional.empty();
|
||||
if (sourceIsSlot == true) {
|
||||
sourceSlot = warehouseBookingPositionSlotEntryRepository.getBySlotNum(sourceSlotNum);
|
||||
if (!sourceSlot.isPresent()) {
|
||||
request.setAttribute("error", "Quelllagerplatz wurde nicht gefunden oder ist leer.");
|
||||
response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
|
||||
return "intern/warehouse/addManual";
|
||||
}
|
||||
}
|
||||
|
||||
Optional<WarehouseBookingPositionSlotEntry> destinationSlot = Optional.empty();
|
||||
if (destinationIsSlot == true) {
|
||||
Optional<Slot> slot = slotRepository.findBySlotNum(destinationSlotNum);
|
||||
if (!slot.isPresent()) {
|
||||
request.setAttribute("error", "Ziellagerplatz wurde nicht gefunden.");
|
||||
response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
|
||||
return "intern/warehouse/addManual";
|
||||
}
|
||||
|
||||
Article finalArticle = article;
|
||||
destinationSlot = Optional.of(warehouseBookingPositionSlotEntryRepository.getBySlotNum(destinationSlotNum).orElseGet(
|
||||
() -> WarehouseBookingPositionSlotEntry.empty(finalArticle, slot.get())
|
||||
));
|
||||
}
|
||||
|
||||
try {
|
||||
warehouseBookingRepository.save(
|
||||
new CreateManuelBookingAction(article, amount, sourceSlot, destinationSlot, reason).finish()
|
||||
);
|
||||
} catch (CreateManuelBookingAction.ArticleSlotConstraintArticleTypeFailedException e) {
|
||||
model.addAttribute("error", "Es befindet sich der falsche Artikeltyp in Quell- oder Ziellagerplatz. ");
|
||||
response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
|
||||
return "intern/warehouse/addManual";
|
||||
} catch (CreateManuelBookingAction.ArticleSlotConstraintFailedException e) {
|
||||
model.addAttribute("error", "Die maximale Anzahl an lagerbaren Artikeln im Ziellagerplatz wurde überschritten.");
|
||||
response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
|
||||
return "intern/warehouse/addManual";
|
||||
}
|
||||
|
||||
return "redirect:/intern/warehouse/todo";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package org.hso.ecommerce.controller.intern.warehouse;
|
||||
|
||||
import org.hso.ecommerce.action.warehouse.CalculateWarehouseStatsAction;
|
||||
import org.hso.ecommerce.entities.warehouse.WarehouseBookingPositionSlotEntry;
|
||||
import org.hso.ecommerce.repos.warehouse.SlotRepository;
|
||||
import org.hso.ecommerce.repos.warehouse.WarehouseBookingPositionSlotEntryRepository;
|
||||
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;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/intern/warehouse/")
|
||||
public class SlotsController {
|
||||
|
||||
@Autowired
|
||||
private final WarehouseBookingPositionSlotEntryRepository warehouseBookingPositionSlotEntryRepository = null;
|
||||
|
||||
@Autowired
|
||||
private final SlotRepository slotRepository = null;
|
||||
|
||||
@GetMapping("slots/")
|
||||
public String accountingWarehouseSlots(
|
||||
Model model,
|
||||
HttpServletRequest request
|
||||
) {
|
||||
|
||||
// Doing this in a single would be hard and error prone.
|
||||
// Writing native queries should be minimized.
|
||||
// Therefore this method was prefered
|
||||
List<WarehouseBookingPositionSlotEntry> entries = slotRepository.findAll().stream().map(
|
||||
s -> warehouseBookingPositionSlotEntryRepository
|
||||
.getBySlotNum(s.slotNum)
|
||||
.orElseGet(() -> WarehouseBookingPositionSlotEntry.empty(null, s))
|
||||
).collect(Collectors.toList());
|
||||
model.addAttribute("entries", entries);
|
||||
|
||||
model.addAttribute("stats", new CalculateWarehouseStatsAction(entries).finish());
|
||||
return "intern/warehouse/slots/index";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
package org.hso.ecommerce.controller.intern.warehouse;
|
||||
|
||||
import org.hso.ecommerce.action.shop.EnableTrackingAction;
|
||||
import org.hso.ecommerce.entities.warehouse.WarehouseBooking;
|
||||
import org.hso.ecommerce.repos.warehouse.WarehouseBookingRepository;
|
||||
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.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Optional;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/intern/warehouse/")
|
||||
public class TodoController {
|
||||
|
||||
@Autowired
|
||||
private final WarehouseBookingRepository warehouseBookingRepository = null;
|
||||
|
||||
@GetMapping("todo")
|
||||
public String accountingWarehouseTodo(
|
||||
Model model
|
||||
) {
|
||||
model.addAttribute("bookings", warehouseBookingRepository.findNotDone());
|
||||
return "intern/warehouse/todo";
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("progress/{id}")
|
||||
public String postProgressId(
|
||||
Model model,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
@PathVariable("id") Long id
|
||||
) {
|
||||
Optional<WarehouseBooking> booking = warehouseBookingRepository.findById(id);
|
||||
if (!booking.isPresent()) {
|
||||
model.addAttribute("error", "Die Buchung wurde nicht gefunden.");
|
||||
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
||||
return "error/404";
|
||||
}
|
||||
|
||||
if (booking.get().isInProgress) {
|
||||
response.setStatus(409);
|
||||
return "intern/warehouse/error_progress_failed";
|
||||
}
|
||||
|
||||
booking.get().isInProgress = true;
|
||||
warehouseBookingRepository.save(booking.get());
|
||||
|
||||
return "redirect:/intern/warehouse/progress/" + id;
|
||||
}
|
||||
|
||||
@PostMapping("progress/{id}/finish")
|
||||
public String postProgressIdFinish(
|
||||
Model model,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
@PathVariable("id") Long id
|
||||
) {
|
||||
Optional<WarehouseBooking> booking = warehouseBookingRepository.findById(id);
|
||||
if (!booking.isPresent()) {
|
||||
model.addAttribute("error", "Die Buchung wurde nicht gefunden.");
|
||||
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
||||
return "error/404";
|
||||
}
|
||||
|
||||
booking.get().isInProgress = true;
|
||||
booking.get().isDone = true;
|
||||
|
||||
// Update Delivery Date
|
||||
if (booking.get().reason.customerOrder != null) {
|
||||
EnableTrackingAction.addTrackingInfo(booking.get().reason.customerOrder);
|
||||
}
|
||||
|
||||
warehouseBookingRepository.save(booking.get());
|
||||
|
||||
return "redirect:/intern/warehouse/todo";
|
||||
}
|
||||
|
||||
@GetMapping("progress/{id}")
|
||||
public String getProgressId(Model model,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
@PathVariable("id") Long id) {
|
||||
Optional<WarehouseBooking> booking = warehouseBookingRepository.findById(id);
|
||||
if (!booking.isPresent()) {
|
||||
model.addAttribute("error", "Die Buchung wurde nicht gefunden.");
|
||||
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
||||
return "error/404";
|
||||
}
|
||||
|
||||
if (booking.get().isDone) {
|
||||
model.addAttribute("info", "Die Buchung wurde schon abgeschlossen.");
|
||||
}
|
||||
|
||||
if (!booking.get().isInProgress) {
|
||||
// Only reachable if path is manipulated.
|
||||
model.addAttribute("error", "Die Buchung wurde noch nicht zugewiesen!");
|
||||
}
|
||||
|
||||
model.addAttribute("booking", booking.get());
|
||||
return "intern/warehouse/id_progress";
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -100,8 +100,11 @@ public class ShopArticleController {
|
|||
@PathVariable("id") Long id
|
||||
) throws IOException {
|
||||
Article article = articleRepository.findArticleById(id);
|
||||
InputStream in = new FileInputStream(article.image.path);
|
||||
response.setContentType(MediaType.IMAGE_JPEG_VALUE);
|
||||
IOUtils.copy(in, response.getOutputStream());
|
||||
|
||||
if(article.image != null) {
|
||||
InputStream in = new FileInputStream(article.image.path);
|
||||
response.setContentType(MediaType.IMAGE_JPEG_VALUE);
|
||||
IOUtils.copy(in, response.getOutputStream());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
package org.hso.ecommerce.controller.shop;
|
||||
|
||||
import org.hso.ecommerce.action.shop.CreateOrderAction;
|
||||
import org.hso.ecommerce.action.shop.EnableTrackingAction;
|
||||
import org.hso.ecommerce.entities.booking.BookingAccountEntry;
|
||||
import org.hso.ecommerce.entities.booking.PaymentMethod;
|
||||
import org.hso.ecommerce.entities.shop.Address;
|
||||
|
@ -11,7 +10,7 @@ import org.hso.ecommerce.entities.user.User;
|
|||
import org.hso.ecommerce.repos.booking.BookingAccountEntryRepository;
|
||||
import org.hso.ecommerce.repos.booking.BookingRepository;
|
||||
import org.hso.ecommerce.repos.shop.ArticleRepository;
|
||||
import org.hso.ecommerce.repos.shop.CustomerOderRepository;
|
||||
import org.hso.ecommerce.repos.shop.CustomerOrderRepository;
|
||||
import org.hso.ecommerce.repos.user.UserRepository;
|
||||
import org.hso.ecommerce.repos.warehouse.WarehouseBookingPositionSlotEntryRepository;
|
||||
import org.hso.ecommerce.repos.warehouse.WarehouseBookingRepository;
|
||||
|
@ -45,7 +44,7 @@ public class ShopCheckoutController {
|
|||
private final WarehouseBookingRepository warehouseBookingRepository = null;
|
||||
|
||||
@Autowired
|
||||
private final CustomerOderRepository customerOderRepository = null;
|
||||
private final CustomerOrderRepository customerOderRepository = null;
|
||||
|
||||
@Autowired
|
||||
private final WarehouseBookingPositionSlotEntryRepository wbeseRepo = null;
|
||||
|
@ -122,7 +121,7 @@ public class ShopCheckoutController {
|
|||
user,
|
||||
expectedPrice,
|
||||
Address.fromString(address),
|
||||
PaymentMethod.fromCreditCarNumber(cardnumber),
|
||||
PaymentMethod.fromCreditCardNumber(cardnumber),
|
||||
bookingEntryRepository.getByUser(user.id).orElse(BookingAccountEntry.newUser(user)),
|
||||
bookingEntryRepository.getByVat().orElse(BookingAccountEntry.newVat()),
|
||||
bookingEntryRepository.getByMain().orElse(BookingAccountEntry.newMain())
|
||||
|
@ -136,7 +135,6 @@ public class ShopCheckoutController {
|
|||
CreateOrderAction.Result result = null;
|
||||
try {
|
||||
result = action.finish();
|
||||
//EnableTrackingAction.addTrackingInfo(result.customerOrder);
|
||||
|
||||
customerOderRepository.save(result.customerOrder);
|
||||
bookingRepository.saveAll(result.bookings);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.hso.ecommerce.controller.shop;
|
||||
|
||||
import org.hso.ecommerce.action.shop.SearchByTermAction;
|
||||
import org.hso.ecommerce.entities.shop.Article;
|
||||
import org.hso.ecommerce.repos.shop.ArticleRepository;
|
||||
import org.hso.ecommerce.repos.shop.CategoryRepository;
|
||||
|
@ -32,7 +33,8 @@ public class ShopSearchController {
|
|||
model.addAttribute("categories", categoryRepository.getCategories()); //for sidebar
|
||||
|
||||
if (term != null) { //if search by Term
|
||||
List<Article> articles = articleRepository.getArticlesByTerm(term); //search by Term
|
||||
term = term.trim();
|
||||
List<Article> articles = SearchByTermAction.searchByTerm(term, articleRepository);
|
||||
model.addAttribute("articles", articles);
|
||||
} else if (category != null) { //if search by Category
|
||||
List<Article> articles = articleRepository.getArticlesByCategory(category); //search by Category
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -43,4 +43,9 @@ public class BookingReason {
|
|||
public BookingReason(SupplierOrder supplierOrder) {
|
||||
this.supplierOrder = supplierOrder;
|
||||
}
|
||||
|
||||
public BookingReason(String comment) {
|
||||
this.isManuel = true;
|
||||
this.comment = comment;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ public class PaymentMethod {
|
|||
|
||||
public String creditCardNumber;
|
||||
|
||||
public static PaymentMethod fromCreditCarNumber(String cardnumber) {
|
||||
public static PaymentMethod fromCreditCardNumber(String cardnumber) {
|
||||
PaymentMethod m = new PaymentMethod();
|
||||
m.creditCardNumber = cardnumber;
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ public class Article {
|
|||
@Basic
|
||||
public long id;
|
||||
|
||||
@ManyToOne(optional = false)
|
||||
@OneToOne(optional = false)
|
||||
public ArticleOffer related;
|
||||
|
||||
public int shopPricePerUnitNetCent;
|
||||
|
|
|
@ -4,6 +4,7 @@ import org.hso.ecommerce.entities.user.User;
|
|||
|
||||
import javax.persistence.*;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -43,4 +44,21 @@ public class CustomerOrder {
|
|||
public int totalNetCent;
|
||||
public int totalGrossCent;
|
||||
public int totalVatCent;
|
||||
|
||||
public String formatInDeliverySince(){
|
||||
return new SimpleDateFormat("dd.MM.yyyy HH:mm").format(inDeliverySince);
|
||||
}
|
||||
|
||||
public String formatCreated(){
|
||||
return new SimpleDateFormat("dd.MM.yyyy HH:mm").format(created);
|
||||
}
|
||||
|
||||
public String formatDeliveredAt(){
|
||||
return new SimpleDateFormat("dd.MM.yyyy HH:mm").format(deliveredAt);
|
||||
}
|
||||
|
||||
public String getEstimatedArrival() {
|
||||
//TODO: get estimated arrival from api
|
||||
return "TODO TODO TODO";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,5 +28,6 @@ public class ArticleOffer {
|
|||
|
||||
public boolean shouldBeAdvertised;
|
||||
|
||||
|
||||
@ManyToOne(optional = true)
|
||||
public Supplier cheapestSupplier;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,11 @@ public class User {
|
|||
@Column(unique = true)
|
||||
public String email;
|
||||
|
||||
@Column(insertable = false, updatable = false)
|
||||
public String name;
|
||||
|
||||
public String salutation;
|
||||
|
||||
public String passwordHash;
|
||||
|
||||
public boolean isActive;
|
||||
|
|
|
@ -25,7 +25,12 @@ public class WarehouseBookingPositionSlotEntry {
|
|||
@ManyToOne
|
||||
public Slot slot;
|
||||
|
||||
public WarehouseBookingPositionSlotEntry copyAddAmount(int amount) {
|
||||
public WarehouseBookingPositionSlotEntry copyAddAmount(int amount, Article article) {
|
||||
// Article can be changed if newSumSlot == 0.
|
||||
if (this.newSumSlot != 0 && this.article.id != article.id) {
|
||||
throw new IllegalArgumentException("Article does not match.");
|
||||
}
|
||||
|
||||
WarehouseBookingPositionSlotEntry e = new WarehouseBookingPositionSlotEntry();
|
||||
|
||||
e.article = article;
|
||||
|
@ -38,4 +43,14 @@ public class WarehouseBookingPositionSlotEntry {
|
|||
|
||||
return e;
|
||||
}
|
||||
|
||||
public static WarehouseBookingPositionSlotEntry empty(Article article, Slot slot) {
|
||||
WarehouseBookingPositionSlotEntry e = new WarehouseBookingPositionSlotEntry();
|
||||
|
||||
e.article = article;
|
||||
e.slot = slot;
|
||||
e.newSumSlot = 0;
|
||||
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,28 @@
|
|||
package org.hso.ecommerce.repos.booking;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hso.ecommerce.entities.booking.Booking;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface BookingRepository extends JpaRepository<Booking, Long> {
|
||||
|
||||
@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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.hso.ecommerce.repos.shop;
|
||||
|
||||
import org.hso.ecommerce.entities.shop.Article;
|
||||
import org.hso.ecommerce.entities.supplier.ArticleOffer;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
@ -12,26 +13,40 @@ import java.util.Optional;
|
|||
@Repository
|
||||
public interface ArticleRepository extends JpaRepository<Article, Long> {
|
||||
|
||||
@Query("SELECT a FROM Article a WHERE a.id = :articleId")
|
||||
Article findArticleById(@Param("articleId") long articleId);
|
||||
/***
|
||||
* use findById instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@Query("SELECT a FROM Article a WHERE a.id = :articleId")
|
||||
Article findArticleById(@Param("articleId") long articleId);
|
||||
|
||||
@Query("SELECT a FROM Article a")
|
||||
List<Article> findAll();
|
||||
@Query("SELECT a FROM Article a")
|
||||
List<Article> findAll();
|
||||
|
||||
@Query(value = "Select a.* from articles as a, article_offers as ao, warehouse_booking_position_entries as wbpe where a.related_id = ao.id and wbpe.article_id = a.id and ao.should_be_advertised = true group by wbpe.slot_id having max(wbpe.id) and wbpe.new_sum_slot != 0", nativeQuery = true)
|
||||
List<Article> getAdvertisedArticles();
|
||||
|
||||
@Query("SELECT a FROM CustomerOrderPosition cop JOIN cop.order co JOIN co.customer c JOIN cop.article a ORDER BY co.id DESC")
|
||||
List<Article> getOrderedArticles();
|
||||
@Query("SELECT a FROM CustomerOrderPosition cop JOIN cop.order co JOIN co.customer c JOIN cop.article a ORDER BY co.id DESC")
|
||||
List<Article> getOrderedArticles();
|
||||
|
||||
@Query("SELECT a FROM CustomerOrderPosition cop JOIN cop.order co JOIN co.customer c JOIN cop.article a WHERE c.id = :customerId ORDER BY co.id DESC")
|
||||
List<Article> getOrderedArticles(long customerId);
|
||||
|
||||
/***
|
||||
* use type safe findArticleByArticleOffer instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@Query(value = "SELECT a.id FROM articles a WHERE a.related_id = :relatedId", nativeQuery = true)
|
||||
Optional<Integer> findArticleIDByRelatedID(@Param("relatedId") long relatedId);
|
||||
|
||||
|
||||
@Query(value = "SELECT a FROM Article a Where a.related = :related")
|
||||
Optional<Article> findArticleByArticleOffer(ArticleOffer related);
|
||||
|
||||
@Query(value = "Select a.* from articles as a, warehouse_booking_position_entries as wbpe where wbpe.article_id = a.id and a.title LIKE %:term% group by wbpe.slot_id having max(wbpe.id) and wbpe.new_sum_slot != 0", nativeQuery = true)
|
||||
List<Article> getArticlesByTerm(String term);
|
||||
List<Article> getArticlesByTermInTitle(String term);
|
||||
|
||||
@Query(value = "Select a.* from articles as a, warehouse_booking_position_entries as wbpe where wbpe.article_id = a.id and a.description LIKE %:term% group by wbpe.slot_id having max(wbpe.id) and wbpe.new_sum_slot != 0", nativeQuery = true)
|
||||
List<Article> getArticlesByTermInDescription(String term);
|
||||
|
||||
@Query(value = "Select a.* from articles as a, categories as c, article_categories_bindings as acb, warehouse_booking_position_entries as wbpe where wbpe.article_id = a.id and acb.articles_id = a.id and acb.categories_id = c.id and c.name = :category group by wbpe.slot_id having max(wbpe.id) and wbpe.new_sum_slot != 0", nativeQuery = true)
|
||||
List<Article> getArticlesByCategory(String category);
|
||||
|
|
|
@ -9,8 +9,10 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface CustomerOderRepository extends JpaRepository<CustomerOrder, Long> {
|
||||
public interface CustomerOrderRepository extends JpaRepository<CustomerOrder, Long> {
|
||||
|
||||
@Query("SELECT SUM(cop.quantity) FROM CustomerOrderPosition cop JOIN cop.order co WHERE cop.article.id = :articleId AND co.created >= :begin AND co.created < :end")
|
||||
Integer countOrdersOfArticleInTimespan(
|
||||
|
@ -24,5 +26,9 @@ public interface CustomerOderRepository extends JpaRepository<CustomerOrder, Lon
|
|||
@Modifying(clearAutomatically = true)
|
||||
@Query("UPDATE CustomerOrder co SET co.deliveredAt = :newDeliveredAt WHERE co.id = :customerOrderID")
|
||||
int updateUserDeliveredAt(long customerOrderID, java.sql.Timestamp newDeliveredAt);
|
||||
}
|
||||
|
||||
|
||||
@Query("SELECT co FROM CustomerOrder co WHERE co.customer.id = :userId ORDER BY co.id DESC")
|
||||
List<CustomerOrder> getOrdersByUserId(long userId);
|
||||
|
||||
}
|
|
@ -1,8 +1,11 @@
|
|||
package org.hso.ecommerce.repos.supplier;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hso.ecommerce.entities.supplier.SupplierOrder;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
|
@ -11,4 +14,9 @@ public interface SupplierOrderRepository extends JpaRepository<SupplierOrder, Lo
|
|||
@Query("SELECT SUM(so.numberOfUnits) FROM SupplierOrder so JOIN so.ordered ao WHERE ao.articleNumber = :articleNumber AND so.delivered IS NULL")
|
||||
Integer countUndeliveredReorders(String articleNumber);
|
||||
|
||||
@Query(value = "SELECT * FROM supplier_orders as a WHERE a.supplier_id = :supplierId", nativeQuery = true)
|
||||
List<SupplierOrder> findOrderBySupplierID(@Param("supplierId") long supplierId);
|
||||
|
||||
@Query("SELECT a FROM SupplierOrder a")
|
||||
List<SupplierOrder> findAll();
|
||||
}
|
||||
|
|
|
@ -1,10 +1,19 @@
|
|||
package org.hso.ecommerce.repos.supplier;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hso.ecommerce.entities.supplier.Supplier;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface SupplierRepository extends JpaRepository<Supplier, Long> {
|
||||
|
||||
}
|
||||
|
||||
@Query("SELECT a FROM Supplier a")
|
||||
List<Supplier> findAll();
|
||||
|
||||
@Query("SELECT a FROM Supplier a WHERE a.id = :supplierId")
|
||||
Supplier findSupplierById(@Param("supplierId") long supplierId);
|
||||
}
|
|
@ -13,10 +13,12 @@ public interface WarehouseBookingPositionSlotEntryRepository extends JpaReposito
|
|||
|
||||
@Query(value = "Select e.id, e.article_id, e.new_sum_slot, e.slot_id from warehouse_booking_position_entries as e, warehouse_slots as s where e.slot_id = s.id AND e.article_id = :article GROUP BY s.slot_num HAVING max(e.id)", nativeQuery = true)
|
||||
List<WarehouseBookingPositionSlotEntry> getByArticle(long article);
|
||||
|
||||
|
||||
|
||||
@Query(value = "SELECT SUM(w.new_sum_slot) FROM warehouse_booking_position_entries as w WHERE w.article_id = :articleid", nativeQuery = true)
|
||||
Optional<Integer> getArticleStock(long articleid);
|
||||
|
||||
|
||||
@Query(value = "Select e.id, e.article_id, e.new_sum_slot, e.slot_id from warehouse_booking_position_entries as e, warehouse_slots as s where e.slot_id = s.id AND s.slot_num = :slotnum GROUP BY s.slot_num HAVING max(e.id)", nativeQuery = true)
|
||||
Optional<WarehouseBookingPositionSlotEntry> getBySlotNum(long slotnum);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -2,10 +2,16 @@ package org.hso.ecommerce.repos.warehouse;
|
|||
|
||||
import org.hso.ecommerce.entities.warehouse.WarehouseBooking;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface WarehouseBookingRepository extends JpaRepository<WarehouseBooking, Long> {
|
||||
|
||||
@Query("Select b FROM WarehouseBooking b WHERE b.isDone = 0")
|
||||
List<WarehouseBooking> findNotDone();
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
document.addEventListener("DOMContentLoaded", function() {
|
||||
let priceElm = document.getElementById("price");
|
||||
let priceGrossElm = document.getElementById("priceGross");
|
||||
let vatPercent = parseInt(document.getElementById("vatPercent").value);
|
||||
|
||||
let updateFn = () => {
|
||||
let net = Math.floor(priceElm.value*100);
|
||||
let vat = Math.floor((net * vatPercent) / 100);
|
||||
let gross = net + vat;
|
||||
|
||||
priceGrossElm.innerText = (gross / 100.0).toFixed(2).replace("\\.", ",");
|
||||
};
|
||||
|
||||
priceElm.onchange = updateFn;
|
||||
});
|
|
@ -12,8 +12,6 @@
|
|||
<ul class="secondary">
|
||||
<li><a th:href="@{/}"> > Zur Startseite</a></li>
|
||||
<li><a th:href="@{/user/settings}">Einstellungen</a></li>
|
||||
<li><a th:href="@{/user/bonuspoints}">Bonuspunkte</a></li>
|
||||
<li><a th:href="@{/user/notifications/}">Benachrichtigungen</a></li>
|
||||
<li><a th:href="@{/user/orders/}">Bestellungen</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
<div th:if="${user}" class="dropdown">
|
||||
<a class="dropdown-button button">Mein Konto</a>
|
||||
<div class="dropdown-content">
|
||||
<a class="black button" th:href="@{/user/notifications/}">Benachrichtigungen</a>
|
||||
<a class="black button" th:href="@{/user/}">Einstellungen</a>
|
||||
<a class="black button" th:href="@{/user/orders/}">Meine Bestellungen</a>
|
||||
<form th:if="${user}" method="post" th:action="@{/logout}" class="no-margin">
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -63,7 +63,6 @@
|
|||
<td><a th:href="@{/shop/articles/{id}(id = ${position.article.id})}" th:text="${position.article.title}" class="s"></a></td>
|
||||
<td th:text="${position.quantity}" />
|
||||
<td th:text="${#numbers.formatDecimal(position.getSumPrice() * 0.01, 1, 'POINT', 2, 'COMMA')}" />
|
||||
</tr>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th></th>
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
<div class="sidebar-layout content-width">
|
||||
<nav></nav>
|
||||
<div>
|
||||
<h1>Kunde 1510</h1>
|
||||
<h1 th:text="|Kunde ${user.id}"></h1>
|
||||
|
||||
<script th:src="@{/js/back.js}"></script>
|
||||
<div class="back" data-group="intern" data-insert="true"></div>
|
||||
|
@ -37,33 +37,26 @@
|
|||
<table class="key-value">
|
||||
<tr>
|
||||
<th>Nutzer</th>
|
||||
<td><a th:href="@{/intern/customers/498}">1510</a></td>
|
||||
<td><a th:href="@{/intern/customers/{id}(id=${user.id})}" th:text="${user.id}"></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Bonuspunktestand</th>
|
||||
<td>50</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<td>Hans Maier</td>
|
||||
<td th:text="${user.name}"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>E-Mail</th>
|
||||
<td>hans.maier@example.com</td>
|
||||
<td th:text="${user.email}"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Status</th>
|
||||
<td>Geschäftskunde, Aktiv</td>
|
||||
<td>
|
||||
<span th:text="${user.isActive} ? 'Aktiv,' : 'Inaktiv,'"></span>
|
||||
<span th:text="${user.isEmployee} ? 'Mitarbeiter' : 'Kunde'"></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Adresse</th>
|
||||
<td>
|
||||
Hans Maier <br/>
|
||||
Hauptstraße 12<br/>
|
||||
74880 Musterstadt<br/>
|
||||
Deutschland <br/>
|
||||
</td>
|
||||
<td th:Text="${user.defaultDeliveryAddress}"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
|
@ -74,15 +67,15 @@
|
|||
<div id="add-actions" class="invisible info-box secondary hero">
|
||||
<h2>Status bearbeiten</h2>
|
||||
<p>
|
||||
<form>
|
||||
<form method="POST" th:action="@{/intern/customers/{id}/changeState(id=${user.id})}">
|
||||
<fieldset>
|
||||
<input type="checkbox" name="activ" id="activ" checked>
|
||||
<label for="activ">Aktiv</label> <br/>
|
||||
<input type="checkbox" name="active" id="active" th:checked="${user.isActive}">
|
||||
<label for="active">Aktiv</label> <br/>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
|
||||
<input type="checkbox" name="ma" id="ma">
|
||||
<input type="checkbox" name="ma" id="ma" th:checked="${user.isEmployee}">
|
||||
<label for="ma">Mitarbeiter-Status</label> <br/>
|
||||
</fieldset>
|
||||
|
||||
|
@ -94,7 +87,7 @@
|
|||
</p>
|
||||
<h2>Passwort zurücksetzen</h2>
|
||||
<p>
|
||||
<form>
|
||||
<form method="POST" th:action="@{/intern/customers/{id}/resetPassword(id=${user.id})}">
|
||||
<div>
|
||||
<label for="password">Passwort</label>
|
||||
<input class="full-width" type="password" name="password" placeholder="Passwort" id="password"
|
||||
|
@ -113,10 +106,8 @@
|
|||
</button>
|
||||
</form>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<h2>Bestellungen</h2>
|
||||
<p>
|
||||
<table id="main-table">
|
||||
|
@ -127,26 +118,20 @@
|
|||
<th>Status</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>440</td>
|
||||
<td>2019-12-54</td>
|
||||
<td>10,13 EUR</td>
|
||||
<td>Zugestellt</td>
|
||||
<td><a th:href="@{/intern/customerOrders/48584}" class="button smaller">Details</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>241</td>
|
||||
<td>2019-11-10</td>
|
||||
<td>40,13 EUR</td>
|
||||
<td>In Zustellung</td>
|
||||
<td><a th:href="@{/intern/customerOrders/48584}" class="button smaller">Details</a></td>
|
||||
<tr th:each="order: ${orders}">
|
||||
<td th:text="${order.id}"></td>
|
||||
<td th:text="${order.formatCreated()}"></td>
|
||||
<td th:text="${#numbers.formatDecimal(order.totalGrossCent * 0.01, 1, 'POINT', 2, 'COMMA')}"></td>
|
||||
<td th:if="${order.deliveredAt == null}">In Zustellung</td>
|
||||
<td th:if="${order.deliveredAt != null}">Zugestellt</td>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
|
||||
<h2>Buchungen</h2>
|
||||
<div>
|
||||
<h4> Kontostand </h4>
|
||||
<h3> 0,00 EUR </h3>
|
||||
<h3 th:text="${balance}" />
|
||||
</div>
|
||||
<p>
|
||||
<table id="main-table">
|
||||
|
@ -164,21 +149,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>
|
||||
|
|
|
@ -39,85 +39,16 @@
|
|||
<th>Status</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1209</td>
|
||||
<td>2019-11-10</td>
|
||||
<td>Hans Maier</td>
|
||||
<td>hans.maier@example.com</td>
|
||||
<td>Geschäftskunde</td>
|
||||
<td><a th:href="@{/intern/customers/4884}" class="button smaller">Details</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1208</td>
|
||||
<td>2019-11-10</td>
|
||||
<td>Hans Maier</td>
|
||||
<td>hans.maier@example.com</td>
|
||||
<td>Inaktiv, Geschäftskunde</td>
|
||||
<td><a th:href="@{/intern/customers/4884}" class="button smaller">Details</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1207</td>
|
||||
<td>2019-11-10</td>
|
||||
<td>Hans Maier</td>
|
||||
<td>hans.maier@example.com</td>
|
||||
<td></td>
|
||||
<td><a th:href="@{/intern/customers/4884}" class="button smaller">Details</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1206</td>
|
||||
<td>2019-11-10</td>
|
||||
<td>Hans Maier</td>
|
||||
<td>hans.maier@example.com</td>
|
||||
<td></td>
|
||||
<td><a th:href="@{/intern/customers/4884}" class="button smaller">Details</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1205</td>
|
||||
<td>2019-11-10</td>
|
||||
<td>Hans Maier</td>
|
||||
<td>hans.maier@example.com</td>
|
||||
<td></td>
|
||||
<td><a th:href="@{/intern/customers/4884}" class="button smaller">Details</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1204</td>
|
||||
<td>2019-11-10</td>
|
||||
<td>Hans Maier</td>
|
||||
<td>hans.maier@example.com</td>
|
||||
<td></td>
|
||||
<td><a th:href="@{/intern/customers/4884}" class="button smaller">Details</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1203</td>
|
||||
<td>2019-11-10</td>
|
||||
<td>Hans Maier</td>
|
||||
<td>hans.maier@example.com</td>
|
||||
<td></td>
|
||||
<td><a th:href="@{/intern/customers/4884}" class="button smaller">Details</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1202</td>
|
||||
<td>2019-11-10</td>
|
||||
<td>Hans Maier</td>
|
||||
<td>hans.maier@example.com</td>
|
||||
<td></td>
|
||||
<td><a th:href="@{/intern/customers/4884}" class="button smaller">Details</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1201</td>
|
||||
<td>2019-11-10</td>
|
||||
<td>Hans Maier</td>
|
||||
<td>hans.maier@example.com</td>
|
||||
<td>Inaktiv, Mitarbeiter</td>
|
||||
<td><a th:href="@{/intern/customers/4884}" class="button smaller">Details</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1214</td>
|
||||
<td>2019-11-10</td>
|
||||
<td>Hans Maier</td>
|
||||
<td>admin@example.com</td>
|
||||
<td>Mitarbeiter</td>
|
||||
<td><a th:href="@{/intern/customers/4884}" class="button smaller">Details</a></td>
|
||||
<tr th:each="user: ${users}">
|
||||
<td th:text="${user.id}"></td>
|
||||
<td th:text="${user.created.toString().substring(0, 10)}"></td>
|
||||
<td th:text="${user.name}"></td>
|
||||
<td th:text="${user.email}"></td>
|
||||
<td>
|
||||
<span th:text="${user.isActive} ? 'Aktiv,' : 'Inaktiv,'"></span>
|
||||
<span th:text="${user.isEmployee} ? 'Mitarbeiter' : 'Kunde'"></span>
|
||||
</td>
|
||||
<td><a th:href="@{/intern/customers/{id}(id = ${user.id})}" class="button smaller">Details</a></td>
|
||||
</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>
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=0.75, user-scalable=no">
|
||||
<title>Bearbeiten: Artikel</title>
|
||||
<script th:src="@{/js/filterTable.js}"></script>
|
||||
<script th:src="@{/js/editViewUpdateTax.js}"></script>
|
||||
<link rel="stylesheet" th:href="@{/css/ecom.css}"/>
|
||||
</head>
|
||||
<body>
|
||||
|
@ -28,9 +29,9 @@
|
|||
</p>
|
||||
<p class="s">
|
||||
<label for="ref_disabled">Refernzierter Artikel</label>
|
||||
<input class="" type="text" id="ref_disabled" th:value="${ArticleID.offer_id}" disabled/>
|
||||
<input class="" type="text" id="ref_disabled" th:value="${ArticleID.offerID}" disabled/>
|
||||
|
||||
<input type="hidden" id="ref_hidden" th:value="${ArticleID.offer_id}" name="ref-article" />
|
||||
<input type="hidden" id="ref_hidden" th:value="${ArticleID.offerID}" name="ref-article" />
|
||||
|
||||
<a th:href="${'/intern/supplierOffers/#q=' + ArticleID.id}">Details</a>
|
||||
</p>
|
||||
|
@ -47,10 +48,13 @@
|
|||
<div class="s">
|
||||
<p>
|
||||
<label for="price">Preis (Netto)</label>
|
||||
<input class="" type="number" id="price" step="0.01" name="price_netto" required th:value="${ArticleID.price_netto}"/> EUR <br/>
|
||||
(19% Mwst.)
|
||||
<input class="" type="number" id="price" step="0.01" name="priceNet" required
|
||||
th:value="${ArticleID.priceNet}"/> EUR <br/>
|
||||
(<span th:text="${ArticleID.vatPercent}"></span>% Mwst.)
|
||||
<input type="hidden" id="vatPercent" name="vatPercent" th:value="${ArticleID.vatPercent}"/>
|
||||
|
||||
<!-- Info von article ref--> <br/>
|
||||
= <span th:text="${ArticleID.price}"></span> EUR Brutto
|
||||
= <span id="priceGross" th:text="${ArticleID.price}"></span> EUR Brutto
|
||||
</p>
|
||||
<p>
|
||||
<label for="reorderMaxPrice">Maximaler Einkaufspreis (Netto)</label>
|
||||
|
@ -106,4 +110,4 @@
|
|||
</main>
|
||||
<footer th:replace="fragments/footer :: footer"></footer>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
|
@ -50,10 +50,10 @@
|
|||
<td><img th:src="@{/shop/articles/{id}/image.jpg(id=${article.id})}" class="s"/></td>
|
||||
<td><span th:text="${article.title}"></span></td>
|
||||
<td><span th:text="${article.price}"></span> €</td>
|
||||
<td><span th:text="${article.price_netto}"></span> €</td>
|
||||
<td><span th:text="${article.priceNet}"></span> €</td>
|
||||
<td><span th:text="${article.categorie}"></span></td>
|
||||
<td><span th:text="${article.stock}"></span></td>
|
||||
<td><a th:href="${'/intern/supplierOffers/#q=' + article.title}" th:text="${article.offer_id}"></a></td>
|
||||
<td><a th:href="${'/intern/supplierOffers/#q=' + article.title}" th:text="${article.offerID}"></a></td>
|
||||
<td><a th:href="@{/intern/articles/{id}(id = ${article.id})}" th:text="${article.id}"></a></td>
|
||||
<td>
|
||||
<form th:action="@{/intern/articles/{id}(id = ${article.id})}"><input class="button smaller" type="submit" value="Bearbeiten" /></form>
|
||||
|
|
|
@ -43,8 +43,9 @@
|
|||
<tr th:each="article : ${OfferedArticles}">
|
||||
<td><span th:text="${article.title}"></span></td>
|
||||
<td><span th:text="${article.manufacturer}"></span></td>
|
||||
<td><span th:text="${article.articlenumber}"></span></td>
|
||||
<td><a th:href="@{/intern/suppliers/{id}(id = ${article.supplierId})}" th:text="${article.supplierName}"></a></td>
|
||||
<td><span th:text="${article.articleNumber}"></span></td>
|
||||
<td th:if="${article.supplierName} == '-'">-</td>
|
||||
<td th:unless="${article.supplierName} == '-'"><a th:href="${'/intern/suppliers/#q=' + article.supplierName}" th:text="${article.supplierName}"></a></td>
|
||||
<td><span th:text="${article.price}"></span> €</td>
|
||||
<td><span th:text="${article.ads}"></span></td>
|
||||
<td>
|
||||
|
@ -53,7 +54,7 @@
|
|||
</div>
|
||||
<!-- ELSE -->
|
||||
<div th:unless="${article.offerIsListed}">
|
||||
<form class="detailgrid" action="#" th:action="@{/intern/articles/addArticle/{id}(id = ${article.offer_id})}" method="POST">
|
||||
<form class="detailgrid" action="#" th:action="@{/intern/articles/addArticle/{id}(id = ${article.offerId})}" method="POST">
|
||||
<input class="button smaller" type="submit" value="Hinzufügen" />
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -1,103 +1,74 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="de" dir="ltr" xmlns:th="http://www.thymeleaf.org">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.75, user-scalable=no">
|
||||
|
||||
<title>Lieferanten Bestellungen</title>
|
||||
<script th:src="@{/js/filterTable.js}"></script>
|
||||
<link rel="stylesheet" th:href="@{/css/ecom.css}"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<nav th:replace="fragments/header :: header">Header</nav>
|
||||
<div class="sidebar-layout content-width">
|
||||
<nav></nav>
|
||||
<div>
|
||||
<h1>Lieferanten Bestellungen</h1>
|
||||
|
||||
<script th:src="@{/js/back.js}"></script>
|
||||
<div class="back" data-group="intern" data-name="Zurück zu den Bestellungen bei Lieferanten."
|
||||
data-insert="false"></div>
|
||||
</div>
|
||||
</div>
|
||||
<main class="sidebar-layout content-width">
|
||||
<nav th:replace="fragments/intern :: sidebar"></nav>
|
||||
<div class="content-width">
|
||||
<p>
|
||||
<table id="main-table">
|
||||
<tr>
|
||||
<th colspan="9">
|
||||
<input type="text" placeholder="Filtern" class="smaller jsFilterTable full-width"
|
||||
data-target-id="main-table"></input>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Bestellnummer</th>
|
||||
<th>Datum</th>
|
||||
<th>Leiferant</th>
|
||||
<th>Artikel</th>
|
||||
<th>Preis/Stk (Netto)</th>
|
||||
<th>Menge</th>
|
||||
<th>Gesamtpreis (Netto)</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>4545</td>
|
||||
<td>2019-18-10</td>
|
||||
<td><a th:href="@{/intern/suppliers/45015}">Cheap AG</a></td>
|
||||
<td><a th:href="@{/intern/listedArticles/45015}">Kamera</a></td>
|
||||
<td>20,00 EUR</td>
|
||||
<td>10</td>
|
||||
<td>200,00 EUR</td>
|
||||
<td>Unterwegs <br/><a th:href="@{/intern/warehouse/todo}" class="button smaller">Angekommen</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2455</td>
|
||||
<td>2019-18-10</td>
|
||||
<td><a th:href="@{/intern/suppliers/45015}">Cheap AG</a></td>
|
||||
<td><a th:href="@{/intern/listedArticles/45015}">Kamera</a></td>
|
||||
<td>20,00 EUR</td>
|
||||
<td>11</td>
|
||||
<td>220,00 EUR</td>
|
||||
<td>Unterwegs <br/><a th:href="@{/intern/warehouse/todo}" class="button smaller">Angekommen</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1224</td>
|
||||
<td>2019-18-10</td>
|
||||
<td><a th:href="@{/intern/suppliers/45015}">Cheap AG</a></td>
|
||||
<td><a th:href="@{/intern/listedArticles/45015}">Kamera</a></td>
|
||||
<td>20,00 EUR</td>
|
||||
<td>11</td>
|
||||
<td>220,00 EUR</td>
|
||||
<td>Angekommen</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>4520</td>
|
||||
<td>2019-18-10</td>
|
||||
<td><a th:href="@{/intern/suppliers/45015}">Cheap AG</a></td>
|
||||
<td><a th:href="@{/intern/listedArticles/45015}">Kamera</a></td>
|
||||
<td>20,00 EUR</td>
|
||||
<td>11</td>
|
||||
<td>220,00 EUR</td>
|
||||
<td>Angekommen</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>4521</td>
|
||||
<td>2019-18-10</td>
|
||||
<td><a th:href="@{/intern/suppliers/45015}">Cheap AG</a></td>
|
||||
<td><a th:href="@{/intern/listedArticles/45015}">Kamera</a></td>
|
||||
<td>20,00 EUR</td>
|
||||
<td>11</td>
|
||||
<td>220,00 EUR</td>
|
||||
<td>Angekommen</td>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
<footer th:replace="fragments/footer :: footer"></footer>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.75, user-scalable=no">
|
||||
<title>Lieferanten Bestellungen</title>
|
||||
<script th:src="@{/js/filterTable.js}"></script>
|
||||
<link rel="stylesheet" th:href="@{/css/ecom.css}"/>
|
||||
</head>
|
||||
<body>
|
||||
<nav th:replace="fragments/header :: header">Header</nav>
|
||||
<div class="sidebar-layout content-width">
|
||||
<nav></nav>
|
||||
<div>
|
||||
<h1>Lieferanten Bestellungen</h1>
|
||||
<script th:src="@{/js/back.js}"></script>
|
||||
<div class="back" data-group="intern" data-name="Zurück zu den Bestellungen bei Lieferanten."
|
||||
data-insert="false"></div>
|
||||
</div>
|
||||
</div>
|
||||
<main class="sidebar-layout content-width">
|
||||
<nav th:replace="fragments/intern :: sidebar"></nav>
|
||||
<div class="content-width">
|
||||
<p>
|
||||
<table id="main-table">
|
||||
<tr>
|
||||
<th colspan="9">
|
||||
<input type="text" placeholder="Filtern" class="smaller jsFilterTable full-width"
|
||||
data-target-id="main-table">
|
||||
</th>
|
||||
</tr>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Bestellnummer</th>
|
||||
<th>Datum</th>
|
||||
<th>Leiferant</th>
|
||||
<th>Artikel</th>
|
||||
<th>Preis/Stk (Netto)</th>
|
||||
<th>Menge</th>
|
||||
<th>Gesamtpreis (Netto)</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<tr th:each="order : ${orders}">
|
||||
<td><span th:text="${order.id}"></span></td>
|
||||
<td><span th:text="${order.dateOrder}"></span></td>
|
||||
<td><span th:text="${order.supplierName}"></span></td>
|
||||
<td><a th:href="@{/intern/articles/{id}(id = ${order.articleId})}" class="button smaller" th:text="${order.articleName}"></a></td>
|
||||
<td><span th:text="${order.priceNet}"></span> €</td>
|
||||
<td><span th:text="${order.quantity}"></span></td>
|
||||
<td><span th:text="${order.priceTotal}"></span> €</td>
|
||||
<td>
|
||||
<div th:if="${order.arrived}">
|
||||
Angekommen
|
||||
</div>
|
||||
<!-- ELSE -->
|
||||
<div th:unless="${order.arrived}">
|
||||
Unterwegs <br>
|
||||
<form class="detailgrid" action="#" th:action="@{/intern/supplierOrders/store/{id}(id = ${order.id})}" method="POST">
|
||||
<input class="button smaller" type="submit" value="Eingang verbuchen" />
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
<footer th:replace="fragments/footer :: footer"></footer>
|
||||
</body>
|
||||
</html>
|
|
@ -1,86 +1,106 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="de" dir="ltr" xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.75, user-scalable=no">
|
||||
<title>Lieferanten Details</title>
|
||||
<script th:src="@{/js/filterTable.js}"></script>
|
||||
<link rel="stylesheet" th:href="@{/css/ecom.css}"/>
|
||||
</head>
|
||||
<body>
|
||||
<nav th:replace="fragments/header :: header">Header</nav>
|
||||
<div class="sidebar-layout content-width">
|
||||
<nav></nav>
|
||||
<div>
|
||||
<h1>Lieferant <span th:text="${SupplierDetail.name}"></span></h1>
|
||||
<script th:src="@{/js/back.js}"></script>
|
||||
<div class="back" data-group="intern" data-insert="true"></div>
|
||||
</div>
|
||||
</div>
|
||||
<main class="sidebar-layout content-width">
|
||||
<nav th:replace="fragments/intern :: sidebar"></nav>
|
||||
<div class="content-width">
|
||||
<h2>Bestellungen</h2>
|
||||
<p>
|
||||
<table id="order-table">
|
||||
<tr>
|
||||
<th colspan="9">
|
||||
<input type="text" placeholder="Filtern" class="smaller jsFilterTable full-width"
|
||||
data-target-id="main-table">
|
||||
</th>
|
||||
</tr>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Bestellnummer</th>
|
||||
<th>Datum</th>
|
||||
<th>Artikel</th>
|
||||
<th>Preis/Stk (Netto)</th>
|
||||
<th>Menge</th>
|
||||
<th>Gesamtpreis (Netto)</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="order : ${SupplierDetail.orders}">
|
||||
<td><span th:text="${order.id}"></span></td>
|
||||
<td><span th:text="${order.dateOrder}"></span></td>
|
||||
<td><a th:href="@{/intern/articles/{id}(id = ${order.articleId})}" class="button smaller" th:text="${order.articleName}"></a></td>
|
||||
<td><span th:text="${order.priceNet}"></span> €</td>
|
||||
<td><span th:text="${order.quantity}"></span></td>
|
||||
<td><span th:text="${order.priceTotal}"></span> €</td>
|
||||
<td>
|
||||
<div th:if="${order.arrived}">
|
||||
Angekommen
|
||||
</div>
|
||||
<!-- ELSE -->
|
||||
<div th:unless="${order.arrived}">
|
||||
Unterwegs <br>
|
||||
<form class="detailgrid" action="#" th:action="@{/intern/supplierOrders/store/{id}(id = ${order.id})}" method="POST">
|
||||
<input class="button smaller" type="submit" value="Eingang verbuchen" />
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</p>
|
||||
<h2>Buchungen</h2>
|
||||
<div>
|
||||
<h4> Kontostand </h4>
|
||||
<h3 th:text="${SupplierDetail.balance}" />
|
||||
</div>
|
||||
<p>
|
||||
<table id="booking-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Zeitpunkt</th>
|
||||
<th>Betrag</th>
|
||||
<th>Von</th>
|
||||
<th>Kontostand</th>
|
||||
<th>Grund</th>
|
||||
<th>Referenz</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<tr th:each="booking : ${SupplierDetail.bookings}">
|
||||
<td th:text="${booking.datetime}" />
|
||||
<td th:text="${booking.amount}" />
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.75, user-scalable=no">
|
||||
<td th:if="${booking.sourceAddr}"><a th:href="@{${booking.sourceAddr}}" th:text="${booking.source}" /></td>
|
||||
<td th:unless="${booking.sourceAddr}" th:text="${booking.source}" />
|
||||
|
||||
<title>Lieferanten Details</title>
|
||||
<script th:src="@{/js/filterTable.js}"></script>
|
||||
<link rel="stylesheet" th:href="@{/css/ecom.css}"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<nav th:replace="fragments/header :: header">Header</nav>
|
||||
<div class="sidebar-layout content-width">
|
||||
<nav></nav>
|
||||
<div>
|
||||
<h1>Lierfant Cheap AG</h1>
|
||||
|
||||
<script th:src="@{/js/back.js}"></script>
|
||||
<div class="back" data-group="intern" data-insert="true"></div>
|
||||
</div>
|
||||
</div>
|
||||
<main class="sidebar-layout content-width">
|
||||
<nav th:replace="fragments/intern :: sidebar"></nav>
|
||||
<div class="content-width">
|
||||
<h2>Bestellungen</h2>
|
||||
<p>
|
||||
<table id="main-table">
|
||||
<tr>
|
||||
<th colspan="9">
|
||||
<input type="text" placeholder="Filtern" class="smaller jsFilterTable full-width"
|
||||
data-target-id="main-table"></input>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Bestellnummer</th>
|
||||
<th>Datum</th>
|
||||
<th>Artikel</th>
|
||||
<th>Preis/Stk (Netto)</th>
|
||||
<th>Menge</th>
|
||||
<th>Gesamtpreis (Netto)</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>4545</td>
|
||||
<td>2019-18-10</td>
|
||||
<td><a th:href="@{/intern/listedArticles/45015}">Kamera</a></td>
|
||||
<td>20,00 EUR</td>
|
||||
<td>10</td>
|
||||
<td>200,00 EUR</td>
|
||||
<td>Unterwegs <br/><a th:href="@{/intern/warehouse/todo}" class="button smaller">Angekommen</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
<h2>Buchungen</h2>
|
||||
<div>
|
||||
<h4> Kontostand </h4>
|
||||
<h3> -100,00 EUR </h3>
|
||||
</div>
|
||||
<p>
|
||||
<table id="main-table">
|
||||
<tr>
|
||||
<th>Zeitpunkt</th>
|
||||
<th>Betrag</th>
|
||||
<th>Von</th>
|
||||
<th>Kontostand</th>
|
||||
<th>Grund</th>
|
||||
<th>Referenz</th>
|
||||
</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>Lieferanten-Bestellung</td>
|
||||
<td><a th:href="@{/intern/supplierOrders/#q=4520}">2504</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
<footer th:replace="fragments/footer :: footer"></footer>
|
||||
</body>
|
||||
<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>
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
<footer th:replace="fragments/footer :: footer"></footer>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,63 +1,52 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="de" dir="ltr" xmlns:th="http://www.thymeleaf.org">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.75, user-scalable=no">
|
||||
|
||||
<title>Lieferanten</title>
|
||||
<script th:src="@{/js/filterTable.js}"></script>
|
||||
<link rel="stylesheet" th:href="@{/css/ecom.css}"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<nav th:replace="fragments/header :: header">Header</nav>
|
||||
<div class="sidebar-layout content-width">
|
||||
<nav></nav>
|
||||
<div>
|
||||
<h1>Lieferanten</h1>
|
||||
|
||||
<script th:src="@{/js/back.js}"></script>
|
||||
<div class="back" data-group="intern" data-name="Zurück zur Übersicht der Lieferanten."
|
||||
data-insert="false"></div>
|
||||
</div>
|
||||
</div>
|
||||
<main class="sidebar-layout content-width">
|
||||
<nav th:replace="fragments/intern :: sidebar"></nav>
|
||||
<div class="content-width">
|
||||
<p>
|
||||
<table id="main-table">
|
||||
<tr>
|
||||
<th colspan="7">
|
||||
<input type="text" placeholder="Filtern" class="smaller jsFilterTable full-width"
|
||||
data-target-id="main-table"></input>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Nr</th>
|
||||
<th>Name</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>0015</td>
|
||||
<td>Cheap AG</td>
|
||||
<td><a th:href="@{/intern/suppliers/4884}" class="button smaller">Details</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>5012</td>
|
||||
<td>Not Cheap GmbH & Co. KG</td>
|
||||
<td><a th:href="@{/intern/suppliers/4884}" class="button smaller">Details</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>7400</td>
|
||||
<td>Hans MÜller GmbH</td>
|
||||
<td><a th:href="@{/intern/suppliers/4884}" class="button smaller">Details</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
<footer th:replace="fragments/footer :: footer"></footer>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.75, user-scalable=no">
|
||||
<title>Lieferanten</title>
|
||||
<script th:src="@{/js/filterTable.js}"></script>
|
||||
<link rel="stylesheet" th:href="@{/css/ecom.css}"/>
|
||||
</head>
|
||||
<body>
|
||||
<nav th:replace="fragments/header :: header">Header</nav>
|
||||
<div class="sidebar-layout content-width">
|
||||
<nav></nav>
|
||||
<div>
|
||||
<h1>Lieferanten</h1>
|
||||
<script th:src="@{/js/back.js}"></script>
|
||||
<div class="back" data-group="intern" data-name="Zurück zur Übersicht der Lieferanten."
|
||||
data-insert="false"></div>
|
||||
</div>
|
||||
</div>
|
||||
<main class="sidebar-layout content-width">
|
||||
<nav th:replace="fragments/intern :: sidebar"></nav>
|
||||
<div class="content-width">
|
||||
<p>
|
||||
<table id="main-table">
|
||||
<tr>
|
||||
<th colspan="7">
|
||||
<input type="text" placeholder="Filtern" class="smaller jsFilterTable full-width"
|
||||
data-target-id="main-table">
|
||||
</th>
|
||||
</tr>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Nr</th>
|
||||
<th>Name</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="supplier : ${suppliers}">
|
||||
<td><span th:text="${supplier.id}"></span></td>
|
||||
<td><span th:text="${supplier.name}"></span></td>
|
||||
<td><a th:href="@{/intern/suppliers/{id}(id = ${supplier.id})}" class="button smaller">Details</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
<footer th:replace="fragments/footer :: footer"></footer>
|
||||
</body>
|
||||
</html>
|
|
@ -20,14 +20,12 @@
|
|||
<main class="sidebar-layout content-width">
|
||||
<nav th:replace="fragments/intern :: sidebar"></nav>
|
||||
<div class="content-width">
|
||||
<form class="detailgrid" th:action="@{/intern/warehouse/todo}">
|
||||
<form class="detailgrid" method="post" th:action="@{/intern/warehouse/addManual}">
|
||||
<div class="m">
|
||||
<label for="amount">Artikelnummer</label>
|
||||
<input placeholder="Nr." class="full-width" type="text" name="article" value="" list="articles"/>
|
||||
<input placeholder="Nr." class="full-width" type="text" name="articleId" value="" list="articles"/>
|
||||
<datalist id="articles">
|
||||
<option value="5100 - Kamera"/>
|
||||
<option value="5200 - Usb Stick"/>
|
||||
<option value="5640 - Stativ"/>
|
||||
<option th:each="article: ${articles}" th:value="${article.id + ' - ' + article.title}"/>
|
||||
</datalist>
|
||||
</div>
|
||||
<div class="s">
|
||||
|
@ -36,20 +34,23 @@
|
|||
</div>
|
||||
<div class="l">
|
||||
<label for="reason">Grund:</label>
|
||||
<input placeholder="Grund" class="full-width" type="text" name="reason-man" value=""/>
|
||||
<input placeholder="Grund" class="full-width" type="text" name="reason" value=""/>
|
||||
</div>
|
||||
|
||||
<div class="s">
|
||||
<fieldset>
|
||||
<label for="source">Von</label>
|
||||
<fieldset>
|
||||
<input type="radio" id="s-no" name="source" value="None" required>
|
||||
<input type="radio" id="s-no" name="sourceIsSlot" value="false" required>
|
||||
<label for="s-no">Hinzufügen</label>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<input type="radio" id="s-main" name="source" value="Slot" required>
|
||||
<input type="radio" id="s-main" name="sourceIsSlot" value="true" required>
|
||||
<label for="s-main">Lagerplatz</label>
|
||||
<input placeholder="Nr." type="text" name="source-slot" value=""/>
|
||||
<input placeholder="Nr." type="text" name="sourceSlot" value="" list="slots"/>
|
||||
<datalist id="slots">
|
||||
<option th:each="slot: ${slots}" th:value="${slot.slotNum}"/>
|
||||
</datalist>
|
||||
</fieldset>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
@ -58,13 +59,13 @@
|
|||
<fieldset>
|
||||
<label for="destination">Nach</label>
|
||||
<fieldset>
|
||||
<input type="radio" id="d-no" name="destination" value="None" required>
|
||||
<input type="radio" id="d-no" name="destinationIsSlot" value="false" required>
|
||||
<label for="d-no">Entfernen</label>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<input type="radio" id="d-main" name="destination" value="Main" required>
|
||||
<input type="radio" id="d-main" name="destinationIsSlot" value="true" required>
|
||||
<label for="d-main">Lagerplatz</label>
|
||||
<input placeholder="Nr." type="text" name="destination-slot" value=""/>
|
||||
<input placeholder="Nr." type="text" name="destinationSlot" value="" list="slots"/>
|
||||
</fieldset>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
|
|
@ -21,35 +21,54 @@
|
|||
</tr>
|
||||
|
||||
<!-------------------------------------------------------------->
|
||||
<tr data-group="3">
|
||||
<td>2020-01-12 12:18</td>
|
||||
<td colspan="4" class="l">
|
||||
<a th:href="@{/intern/customerOrders/4808}">Bestellung 8408</a>
|
||||
<div>
|
||||
Hans Maier <br/>
|
||||
Hauptstraße 12<br/>
|
||||
74880 Musterstadt<br/>
|
||||
Deutschland <br/>
|
||||
</div>
|
||||
<tr>
|
||||
<td th:text="${booking.created.toString()}"></td>
|
||||
<td th:if="${booking.reason.isManuel}" colspan="4" class="l">
|
||||
Manuell:
|
||||
<pre th:text="${booking.reason.comment}"></pre>
|
||||
</td>
|
||||
<td th:if="${booking.reason.isStartBooking}" colspan="4" class="l">
|
||||
Startbuchung
|
||||
</td>
|
||||
<td th:if="${booking.reason.customerOrder != null}" colspan="4" class="l">
|
||||
<a th:href="${'/intern/customerOrders/' + booking.reason.customerOrder.id}">
|
||||
Bestellung: <span th:text="${booking.reason.customerOrder.id}"></span>
|
||||
</a>
|
||||
<pre th:text="${booking.reason.customerOrder.destination.toString()}"></pre>
|
||||
</td>
|
||||
<td th:if="${booking.reason.supplierOrder != null}" colspan="4" class="l">
|
||||
<a th:href="${'/intern/supplierOrders/#q=' + booking.reason.supplierOrder.id}">
|
||||
Lieferung: <span th:text="${booking.reason.supplierOrder.id}"></span>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr data-group="3">
|
||||
<td><img th:src="@{/img/product-1.jpg}" class="s"/></td>
|
||||
<td><a th:href="@{/intern/listedArticles/45015}">Kamera</a></td>
|
||||
<td>1</td>
|
||||
<td><a th:href="@{/intern/warehouse/slots/#q=%231}">Lagerplatz 01</a></td>
|
||||
<td> -</td>
|
||||
</tr>
|
||||
<tr data-group="3">
|
||||
<td><img th:src="@{/img/product-2.jpg}" class="s"/></td>
|
||||
<td><a th:href="@{/intern/listedArticles/4205}">Spielzeugauto</a></td>
|
||||
<td>2</td>
|
||||
<td><a th:href="@{/intern/warehouse/slots/#q=%232}">Lagerplatz 02</a></td>
|
||||
<td> -</td>
|
||||
<tr th:each="pos : ${booking.positions}">
|
||||
<td><img th:src="@{/shop/articles/{id}/image.jpg(id=${pos.article.id})}" class="s"/></td>
|
||||
<td><a th:href="@{/intern/articles/{id}(id=${pos.article.id})}"
|
||||
th:text="${pos.article.title}"></a></td>
|
||||
<th:block th:if="${pos.amount > 0}">
|
||||
<td th:text="${pos.amount}"></td>
|
||||
<td> -</td>
|
||||
<td><a th:href="${'/intern/warehouse/slots/#q=%23' + pos.slotEntry.slot.slotNum}">Lagerplatz <span
|
||||
th:text="${pos.slotEntry.slot.slotNum}"></span> </a></td>
|
||||
</th:block>
|
||||
<th:block th:if="${pos.amount < 0}">
|
||||
<td th:text="${pos.amount * -1}"></td>
|
||||
<td><a th:href="${'/intern/warehouse/slots/#q=%23' + pos.slotEntry.slot.slotNum}">Lagerplatz <span
|
||||
th:text="${pos.slotEntry.slot.slotNum}"></span> </a></td>
|
||||
<td> -</td>
|
||||
</th:block>
|
||||
<th:block th:if="${pos.amount == 0}">
|
||||
<td th:text="${pos.amount}"></td>
|
||||
<td> -</td>
|
||||
<td> -</td>
|
||||
</th:block>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
<a class="secondary button" th:href="@{/intern/warehouse/todo}"> Abschließen </a>
|
||||
<form method="post" th:action="@{/intern/warehouse/progress/{id}/finish(id=${booking.id})}">
|
||||
<button class="secondary full-width"> Abschließen</button>
|
||||
</form>
|
||||
</div>
|
||||
</main>
|
||||
<footer th:replace="fragments/footer :: footer"></footer>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="de" dir="ltr" xmlns:th="http://www.thymeleaf.org">
|
||||
<html dir="ltr" lang="de" xmlns:th="http://www.thymeleaf.org">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.75, user-scalable=no">
|
||||
<meta content="width=device-width, initial-scale=0.75, user-scalable=no" name="viewport">
|
||||
|
||||
<title>Lager</title>
|
||||
<script th:src="@{/js/filterTable.js}"></script>
|
||||
|
@ -18,7 +18,7 @@
|
|||
<h1>Lagerbuchungen</h1>
|
||||
|
||||
<script th:src="@{/js/back.js}"></script>
|
||||
<div class="back" data-group="intern" data-name="Zurück zu den Lagerbuchungen." data-insert="false"></div>
|
||||
<div class="back" data-group="intern" data-insert="false" data-name="Zurück zu den Lagerbuchungen."></div>
|
||||
</div>
|
||||
</div>
|
||||
<main class="sidebar-layout content-width">
|
||||
|
@ -32,8 +32,8 @@
|
|||
<table id="main-table">
|
||||
<tr>
|
||||
<th colspan="7">
|
||||
<input type="text" placeholder="Filtern" class="smaller jsFilterTable full-width"
|
||||
data-target-id="main-table"></input>
|
||||
<input class="smaller jsFilterTable full-width" data-target-id="main-table" placeholder="Filtern"
|
||||
type="text"></input>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -45,77 +45,61 @@
|
|||
<th>Status</th>
|
||||
</tr>
|
||||
|
||||
<th:block th:each="booking : ${bookings}">
|
||||
<tr th:data-group="${booking.id}">
|
||||
<td th:text="${booking.created.toString()}"></td>
|
||||
<td class="l" colspan="4" th:if="${booking.reason.isManuel}">
|
||||
Manuell: <small th:text="${booking.reason.comment}"></small>
|
||||
</td>
|
||||
<td class="l" colspan="4" th:if="${booking.reason.isStartBooking}">
|
||||
Startbuchung
|
||||
</td>
|
||||
<td class="l" colspan="4" th:if="${booking.reason.customerOrder != null}">
|
||||
<a th:href="${'/intern/customerOrders/' + booking.reason.customerOrder.id}">
|
||||
Bestellung: <span th:text="${booking.reason.customerOrder.id}"></span>
|
||||
</a>
|
||||
</td>
|
||||
<td class="l" colspan="4" th:if="${booking.reason.supplierOrder != null}">
|
||||
<a th:href="${'/intern/supplierOrders/#q=' + booking.reason.supplierOrder.id}">
|
||||
Lieferung: <span th:text="${booking.reason.supplierOrder.id}"></span>
|
||||
</a>
|
||||
</td>
|
||||
|
||||
<!-------------------------------------------------------------->
|
||||
<tr data-group="3">
|
||||
<td>2020-01-12 12:18</td>
|
||||
<td colspan="4" class="l">
|
||||
<a th:href="@{/intern/customerOrders/4808}">Bestellung 8408</a>
|
||||
</td>
|
||||
<td>Auf Warteliste <br/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr data-group="3">
|
||||
<td></td>
|
||||
<td><a th:href="@{/intern/listedArticles/45015}">Kamera</a></td>
|
||||
<td>1</td>
|
||||
<td><a th:href="@{/intern/warehouse/slots/#q=%231}">Lagerplatz 01</a></td>
|
||||
<td> -</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr data-group="3">
|
||||
<td></td>
|
||||
<td><a th:href="@{/intern/listedArticles/4205}">Spielzeugauto</a></td>
|
||||
<td>2</td>
|
||||
<td><a th:href="@{/intern/warehouse/slots/#q=%232}">Lagerplatz 02</a></td>
|
||||
<td> -</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<td th:if="${!booking.isInProgress && !booking.isDone}">
|
||||
Auf Warteliste
|
||||
</td>
|
||||
<td th:if="${booking.isInProgress && !booking.isDone}">
|
||||
Wird bearbeitet
|
||||
</td>
|
||||
<td th:if="${booking.isInProgress && booking.isDone}">
|
||||
Fertig
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-------------------------------------------------------------->
|
||||
<tr data-group="2">
|
||||
<td>2020-01-12 12:15</td>
|
||||
<td colspan="4" class="l">
|
||||
Manuell: Ware war defekt.
|
||||
</td>
|
||||
<td>In Arbeit <br/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr data-group="2">
|
||||
<td></td>
|
||||
<td><a th:href="@{/intern/listedArticles/45015}">Kamera</a></td>
|
||||
<td>1</td>
|
||||
<td><a th:href="@{/intern/warehouse/slots/#q=%231}">Lagerplatz 01</a></td>
|
||||
<td> -</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
|
||||
<!-------------------------------------------------------------->
|
||||
<tr data-group="1">
|
||||
<td>2020-01-12 12:11</td>
|
||||
<td colspan="4" class="l">
|
||||
<a th:href="@{/intern/supplierOrders/#q=4545}">Lieferung 4545</a>
|
||||
</td>
|
||||
<td>Fertig <br/></td>
|
||||
</tr>
|
||||
<tr data-group="1">
|
||||
<td></td>
|
||||
<td><a th:href="@{/intern/listedArticles/45015}">Kamera</a></td>
|
||||
<td>10</td>
|
||||
<td> -</td>
|
||||
<td><a th:href="@{/intern/warehouse/slots/#q=%231}">Lagerplatz 01</a>
|
||||
</th>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr data-group="1">
|
||||
<td></td>
|
||||
<td><a th:href="@{/intern/listedArticles/45015}">Kamera</a></td>
|
||||
<td>1</td>
|
||||
<td> -</td>
|
||||
<td><a th:href="@{/intern/warehouse/slots/#q=%234}">Lagerplatz 04</a></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr th:data-group="${booking.id}" th:each="pos : ${booking.positions}">
|
||||
<td></td>
|
||||
<td><a th:href="@{/intern/articles/{id}(id=${pos.article.id})}"
|
||||
th:text="${pos.article.title}"></a></td>
|
||||
<th:block th:if="${pos.amount > 0}">
|
||||
<td th:text="${pos.amount}"></td>
|
||||
<td> -</td>
|
||||
<td><a th:href="${'/intern/warehouse/slots/#q=%23' + pos.slotEntry.slot.slotNum}">Lagerplatz
|
||||
<span th:text="${pos.slotEntry.slot.slotNum}"></span> </a></td>
|
||||
</th:block>
|
||||
<th:block th:if="${pos.amount < 0}">
|
||||
<td th:text="${pos.amount * -1}"></td>
|
||||
<td><a th:href="${'/intern/warehouse/slots/#q=%23' + pos.slotEntry.slot.slotNum}">Lagerplatz
|
||||
<span th:text="${pos.slotEntry.slot.slotNum}"></span> </a></td>
|
||||
<td> -</td>
|
||||
</th:block>
|
||||
<th:block th:if="${pos.amount == 0}">
|
||||
<td th:text="${pos.amount}"></td>
|
||||
<td> -</td>
|
||||
<td> -</td>
|
||||
</th:block>
|
||||
<td></td>
|
||||
</tr>
|
||||
</th:block>
|
||||
|
||||
</table>
|
||||
</p>
|
||||
|
|
|
@ -27,15 +27,16 @@
|
|||
<!-- Dirty -->
|
||||
<div style="min-width: 10rem; display: inline-block; margin: var(--u0);">
|
||||
<h3>Plätze in Verwendung</h3>
|
||||
<h2>67%</h2>
|
||||
<h2><span th:text="${#numbers.formatDecimal(stats.ratioUsedSlots * 100, 2, 'POINT', 2, 'COMMA')}"></span>%
|
||||
</h2>
|
||||
</div>
|
||||
<div style="min-width: 10rem; display: inline-block; margin: var(--u0);">
|
||||
<h3>Lagereffizienz</h3>
|
||||
<h2>43%</h2>
|
||||
<h2><span th:text="${#numbers.formatDecimal(stats.efficiency * 100, 2, 'POINT', 2, 'COMMA')}"></span>%</h2>
|
||||
</div>
|
||||
<div style="min-width: 10rem; display: inline-block; margin: var(--u0);">
|
||||
<h3>Lagerdiversität</h3>
|
||||
<h2>3</h2>
|
||||
<h2><span th:text="${stats.numArticles}"></span></h2>
|
||||
</div>
|
||||
<p>
|
||||
<table id="main-table">
|
||||
|
@ -52,47 +53,21 @@
|
|||
<th>Anzahl</th>
|
||||
<th>Max.</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><h2>#1</h2></td>
|
||||
<td><img th:src="@{/img/product-1.jpg}" class="s"/></td>
|
||||
<td><a th:href="@{/intern/listedArticles/45015}">Kamera</a></td>
|
||||
<td>20</td>
|
||||
<td>20</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><h2>#2</h2></td>
|
||||
<td><img th:src="@{/img/product-1.jpg}" class="s"/></td>
|
||||
<td><a th:href="@{/intern/listedArticles/45015}">Kamera</a></td>
|
||||
<td>1</td>
|
||||
<td>20</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><h2>#3</h2></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td>0</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><h2>#4</h2></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td>0</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><h2>#5</h2></td>
|
||||
<td><img th:src="@{/img/product-3.jpg}" class="s"/></td>
|
||||
<td><a th:href="@{/intern/listedArticles/45015}">Usb-Ding</a></td>
|
||||
<td>1</td>
|
||||
<td>10</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><h2>#6</h2></td>
|
||||
<td><img th:src="@{/img/product-4.jpg}" class="s"/></td>
|
||||
<td><a th:href="@{/intern/listedArticles/45015}">Stativ</a></td>
|
||||
<td>3</td>
|
||||
<td>5</td>
|
||||
<tr th:each="entry : ${entries}">
|
||||
<td><h3>#<span th:text="${entry.slot.slotNum}"></span></h3></td>
|
||||
<th:block th:if="${entry.newSumSlot > 0}">
|
||||
<td><img th:src="@{/shop/articles/{id}/image.jpg(id=${entry.article.id})}" class="xs"/></td>
|
||||
<td><a th:href="@{/intern/articles/{id}(id=${entry.article.id})}" th:text="${entry.article.title}"
|
||||
class="s"/></td>
|
||||
<td th:text="${entry.newSumSlot}"></td>
|
||||
<td th:text="${entry.article.warehouseUnitsPerSlot}"></td>
|
||||
</th:block>
|
||||
<th:block th:if="${entry.newSumSlot == 0}">
|
||||
<td></td>
|
||||
<td> -</td>
|
||||
<td> .</td>
|
||||
<td></td>
|
||||
</th:block>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
<main class="sidebar-layout content-width">
|
||||
<nav th:replace="fragments/intern :: sidebar"></nav>
|
||||
<div class="content-width">
|
||||
<h2 th:if="${bookings.size() == 0}">Es gibt keine offenen Lagerbuchungen!</h2>
|
||||
<p>
|
||||
<table id="main-table">
|
||||
<tr>
|
||||
|
@ -41,60 +42,66 @@
|
|||
<th>Status</th>
|
||||
</tr>
|
||||
|
||||
<th:block th:each="booking : ${bookings}">
|
||||
<tr th:data-group="${booking.id}">
|
||||
<td th:text="${booking.created.toString()}"></td>
|
||||
<td th:if="${booking.reason.isManuel}" colspan="4" class="l">
|
||||
Manuell:
|
||||
<pre th:text="${booking.reason.comment}"></pre>
|
||||
</td>
|
||||
<td th:if="${booking.reason.isStartBooking}" colspan="4" class="l">
|
||||
Startbuchung
|
||||
</td>
|
||||
<td th:if="${booking.reason.customerOrder != null}" colspan="4" class="l">
|
||||
<a th:href="${'/intern/customerOrders/' + booking.reason.customerOrder.id}">
|
||||
Bestellung: <span th:text="${booking.reason.customerOrder.id}"></span>
|
||||
</a>
|
||||
<pre th:text="${booking.reason.customerOrder.destination.toString()}"></pre>
|
||||
</td>
|
||||
<td th:if="${booking.reason.supplierOrder != null}" colspan="4" class="l">
|
||||
<a th:href="${'/intern/supplierOrders/#q=' + booking.reason.supplierOrder.id}">
|
||||
Lieferung: <span th:text="${booking.reason.supplierOrder.id}"></span>
|
||||
</a>
|
||||
</td>
|
||||
|
||||
<!-------------------------------------------------------------->
|
||||
<tr data-group="3">
|
||||
<td>2020-01-12 12:18</td>
|
||||
<td colspan="4" class="l">
|
||||
<a th:href="@{/intern/customerOrders/4808}">Bestellung 8408</a>
|
||||
<div>
|
||||
Hans Maier <br/>
|
||||
Hauptstraße 12<br/>
|
||||
74880 Musterstadt<br/>
|
||||
Deutschland <br/>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<form th:action="@{/intern/warehouse/progress/5410}" method="post">
|
||||
<button type="submit">Beginnen</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<tr data-group="3">
|
||||
<td><img th:src="@{/img/product-1.jpg}" class="s"/></td>
|
||||
<td><a th:href="@{/intern/listedArticles/45015}">Kamera</a></td>
|
||||
<td>1</td>
|
||||
<td><a th:href="@{/intern/warehouse/slots/#q=%231}">Lagerplatz 01</a></td>
|
||||
<td> -</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr data-group="3">
|
||||
<td><img th:src="@{/img/product-2.jpg}" class="s"/></td>
|
||||
<td><a th:href="@{/intern/listedArticles/4205}">Spielzeugauto</a></td>
|
||||
<td>2</td>
|
||||
<td><a th:href="@{/intern/warehouse/slots/#q=%232}">Lagerplatz 02</a></td>
|
||||
<td> -</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<!-------------------------------------------------------------->
|
||||
<tr data-group="2">
|
||||
<td>2020-01-12 12:15</td>
|
||||
<td colspan="4" class="l">
|
||||
Manuell: Ware war defekt.
|
||||
</td>
|
||||
<td><a class="secondary button">Abschließen</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr data-group="2">
|
||||
<td><img th:src="@{/img/product-1.jpg}" class="s"/></td>
|
||||
<td><a th:href="@{/intern/listedArticles/45015}">Kamera</a></td>
|
||||
<td>1</td>
|
||||
<td><a th:href="@{/intern/warehouse/slots/#q=%231}">Lagerplatz 01</a></td>
|
||||
<td> -</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<td th:if="${!booking.isInProgress}">
|
||||
<form th:action="${'/intern/warehouse/progress/' + booking.id}" method="post">
|
||||
<button type="submit">Beginnen</button>
|
||||
</form>
|
||||
</td>
|
||||
<td th:if="${booking.isInProgress}">
|
||||
<form th:action="${'/intern/warehouse/progress/' + booking.id}" method="get">
|
||||
<button class="secondary" type="submit">Abschließen</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr th:each="pos : ${booking.positions}" th:data-group="${booking.id}">
|
||||
<td><img th:src="@{/shop/articles/{id}/image.jpg(id=${pos.article.id})}" class="s"/></td>
|
||||
<td><a th:href="@{/intern/articles/{id}(id=${pos.article.id})}"
|
||||
th:text="${pos.article.title}"></a></td>
|
||||
<th:block th:if="${pos.amount > 0}">
|
||||
<td th:text="${pos.amount}"></td>
|
||||
<td> -</td>
|
||||
<td><a th:href="${'/intern/warehouse/slots/#q=%23' + pos.slotEntry.slot.slotNum}">Lagerplatz
|
||||
<span th:text="${pos.slotEntry.slot.slotNum}"></span> </a></td>
|
||||
<td></td>
|
||||
</th:block>
|
||||
<th:block th:if="${pos.amount < 0}">
|
||||
<td th:text="${pos.amount * -1}"></td>
|
||||
<td><a th:href="${'/intern/warehouse/slots/#q=%23' + pos.slotEntry.slot.slotNum}">Lagerplatz
|
||||
<span th:text="${pos.slotEntry.slot.slotNum}"></span> </a></td>
|
||||
<td> -</td>
|
||||
<td></td>
|
||||
</th:block>
|
||||
<th:block th:if="${pos.amount == 0}">
|
||||
<td th:text="${pos.amount}"></td>
|
||||
<td> -</td>
|
||||
<td> -</td>
|
||||
<td></td>
|
||||
</th:block>
|
||||
</tr>
|
||||
</th:block>
|
||||
</table>
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -1,97 +1,84 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="de" dir="ltr" xmlns:th="http://www.thymeleaf.org">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.75, user-scalable=no">
|
||||
|
||||
<title>Neuen Account erstellen</title>
|
||||
<link rel="stylesheet" th:href="@{/css/ecom.css}"/>
|
||||
|
||||
<script th:src="@{/js/scrollToContent.js}"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<nav th:replace="fragments/header :: header">Header</nav>
|
||||
<main class="modal">
|
||||
<form class="detailflex m" th:action="@{/register}" method="POST">
|
||||
<div>
|
||||
<h1>Neuen Account erstellen</h1>
|
||||
</div>
|
||||
<div>
|
||||
<h2> Login Daten </h2>
|
||||
</div>
|
||||
<div>
|
||||
<label for="username">Email Adresse</label>
|
||||
<input class="full-width" type="text" name="username" placeholder="Email Adresse" id="username" required>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="password">Passwort</label>
|
||||
<input class="full-width" type="password" name="password" placeholder="Passwort" id="password" required>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="password2">Passwort wiederholen</label>
|
||||
<input class="full-width" type="password" name="password2" placeholder="Passwort" id="password2" required>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2> Rechungs- und Lieferinformation </h2>
|
||||
</div>
|
||||
|
||||
<div class="col-2">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.75, user-scalable=no">
|
||||
<title>Neuen Account erstellen</title>
|
||||
<link rel="stylesheet" th:href="@{/css/ecom.css}"/>
|
||||
<script th:src="@{/js/scrollToContent.js}"></script>
|
||||
</head>
|
||||
<body>
|
||||
<nav th:replace="fragments/header :: header">Header</nav>
|
||||
<main class="modal">
|
||||
<form class="detailflex m" th:action="@{/register}" method="POST">
|
||||
<div>
|
||||
<label for="salutation">Anrede</label>
|
||||
<input class="full-width" list="salutationsOpt" name="salutation" id="salutation" placeholder="Anrede"
|
||||
required/>
|
||||
<datalist id="salutationsOpt">
|
||||
<option value="Herr">
|
||||
<option value="Frau">
|
||||
<option value="Herr Dr.">
|
||||
<option value="Frau Dr.">
|
||||
</datalist>
|
||||
<h1>Neuen Account erstellen</h1>
|
||||
</div>
|
||||
<div>
|
||||
<label for="name">Name</label>
|
||||
<input class="full-width" type="text" name="name" id="name" placeholder="Nachname Vorname" required/>
|
||||
<h2> Login Daten </h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<label for="username">Email Adresse</label>
|
||||
<input class="full-width" type="text" name="username" placeholder="Email Adresse" id="username" required>
|
||||
</div>
|
||||
<div>
|
||||
<label for="password">Passwort</label>
|
||||
<input class="full-width" type="password" name="password" placeholder="Passwort" id="password" required>
|
||||
</div>
|
||||
<div>
|
||||
<label for="password2">Passwort wiederholen</label>
|
||||
<input class="full-width" type="password" name="password2" placeholder="Passwort" id="password2" required>
|
||||
</div>
|
||||
<div>
|
||||
<h2> Rechungs- und Lieferinformation </h2>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<div>
|
||||
<label for="salutation">Anrede</label>
|
||||
<input class="full-width" list="salutationsOpt" name="salutation" id="salutation" placeholder="Anrede"
|
||||
required/>
|
||||
<datalist id="salutationsOpt">
|
||||
<option value="Herr">
|
||||
<option value="Frau">
|
||||
<option value="Herr Dr.">
|
||||
<option value="Frau Dr.">
|
||||
</datalist>
|
||||
</div>
|
||||
<div>
|
||||
<label for="name">Name</label>
|
||||
<input class="full-width" type="text" name="name" id="name" placeholder="Nachname Vorname" required/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label for="address">Anschrift</label>
|
||||
<textarea rows="5" class="full-width" type="text" name="address" id="address"
|
||||
placeholder="Optional: Zusatz Optional: Unternehmen Straße Hausnummer Postleitzeit Ort Land"></textarea>
|
||||
</div>
|
||||
<fieldset>
|
||||
<input type="radio" name="type" value="priv" id="type-priv" required>
|
||||
<label for="type-priv">Ich bin Privatkunde.</label> <br/>
|
||||
<input type="radio" name="type" value="bus" id="type-bus" required>
|
||||
<label for="type-bus">Ich bin Geschäftskunde.</label> <br/>
|
||||
</fieldset>
|
||||
|
||||
<div>
|
||||
<h2> Werbung </h2>
|
||||
</div>
|
||||
<div>
|
||||
placeholder="Optional: Zusatz Optional: Unternehmen Straße Hausnummer Postleitzeit Ort Land"></textarea>
|
||||
</div>
|
||||
<fieldset>
|
||||
<input type="radio" name="ad" value="y" id="ad-y" required>
|
||||
<label for="type-priv">Ich möchte Werbung erhalten.</label> <br/>
|
||||
<input type="radio" name="ad" value="n" id="ad-n" required>
|
||||
<label for="type-bus">Ich möchte keine Werbung erhalten.</label> <br/>
|
||||
<input type="radio" id="type-priv" name="type" value="priv">
|
||||
<label for="type-priv">Ich bin Privatkunde</label><br>
|
||||
<input type="radio" id="type-bus" name="type" value="bus">
|
||||
<label for="type-bus">Ich bin Geschäftskunde</label><br>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<h2> Werbung </h2>
|
||||
</div>
|
||||
<div>
|
||||
<fieldset>
|
||||
<input type="radio" id="ad-y" name="ad" value="y">
|
||||
<label for="ad-y">Ich möchte Werbung erhalten.</label><br>
|
||||
<input type="radio" id="ad-n" name="ad" value="n">
|
||||
<label for="ad-n">Ich möchte keine Werbung erhalten.</label><br>
|
||||
</fieldset>
|
||||
</div>
|
||||
<div>
|
||||
<button class="full-width" type="submit" name="action" value="login">Registeren</button>
|
||||
<a th:href="@{/terms}">
|
||||
Unsere AGBs finden sie hier.
|
||||
Unsere AGBs finden sie hier.
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</main>
|
||||
<footer th:replace="fragments/footer :: footer"></footer>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</div>
|
||||
</form>
|
||||
</main>
|
||||
<footer th:replace="fragments/footer :: footer"></footer>
|
||||
</body>
|
||||
</html>
|
|
@ -1,57 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="de" dir="ltr" xmlns:th="http://www.thymeleaf.org">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.75, user-scalable=no">
|
||||
|
||||
<title>Bonusprogramm</title>
|
||||
<link rel="stylesheet" th:href="@{/css/ecom.css}"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<nav th:replace="fragments/header :: header">Header</nav>
|
||||
|
||||
<div class="sidebar-layout content-width">
|
||||
<nav></nav>
|
||||
<div>
|
||||
<h1>Bonusprogramm</h1>
|
||||
</div>
|
||||
</div>
|
||||
<main class="sidebar-layout content-width">
|
||||
<nav th:replace="fragments/customer :: sidebar"></nav>
|
||||
<div class="content-width">
|
||||
<div class="grid xl">
|
||||
<div class="card">
|
||||
<h2> Ihr Bonuspunktestand beträgt: </h2>
|
||||
<h1 class="huge"> 15 </h1>
|
||||
</div>
|
||||
<div class="s">
|
||||
<h2> Bonuspunkte sichern </h2>
|
||||
<p>
|
||||
Sie sichern sich automatisch bei jedem Einkaufen pro Angefangenen
|
||||
10 EUR einen Bonuspunkt.
|
||||
</p>
|
||||
<p>
|
||||
Eine Übersicht ihrer Bonuspunkt finden sie hier auf dieser
|
||||
Bonus.
|
||||
</p>
|
||||
<p>
|
||||
Um die Bonuspunkte einzulösen hacken sie einfach
|
||||
"Bonuspunkte" verwenden beim Abschließen der Bestellung
|
||||
an. Für jeden Bonuspunkt wird ihnen 0,50 EUR gutgeschrieben.
|
||||
</p>
|
||||
</div>
|
||||
<div class="s">
|
||||
<img th:src="@{/img/undraw_gift.svg}"/>
|
||||
</div>
|
||||
<div class="spacer"></div>
|
||||
<div class="spacer"></div>
|
||||
<div class="spacer"></div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<footer th:replace="fragments/footer :: footer"></footer>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,92 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="de" dir="ltr" xmlns:th="http://www.thymeleaf.org">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.75, user-scalable=no">
|
||||
|
||||
<title>Meine Benachrichtigungen</title>
|
||||
<link rel="stylesheet" th:href="@{/css/ecom.css}"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<nav th:replace="fragments/header :: header">Header</nav>
|
||||
|
||||
<div class="sidebar-layout content-width">
|
||||
<nav></nav>
|
||||
<div>
|
||||
<h1>Meine Benachrichtigungen</h1>
|
||||
</div>
|
||||
</div>
|
||||
<main class="sidebar-layout content-width">
|
||||
<nav th:replace="fragments/customer :: sidebar"></nav>
|
||||
<div>
|
||||
<div class="grid xl">
|
||||
<section class="notification unread">
|
||||
<h2>Nachricht vom 17.08.2020, 14:38 Uhr</h2>
|
||||
<h3>Ihre Bestellung kommt voraussichtlich am Donnerstag, den 20.08.2020</h3>
|
||||
<p>
|
||||
Vielen Dank für Ihre Bestellung der folgenden Artikel:<br>
|
||||
<br>
|
||||
2x tolle Kamera<br>
|
||||
1x Bluetooth Kopfhörer<br>
|
||||
3x USB-Magic Light<br>
|
||||
<br>
|
||||
Die Sendung wird Ihnen voraussichtlich am Donnerstag, den 20.08.2020 zugestellt.
|
||||
Den aktuellen Status des Pakets können Sie jederzeit in der <a th:href="@{/shop/orders/}">Bestellübersicht</a>
|
||||
nachvollziehen.
|
||||
</p>
|
||||
<button type="button" name="button">Als gelesen makieren</button>
|
||||
</section>
|
||||
<section class="notification">
|
||||
<h2>Nachricht vom 15.08.2020, 16:38 Uhr</h2>
|
||||
<h3>Jetzt unsere Tagesangebote entdecken.</h3>
|
||||
<p>
|
||||
Entdecken sie jetzt unseren neusten Angebote:
|
||||
</p>
|
||||
<div class="flowflex">
|
||||
<div>
|
||||
<a th:href="@{/shop/articles/1234}" class="section">
|
||||
<h3>Lorem Ipsum</h3>
|
||||
<img th:src="@{/img/product-2.jpg}" class="s"/>
|
||||
<p>Nur 15,00 EUR</p>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<a th:href="@{/shop/articles/1234}" class="section">
|
||||
<h3>Stativ</h3>
|
||||
<img th:src="@{/img/product-4.jpg}" class="s"/>
|
||||
<p>Nur 7,00 EUR</p>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<a th:href="@{/shop/articles/1234}" class="section">
|
||||
<h3>Ersatzfernbedinung</h3>
|
||||
<img th:src="@{/img/product-6.jpg}" class="s"/>
|
||||
<p>Nur 17,00 EUR</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="notification">
|
||||
<h2>Nachricht vom 13.08.2020, 14:38 Uhr</h2>
|
||||
<h3>Ihre Bestellung ist angekommen.</h3>
|
||||
<p>
|
||||
Vielen Dank für Ihre Bestellung der folgenden Artikel:<br>
|
||||
<br>
|
||||
3x USB-Magic Light<br>
|
||||
<br>
|
||||
Ihre Bestellungen ist angekommen.
|
||||
</p>
|
||||
</section>
|
||||
<section class="spacer"></section>
|
||||
<section class="spacer"></section>
|
||||
<section class="spacer"></section>
|
||||
</div>
|
||||
</main>
|
||||
<footer th:replace="fragments/footer :: footer"></footer>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -21,30 +21,22 @@
|
|||
<main class="sidebar-layout content-width">
|
||||
<nav th:replace="fragments/customer :: sidebar"></nav>
|
||||
<div class="content-width detailflex">
|
||||
<div>
|
||||
<h2 id="20202701"> Bestellung vom 27.01.2020 </h2>
|
||||
<div th:each="order: ${orders}">
|
||||
<h2 id="20202701" th:text="|Bestellung vom ${order.formatCreated()}" />
|
||||
<div>
|
||||
<table class="key-value">
|
||||
<tr>
|
||||
<th>Lieferstatus</th>
|
||||
<td><b>Unterwegs</b> <br/> Vorraussichtliche Ankunft: 29.01.2020</td>
|
||||
<td th:if="${order.deliveredAt == null}"><b>Unterwegs</b> <br/> Vorraussichtliche Ankunft: <span th:text="${order.getEstimatedArrival()}" /></td>
|
||||
<td th:if="${order.deliveredAt != null}"><b>Angekommen</b> <br/> Ankunft: <span th:text="${order.formatDeliveredAt()}" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Sendeverfolgungsnummer</th>
|
||||
<td>XE51451436DE</td>
|
||||
<td th:text="${order.trackingId}"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th></th>
|
||||
<td>
|
||||
Hans Maier <br/>
|
||||
Hauptstraße 12<br/>
|
||||
74880 Musterstadt<br/>
|
||||
Deutschland <br/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Eingelösste Bonuspunkte</th>
|
||||
<td>10</td>
|
||||
<td th:text="${order.destination.toString()}" />
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
@ -55,17 +47,11 @@
|
|||
<th>Menge</th>
|
||||
<th>Preis (Brutto)</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a th:href="@{/shop/articles/4151}"><img th:src="@{/img/product-1.jpg}" class="s"/><a></td>
|
||||
<td><a th:href="@{/shop/articles/4151}">Kamera<a/></td>
|
||||
<td> 1</td>
|
||||
<td>100,50 EUR</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a th:href="@{/shop/articles/4151}"><img th:src="@{/img/product-2.jpg}" class="s"/><a/></td>
|
||||
<td><a th:href="@{/shop/articles/4151}">Earbuds<a/></td>
|
||||
<td> 3</td>
|
||||
<td>63,95 EUR</td>
|
||||
<tr th:each="position: ${order.positions}">
|
||||
<td><a th:href="@{/shop/articles/{id}(id = ${position.article.id})}"><img th:src="@{/shop/articles/{id}/image.jpg(id=${position.article.id})}" class="s"/></a></td>
|
||||
<td><a th:href="@{/shop/articles/{id}(id = ${position.article.id})}" th:text="${position.article.title}" class="s"></a></td>
|
||||
<td th:text="${position.quantity}" />
|
||||
<td th:text="${#numbers.formatDecimal(position.getSumPrice() * 0.01, 1, 'POINT', 2, 'COMMA')}" />
|
||||
</tr>
|
||||
<tr>
|
||||
<th></th>
|
||||
|
@ -77,19 +63,13 @@
|
|||
<td></td>
|
||||
<td></td>
|
||||
<td>Artikel (Netto)</td>
|
||||
<td> 120,00 EUR</td>
|
||||
<td th:text="${#numbers.formatDecimal(order.totalNetCent * 0.01, 1, 'POINT', 2, 'COMMA')}" />
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td>Bonuspunkte</td>
|
||||
<td> 5,00 EUR</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td>Umsatzsteuer (19%)</td>
|
||||
<td> 42,00 EUR</td>
|
||||
<td>Umsatzsteuer</td>
|
||||
<td th:text="${#numbers.formatDecimal(order.totalVatCent * 0.01, 1, 'POINT', 2, 'COMMA')}" />
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
|
@ -98,89 +78,7 @@
|
|||
<h3>Gesammtpreis</h3>
|
||||
</td>
|
||||
<td>
|
||||
<h3>240,79 EUR</h3>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div>
|
||||
<h2 id="20200101"> Bestellung vom 01.01.2020 </h2>
|
||||
<div>
|
||||
<table class="key-value">
|
||||
<tr>
|
||||
<th>Lieferstatus</th>
|
||||
<td><b>Angekommen</b> <br/> 03.01.2020</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Sendeverfolgungsnummer</th>
|
||||
<td>XE5140684351DE</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th></th>
|
||||
<td>
|
||||
Hans Maier <br/>
|
||||
Hauptstraße 12<br/>
|
||||
74880 Musterstadt<br/>
|
||||
Deutschland <br/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Gutgeschriebene Bonuspunkte</th>
|
||||
<td>5</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Bild</th>
|
||||
<th>Name</th>
|
||||
<th>Menge</th>
|
||||
<th>Preis pro Artikel (Brutto)</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a th:href="@{/shop/articles/4151}"><img th:src="@{/img/product-1.jpg}" class="s"/><a></td>
|
||||
<td><a th:href="@{/shop/articles/4151}"> Billige Kamera<a/></td>
|
||||
<td> 1</td>
|
||||
<td>40,50 EUR</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a th:href="@{/shop/articles/4151}"><img th:src="@{/img/product-5.jpg}" class="s"/><a></td>
|
||||
<td><a th:href="@{/shop/articles/4151}">Apfel<a/></td>
|
||||
<td> 5</td>
|
||||
<td>1,00 EUR</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th>Position</th>
|
||||
<th>Preis</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td>Artikel (Netto)</td>
|
||||
<td> 20,00 EUR</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td>Umsatzsteuer (19%)</td>
|
||||
<td> 5,00 EUR</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td>Umsatzsteuer (7%)</td>
|
||||
<td> 2,00 EUR</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td>
|
||||
<h3>Gesammtpreis</h3>
|
||||
</td>
|
||||
<td>
|
||||
<h3>50,79 EUR</h3>
|
||||
<h3 th:text="${#numbers.formatDecimal(order.totalGrossCent * 0.01, 1, 'POINT', 2, 'COMMA')}"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
|
@ -21,19 +21,19 @@
|
|||
<main class="sidebar-layout content-width">
|
||||
<nav th:replace="fragments/customer :: sidebar"></nav>
|
||||
<div class="content-width">
|
||||
<form class="detailflex">
|
||||
<form method="POST" th:action="@{/user/settings/changeMail}">
|
||||
<div>
|
||||
<h2> Login Daten </h2>
|
||||
</div>
|
||||
<div>
|
||||
<div class="input-icon">
|
||||
<input class="full-width" type="text" name="email" value="max.mueller@example.com" required/>
|
||||
<input class="full-width" type="text" name="email" th:value="${user.email}" required/>
|
||||
<button> Email-Adresse ändern</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form class="detailflex">
|
||||
<form class="detailflex" method="POST" th:action="@{/user/settings/changePwd}">
|
||||
<div>
|
||||
<h2> Sicherheit </h2>
|
||||
</div>
|
||||
|
@ -42,8 +42,8 @@
|
|||
<input class="full-width" type="password" name="old-password" placeholder="Passwort" id="password"
|
||||
required>
|
||||
|
||||
<label for="password">Neues Passwort</label>
|
||||
<input class="full-width" type="password" name="password" placeholder="Passwort" id="password" required>
|
||||
<label for="password1">Neues Passwort</label>
|
||||
<input class="full-width" type="password" name="password1" placeholder="Passwort" id="password1" required>
|
||||
<label for="password2">Neues Passwort wiederholen</label>
|
||||
<input class="full-width" type="password" name="password2" placeholder="Passwort" id="password2"
|
||||
required>
|
||||
|
@ -51,7 +51,7 @@
|
|||
</div>
|
||||
</form>
|
||||
|
||||
<form class="detailflex">
|
||||
<form class="detailflex" method="POST" th:action="@{/user/settings/changeAddress}">
|
||||
<div>
|
||||
<h2> Rechungs- und Lieferinformation </h2>
|
||||
</div>
|
||||
|
@ -59,7 +59,7 @@
|
|||
<div class="col-2">
|
||||
<div>
|
||||
<label for="salutation">Anrede</label>
|
||||
<input class="full-width" list="salutationsOpt" name="salutation" placeholder="Anrede" value="Herr"
|
||||
<input class="full-width" list="salutationsOpt" name="salutation" id="salutation" placeholder="Anrede" th:value="${user.salutation}"
|
||||
required/>
|
||||
<datalist id="salutationsOpt">
|
||||
<option value="Herr">
|
||||
|
@ -70,52 +70,28 @@
|
|||
</div>
|
||||
<div>
|
||||
<label for="name">Name</label>
|
||||
<input class="full-width" type="text" name="name" placeholder="Nachname Vorname" value="Max Müller"
|
||||
<input class="full-width" type="text" name="name" id="name" placeholder="Nachname Vorname" th:value="${user.name}"
|
||||
required/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="address">Anschrift</label>
|
||||
<textarea rows="5" class="full-width" type="text" name="address"
|
||||
placeholder="Optional: Zusatz Optional: Unternehmen Straße Hausnummer Postleitzeit Ort Land">
|
||||
Musterstraße 26
|
||||
7158 Mustertal
|
||||
Deutschland</textarea>
|
||||
<textarea rows="5" class="full-width" type="text" name="address" id="address"
|
||||
placeholder="Optional: Zusatz Optional: Unternehmen Straße Hausnummer Postleitzeit Ort Land" th:text="${user.defaultDeliveryAddress.addressString}"/>
|
||||
</div>
|
||||
<fieldset>
|
||||
<input type="radio" name="type" value="priv" id="type-priv" required checked>
|
||||
<label for="type-priv">Ich bin Privatkunde.</label> <br/>
|
||||
<input type="radio" name="type" value="bus" id="type-bus" required>
|
||||
<label for="type-bus">Ich bin Geschäftskunde.</label> <br/>
|
||||
</fieldset>
|
||||
<div>
|
||||
<button> Lieferinformation ändern</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form class="detailflex">
|
||||
<div>
|
||||
<h2> Werbung </h2>
|
||||
</div>
|
||||
<div>
|
||||
<fieldset>
|
||||
<input type="radio" name="ad" value="y" id="ad-y" required checked>
|
||||
<label for="type-priv">Ich möchte Werbung erhalten.</label> <br/>
|
||||
<input type="radio" name="ad" value="n" id="ad-n" required>
|
||||
<label for="type-bus">Ich möchte keine Werbung erhalten.</label> <br/>
|
||||
</fieldset>
|
||||
<button type="submit"> Speichern</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form class="detailflex">
|
||||
<form class="detailflex" method="POST" th:action="@{/user/settings/changePaymentInfo}">
|
||||
<div>
|
||||
<h2> Zahlungsinformation</h2>
|
||||
</div>
|
||||
<div>
|
||||
<div class="input-icon">
|
||||
<input class="full-width" type="text" name="payment-card" placeholder="XXXXXXXX840" required/>
|
||||
<input class="full-width" type="text" name="creditCardNumber" th:value="${user.defaultPayment.creditCardNumber}"/>
|
||||
<button> Kreditkartennummer ändern</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -62,10 +62,15 @@ public class RequestController {
|
|||
}
|
||||
|
||||
int priceNet = a.pricePerUnitNet * order.quantity;
|
||||
int discount = 0;
|
||||
if(dailyVolume >= s.discount.minimumDailySalesVolumeNetCent) {
|
||||
discount = (priceNet * s.discount.percentDiscount) / 100;
|
||||
int discountableNetAmount = 0;
|
||||
if (dailyVolume >= s.discount.minimumDailySalesVolumeNetCent) {
|
||||
// grant discount on the full price
|
||||
discountableNetAmount = priceNet;
|
||||
} else if (dailyVolume + priceNet > s.discount.minimumDailySalesVolumeNetCent) {
|
||||
// grant partial discount
|
||||
discountableNetAmount = dailyVolume + priceNet - s.discount.minimumDailySalesVolumeNetCent;
|
||||
}
|
||||
int discount = (discountableNetAmount * s.discount.percentDiscount) / 100;
|
||||
|
||||
OrderConfirmation confirmation = new OrderConfirmation();
|
||||
confirmation.articleNumber = order.articleNumber;
|
||||
|
|
Reference in New Issue