feature/basic_functions #7
2
.gitignore
vendored
@ -89,3 +89,5 @@ local.properties
|
||||
|
||||
# SQLite
|
||||
prototype/*.db
|
||||
|
||||
prototype/images
|
||||
|
2
prototype/.gitignore
vendored
@ -1,4 +1,4 @@
|
||||
./test.db
|
||||
e-commerce.db
|
||||
./build
|
||||
./gradle
|
||||
./out
|
||||
|
6
prototype/scripts/addarticles.sql
Normal file
@ -0,0 +1,6 @@
|
||||
INSERT INTO article_offers ("manufacturer", "article_number", "vat_percent", "should_be_advertised")
|
||||
VALUES ("McDonalds", "1", 7, 1);
|
||||
|
||||
|
||||
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);
|
||||
|
@ -1,9 +1,9 @@
|
||||
/* password is 123 */
|
||||
INSERT INTO users ("created", "email", "password_hash", "gets_ads", "is_active", "is_employee", "isb2b")
|
||||
VALUES (datetime('now','localtime') ||'.0', "emp@ecom", "$2a$10$zFiqcePBmXHErD86vkI.vO1dnX20ezoVSM8xjGi59nktXYQv0o.fK", "0", "1", "1", "0");
|
||||
INSERT INTO users ("created", "email", "password_hash", "is_active", "is_employee")
|
||||
VALUES (datetime('now','localtime') ||'.0', "emp@ecom", "$2a$10$zFiqcePBmXHErD86vkI.vO1dnX20ezoVSM8xjGi59nktXYQv0o.fK", "1", "1");
|
||||
|
||||
INSERT INTO users ("created", "email", "password_hash", "gets_ads", "is_active", "is_employee", "isb2b")
|
||||
VALUES (datetime('now','localtime') ||'.0', "user@ecom", "$2a$10$zFiqcePBmXHErD86vkI.vO1dnX20ezoVSM8xjGi59nktXYQv0o.fK", "1", "1", "0", "0");
|
||||
INSERT INTO users ("created", "email", "password_hash", "is_active", "is_employee")
|
||||
VALUES (datetime('now','localtime') ||'.0', "user@ecom", "$2a$10$zFiqcePBmXHErD86vkI.vO1dnX20ezoVSM8xjGi59nktXYQv0o.fK", "1", "0");
|
||||
|
||||
INSERT INTO users ("created", "email", "password_hash", "gets_ads", "is_active", "is_employee", "isb2b")
|
||||
VALUES (datetime('now','localtime') ||'.0', "blocked@ecom", "$2a$10$zFiqcePBmXHErD86vkI.vO1dnX20ezoVSM8xjGi59nktXYQv0o.fK", "1", "0", "0", "0");
|
||||
INSERT INTO users ("created", "email", "password_hash", "is_active", "is_employee")
|
||||
VALUES (datetime('now','localtime') ||'.0', "blocked@ecom", "$2a$10$zFiqcePBmXHErD86vkI.vO1dnX20ezoVSM8xjGi59nktXYQv0o.fK", "0", "0");
|
@ -0,0 +1,30 @@
|
||||
package org.hso.ecommerce.action.booking;
|
||||
|
||||
import org.hso.ecommerce.entities.booking.Booking;
|
||||
import org.hso.ecommerce.entities.booking.BookingAccountEntry;
|
||||
import org.hso.ecommerce.entities.booking.BookingReason;
|
||||
|
||||
public class CreateBookingAction {
|
||||
|
||||
private Booking booking;
|
||||
|
||||
public CreateBookingAction(BookingAccountEntry source, BookingAccountEntry destination, BookingReason reason, int amountCent) {
|
||||
booking = new Booking();
|
||||
booking.reason = reason;
|
||||
booking.amountCent = amountCent;
|
||||
|
||||
assert source != null || destination != null;
|
||||
|
||||
if (source != null) {
|
||||
booking.source = source.copyAddAmount(-amountCent);
|
||||
}
|
||||
if (destination != null) {
|
||||
booking.destination = destination.copyAddAmount(amountCent);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Booking finish() {
|
||||
return booking;
|
||||
}
|
||||
}
|
@ -0,0 +1,195 @@
|
||||
package org.hso.ecommerce.action.shop;
|
||||
|
||||
import org.hso.ecommerce.action.booking.CreateBookingAction;
|
||||
import org.hso.ecommerce.entities.booking.*;
|
||||
import org.hso.ecommerce.entities.shop.Address;
|
||||
import org.hso.ecommerce.entities.shop.Article;
|
||||
import org.hso.ecommerce.entities.shop.CustomerOrder;
|
||||
import org.hso.ecommerce.entities.shop.CustomerOrderPosition;
|
||||
import org.hso.ecommerce.entities.user.User;
|
||||
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 CreateOrderAction {
|
||||
|
||||
private User user;
|
||||
Address destination;
|
||||
|
||||
private int expectedTotalGrossCent;
|
||||
|
||||
private int totalNetCent;
|
||||
private int totalVatCent;
|
||||
private PaymentMethod method;
|
||||
|
||||
private BookingAccountEntry latestUserBooking;
|
||||
private BookingAccountEntry latestVatBooking;
|
||||
private BookingAccountEntry latestMainBooking;
|
||||
|
||||
private List<OrderItem> orderItems = new ArrayList<>();
|
||||
|
||||
public CreateOrderAction(
|
||||
User user,
|
||||
int expectedTotalGrossCent,
|
||||
Address destination,
|
||||
PaymentMethod method,
|
||||
BookingAccountEntry latestUserBooking,
|
||||
BookingAccountEntry latestVatBooking,
|
||||
BookingAccountEntry latestMainBooking
|
||||
) {
|
||||
this.user = user;
|
||||
this.expectedTotalGrossCent = expectedTotalGrossCent;
|
||||
this.destination = destination;
|
||||
this.method = method;
|
||||
|
||||
this.latestUserBooking = latestUserBooking;
|
||||
assert latestUserBooking.userAccount.id == user.id;
|
||||
|
||||
this.latestVatBooking = latestVatBooking;
|
||||
assert latestVatBooking.isVATAccount;
|
||||
|
||||
this.latestMainBooking = latestMainBooking;
|
||||
assert latestMainBooking.isMainAccount;
|
||||
}
|
||||
|
||||
public void addArticle(Article article, int quantity, List<WarehouseBookingPositionSlotEntry> availableSlots) {
|
||||
for (WarehouseBookingPositionSlotEntry slot : availableSlots) {
|
||||
assert slot.article.id == article.id;
|
||||
}
|
||||
|
||||
orderItems.add(new OrderItem(article, availableSlots, quantity));
|
||||
|
||||
totalNetCent += article.shopPricePerUnitNetCent * quantity;
|
||||
totalVatCent += article.getVat() * quantity;
|
||||
}
|
||||
|
||||
|
||||
public Result finish() throws ArticleNotInStockException {
|
||||
CustomerOrder order = createOrder();
|
||||
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());
|
||||
|
||||
WarehouseBooking warehouseBooking = createWarehouseBooking(order);
|
||||
|
||||
return new Result(
|
||||
order,
|
||||
warehouseBooking,
|
||||
bookingList
|
||||
);
|
||||
}
|
||||
|
||||
private WarehouseBooking createWarehouseBooking(CustomerOrder order) throws ArticleNotInStockException {
|
||||
WarehouseBooking booking = new WarehouseBooking();
|
||||
booking.created = new Timestamp(new Date().getTime());
|
||||
booking.reason = new BookingReason(order);
|
||||
|
||||
for (OrderItem item : orderItems) {
|
||||
int needed = item.quantity;
|
||||
|
||||
for (WarehouseBookingPositionSlotEntry slot : item.availableSlots) {
|
||||
int remove = Math.min(slot.newSumSlot, needed);
|
||||
needed -= remove;
|
||||
|
||||
WarehouseBookingPosition bookingPosition = new WarehouseBookingPosition();
|
||||
|
||||
bookingPosition.article = item.article;
|
||||
bookingPosition.amount = -remove;
|
||||
bookingPosition.slotEntry = slot.copyAddAmount(-remove);
|
||||
bookingPosition.booking = booking;
|
||||
|
||||
booking.positions.add(bookingPosition);
|
||||
|
||||
if (needed == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (needed > 0) {
|
||||
throw new ArticleNotInStockException(item.article);
|
||||
}
|
||||
}
|
||||
|
||||
return booking;
|
||||
}
|
||||
|
||||
private CustomerPayment createPayment() {
|
||||
CustomerPayment payment = new CustomerPayment();
|
||||
payment.amountCent = totalNetCent + totalVatCent;
|
||||
payment.payment = method;
|
||||
return payment;
|
||||
}
|
||||
|
||||
|
||||
private CustomerOrder createOrder() {
|
||||
assert totalNetCent + totalVatCent == expectedTotalGrossCent;
|
||||
|
||||
CustomerOrder customerOrder = new CustomerOrder();
|
||||
customerOrder.customer = user;
|
||||
customerOrder.destination = destination;
|
||||
|
||||
for (OrderItem item : orderItems) {
|
||||
CustomerOrderPosition position = new CustomerOrderPosition();
|
||||
position.article = item.article;
|
||||
position.pricePerUnit = item.article.shopPricePerUnitNetCent;
|
||||
position.quantity = item.quantity;
|
||||
|
||||
position.order = customerOrder;
|
||||
|
||||
customerOrder.positions.add(position);
|
||||
}
|
||||
|
||||
customerOrder.created = new Timestamp(new Date().getTime());
|
||||
|
||||
customerOrder.totalNetCent = totalNetCent;
|
||||
customerOrder.totalVatCent = totalVatCent;
|
||||
customerOrder.totalGrossCent = totalNetCent + totalVatCent;
|
||||
|
||||
return customerOrder;
|
||||
}
|
||||
|
||||
public static class Result {
|
||||
public final CustomerOrder customerOrder;
|
||||
public final WarehouseBooking warehouseBooking;
|
||||
public final List<Booking> bookings;
|
||||
|
||||
Result(CustomerOrder customerOrder, WarehouseBooking warehouseBooking, List<Booking> bookings) {
|
||||
this.customerOrder = customerOrder;
|
||||
this.warehouseBooking = warehouseBooking;
|
||||
this.bookings = bookings;
|
||||
}
|
||||
}
|
||||
|
||||
private static class OrderItem {
|
||||
List<WarehouseBookingPositionSlotEntry> availableSlots;
|
||||
int quantity;
|
||||
Article article;
|
||||
|
||||
public OrderItem(Article article, List<WarehouseBookingPositionSlotEntry> availableSlots, int quantity) {
|
||||
this.article = article;
|
||||
this.availableSlots = availableSlots;
|
||||
this.quantity = quantity;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ArticleNotInStockException extends Exception {
|
||||
private Article article;
|
||||
|
||||
public ArticleNotInStockException(Article article) {
|
||||
super("The quantity of article '" + article.title + "' is not in stock.");
|
||||
this.article = article;
|
||||
}
|
||||
|
||||
public Article getArticle() {
|
||||
return article;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package org.hso.ecommerce.action.shop;
|
||||
|
||||
import org.hso.ecommerce.entities.shop.CustomerOrder;
|
||||
|
||||
public class EnableTrackingAction {
|
||||
|
||||
public static void addTrackingInfo(CustomerOrder customerOrder) {
|
||||
// TODO:
|
||||
customerOrder.trackingId = "555-NASE";
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package org.hso.ecommerce.action.shop;
|
||||
|
||||
import org.hso.ecommerce.entities.shop.Article;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class GetRandomArticlesAction {
|
||||
|
||||
public static List<Article> getRandomArticles(int quantity, List<Article> advertisedArticles) {
|
||||
List<Article> randomisedArticles = new ArrayList<Article>();
|
||||
int loopcount = Math.min(quantity, advertisedArticles.size());
|
||||
Seil0
commented
Replace with Math.min? Replace with Math.min?
hhuber
commented
fixed fixed
|
||||
for (int i = 0; i < loopcount; i++) {
|
||||
int index = (int) (Math.random() * advertisedArticles.size());
|
||||
randomisedArticles.add(advertisedArticles.remove(index));
|
||||
}
|
||||
return randomisedArticles;
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package org.hso.ecommerce.action.somepackage;
|
||||
|
||||
public class DemoAction {
|
||||
// TODO: remove me.
|
||||
// mksubpackage
|
||||
|
||||
}
|
@ -3,6 +3,7 @@ package org.hso.ecommerce.app;
|
||||
import org.hso.ecommerce.components.ErrorDemoInterceptor;
|
||||
import org.hso.ecommerce.components.InfoDemoInterceptor;
|
||||
import org.hso.ecommerce.components.LoginIntercepter;
|
||||
import org.hso.ecommerce.components.ShoppingCartInterceptor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
@ -23,5 +24,7 @@ public class Config implements WebMvcConfigurer {
|
||||
registry.addInterceptor(buildLoginIntercepter());
|
||||
registry.addInterceptor(new ErrorDemoInterceptor());
|
||||
registry.addInterceptor(new InfoDemoInterceptor());
|
||||
registry.addInterceptor(new ShoppingCartInterceptor());
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
package org.hso.ecommerce.app;
|
||||
|
||||
import org.hso.ecommerce.repos.user.UserRepository;
|
||||
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.*;
|
||||
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;
|
||||
@ -22,11 +24,6 @@ public class RequestController {
|
||||
|
||||
static int notSoRandom = 0;
|
||||
|
||||
@GetMapping("/")
|
||||
public String home() {
|
||||
return "redirect:/shop/";
|
||||
}
|
||||
|
||||
@GetMapping("/login")
|
||||
public String login() {
|
||||
return "login";
|
||||
@ -43,7 +40,7 @@ public class RequestController {
|
||||
String gto = (String) session.getAttribute("afterLogin");
|
||||
|
||||
Optional<User> user = userRepository.findByEmail(username);
|
||||
if (user.isEmpty()) {
|
||||
if (!user.isPresent()) {
|
||||
request.setAttribute("error", "Email Adresse falsch.");
|
||||
response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
|
||||
return "login";
|
||||
@ -88,71 +85,11 @@ public class RequestController {
|
||||
return "redirect:/";
|
||||
}
|
||||
|
||||
@GetMapping("/shop/")
|
||||
public String shop() {
|
||||
return "shop/index";
|
||||
}
|
||||
|
||||
@GetMapping("/shop/search")
|
||||
public String shopSearch() {
|
||||
return "shop/search";
|
||||
}
|
||||
|
||||
@GetMapping("/shop/checkout")
|
||||
public String shopCheckout(HttpSession session, HttpServletRequest request) {
|
||||
session.setAttribute("afterLogin", request.getRequestURI());
|
||||
return "shop/checkout";
|
||||
}
|
||||
|
||||
@PostMapping("/shop/checkoutFinish")
|
||||
public String shopCheckoutFinish() {
|
||||
return "shop/checkoutFinish";
|
||||
}
|
||||
|
||||
@GetMapping("/shop/checkoutFinish")
|
||||
public String shopCheckoutFinishGET() {
|
||||
return "shop/checkoutFinish";
|
||||
}
|
||||
|
||||
@GetMapping("/shop/articles/{id}")
|
||||
public String shopArticlesById() {
|
||||
return "shop/articles/id";
|
||||
}
|
||||
|
||||
@PostMapping("/shop/articles/{id}")
|
||||
public String shopArticlesByIdBuy(HttpSession session,
|
||||
@RequestAttribute(value = "user", required = false) User customer,
|
||||
@PathVariable("id") Integer id,
|
||||
@RequestParam("fastcheckout") Boolean fastcheckout
|
||||
) {
|
||||
if (customer != null) {
|
||||
if (!fastcheckout) {
|
||||
return "shop/articles/post_add";
|
||||
} else {
|
||||
return "shop/checkout";
|
||||
}
|
||||
} else {
|
||||
session.setAttribute("afterLogin", "/shop/articles/" + id);
|
||||
return "redirect:/login";
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/about")
|
||||
public String about() {
|
||||
return "about";
|
||||
}
|
||||
|
||||
@GetMapping("/terms")
|
||||
public String terms() {
|
||||
return "terms";
|
||||
}
|
||||
|
||||
@GetMapping("/privacy")
|
||||
public String privacy() {
|
||||
return "privacy";
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/intern/")
|
||||
public String intern() {
|
||||
return "intern/index";
|
||||
|
@ -0,0 +1,43 @@
|
||||
package org.hso.ecommerce.components;
|
||||
|
||||
import org.hso.ecommerce.entities.shop.ShoppingCart;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
public class ShoppingCartInterceptor implements HandlerInterceptor {
|
||||
|
||||
@Override
|
||||
public boolean preHandle(
|
||||
HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
Seil0
commented
Laut Intellij werden die Exceptions nie geworfen. Laut Intellij werden die Exceptions nie geworfen.
CodeSteak
commented
Ist wegen dem Interface, die Methode ist dort so deklariert. Daher würde ich das gerne so lassen, zwecks Konsistenz Ist wegen dem Interface, die Methode ist dort so deklariert. Daher würde ich das gerne so lassen, zwecks Konsistenz
Seil0
commented
Ok Ok
|
||||
|
||||
HttpSession session = request.getSession();
|
||||
Object shoppingCart = session.getAttribute("shoppingCart");
|
||||
|
||||
if (shoppingCart == null) {
|
||||
shoppingCart = new ShoppingCart();
|
||||
}
|
||||
|
||||
request.setAttribute("shoppingCart", shoppingCart);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postHandle(
|
||||
HttpServletRequest request, HttpServletResponse response, Object handler,
|
||||
ModelAndView modelAndView) throws Exception {
|
||||
|
||||
HttpSession session = request.getSession();
|
||||
Object shoppingCart = request.getAttribute("shoppingCart");
|
||||
session.setAttribute("shoppingCart", shoppingCart);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
|
||||
Object handler, Exception exception) throws Exception {
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package org.hso.ecommerce.components;
|
||||
|
||||
import org.hso.ecommerce.entities.warehouse.Slot;
|
||||
import org.hso.ecommerce.repos.warehouse.SlotRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
@Component
|
||||
public class SlotInitializer {
|
||||
|
||||
@Autowired
|
||||
private final SlotRepository slotRepository = null;
|
||||
|
||||
// TODO: use values form cfg.
|
||||
private final int NUM_SLOTS = 50;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
for (int i = 1; i <= NUM_SLOTS; i++) {
|
||||
if (!slotRepository.findBySlotNum(i).isPresent()) {
|
||||
Slot slotAdded = new Slot();
|
||||
slotAdded.slotNum = i;
|
||||
slotRepository.save(slotAdded);
|
||||
|
||||
System.out.println("Added Slot " + i + " to DB");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,8 +1,103 @@
|
||||
package org.hso.ecommerce.controller.shop;
|
||||
|
||||
import org.apache.tomcat.util.http.fileupload.IOUtils;
|
||||
import org.hso.ecommerce.action.shop.GetRandomArticlesAction;
|
||||
import org.hso.ecommerce.entities.shop.Article;
|
||||
import org.hso.ecommerce.entities.shop.ShoppingCart;
|
||||
import org.hso.ecommerce.repos.shop.ArticleRepository;
|
||||
import org.hso.ecommerce.repos.warehouse.WarehouseBookingPositionSlotEntryRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
@Controller
|
||||
Seil0
commented
Unused Imports bitte entfernen. Unused Imports bitte entfernen.
|
||||
//@RequestMapping("...")
|
||||
@RequestMapping("/shop/articles")
|
||||
public class ShopArticleController {
|
||||
|
||||
@Autowired
|
||||
private final ArticleRepository articleRepository = null;
|
||||
|
||||
@Autowired
|
||||
private final WarehouseBookingPositionSlotEntryRepository warehouseBookingPositionSlotEntryRepository = null;
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public String shopArticlesById(Model model,
|
||||
@PathVariable("id") Long id,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response
|
||||
) {
|
||||
Article article = articleRepository.findArticleById(id);
|
||||
|
||||
if (article == null) {
|
||||
request.setAttribute("error", "Der Artikel wurde nicht gefunden.");
|
||||
Seil0
commented
Unnötige Leerzeilen entfernen. Unnötige Leerzeilen entfernen.
hhuber
commented
fixed fixed
|
||||
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
||||
return "error/404";
|
||||
}
|
||||
model.addAttribute("article", article);
|
||||
|
||||
//if (warehouseBookingPositionSlotEntryRepository.getByArticle(id).get(0).newSumSlot > 0) { //TODO: use this as soon as warehouse works
|
||||
if (true) {
|
||||
model.addAttribute("inStock", true);
|
||||
} else {
|
||||
model.addAttribute("inStock", false);
|
||||
}
|
||||
|
||||
List<Article> commercialArticles = GetRandomArticlesAction.getRandomArticles(3, articleRepository.getAdvertisedArticles());
|
||||
model.addAttribute("commercialArticles", commercialArticles);
|
||||
|
||||
return "shop/articles/id";
|
||||
}
|
||||
|
||||
@PostMapping("/{id}")
|
||||
public String shopArticlesByIdBuy(HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
HttpSession session,
|
||||
@RequestAttribute(value = "shoppingCart") ShoppingCart shoppingCart,
|
||||
@PathVariable("id") Long id,
|
||||
@RequestParam("quantity") Integer quantity,
|
||||
@RequestParam(value = "set_amount", required = false) Boolean setAmount,
|
||||
@RequestParam("fastcheckout") Boolean fastcheckout
|
||||
) {
|
||||
Article article = articleRepository.findArticleById(id);
|
||||
|
||||
if (article == null) {
|
||||
request.setAttribute("error", "Der Artikel wurde nicht gefunden.");
|
||||
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
||||
return "error/404";
|
||||
}
|
||||
|
||||
if (setAmount != null && setAmount) {
|
||||
shoppingCart.setArticleCount(article, quantity);
|
||||
} else {
|
||||
shoppingCart.addArticle(article, quantity);
|
||||
}
|
||||
|
||||
if (!fastcheckout) {
|
||||
return "shop/articles/post_add";
|
||||
} else {
|
||||
return "redirect:/shop/checkout";
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/{id}/image.jpg")
|
||||
public void getImageAsByteArray(HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
@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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,160 @@
|
||||
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;
|
||||
import org.hso.ecommerce.entities.shop.Article;
|
||||
import org.hso.ecommerce.entities.shop.ShoppingCart;
|
||||
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.user.UserRepository;
|
||||
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.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.util.ArrayList;
|
||||
import java.util.TreeMap;
|
||||
|
||||
@Controller
|
||||
//@RequestMapping("...")
|
||||
@RequestMapping("/shop/")
|
||||
public class ShopCheckoutController {
|
||||
|
||||
@Autowired
|
||||
private final UserRepository userRepository = null;
|
||||
|
||||
@Autowired
|
||||
private final ArticleRepository articleRepository = null;
|
||||
|
||||
@Autowired
|
||||
private final BookingAccountEntryRepository bookingEntryRepository = null;
|
||||
|
||||
@Autowired
|
||||
private final BookingRepository bookingRepository = null;
|
||||
|
||||
@Autowired
|
||||
private final WarehouseBookingRepository warehouseBookingRepository = null;
|
||||
|
||||
@Autowired
|
||||
private final CustomerOderRepository customerOderRepository = null;
|
||||
|
||||
@Autowired
|
||||
private final WarehouseBookingPositionSlotEntryRepository wbeseRepo = null;
|
||||
|
||||
@GetMapping("/checkout")
|
||||
public String shopCheckout(HttpSession session,
|
||||
HttpServletRequest request,
|
||||
@RequestAttribute(value = "shoppingCart") ShoppingCart shoppingCart) {
|
||||
session.setAttribute("afterLogin", request.getRequestURI());
|
||||
|
||||
CheckoutListTotals totals = new CheckoutListTotals();
|
||||
ArrayList<CheckoutListItem> items = new ArrayList<>();
|
||||
for (ShoppingCart.ShoppingCartItem item : shoppingCart.getItems()) {
|
||||
Article article = articleRepository.findById(item.getArticleId()).get();
|
||||
|
||||
totals.addItem(article, item.getAmount());
|
||||
items.add(new CheckoutListItem(item.getAmount(), article));
|
||||
}
|
||||
|
||||
request.setAttribute("checkoutItems", items);
|
||||
request.setAttribute("checkoutTotals", totals);
|
||||
|
||||
return "shop/checkout";
|
||||
}
|
||||
|
||||
public static class CheckoutListTotals {
|
||||
public int net;
|
||||
public TreeMap<Integer, Integer> vatAmounts = new TreeMap<>();
|
||||
public int total;
|
||||
|
||||
void addItem(Article article, int amount) {
|
||||
net += article.shopPricePerUnitNetCent * amount;
|
||||
Integer vatPos = vatAmounts.getOrDefault(article.related.vatPercent, 0) + article.getVat() * amount;
|
||||
vatAmounts.put(article.related.vatPercent, vatPos);
|
||||
total += article.getPriceGross() * amount;
|
||||
}
|
||||
}
|
||||
|
||||
public static class CheckoutListItem {
|
||||
public int amount;
|
||||
public Article article;
|
||||
public int total;
|
||||
|
||||
public CheckoutListItem(int amount, Article article) {
|
||||
this.amount = amount;
|
||||
this.article = article;
|
||||
this.total = amount * article.getPriceGross();
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/checkoutFinish")
|
||||
public String shopCheckoutFinish(
|
||||
HttpSession session,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
@RequestAttribute(value = "user") User user,
|
||||
@RequestAttribute(value = "shoppingCart") ShoppingCart shoppingCart,
|
||||
@RequestParam("address") String address,
|
||||
@RequestParam("cardnumber") String cardnumber,
|
||||
@RequestParam("shopping_cart_revision") Integer cartRevision,
|
||||
@RequestParam("expected_total") Integer expectedPrice
|
||||
) {
|
||||
|
||||
if (shoppingCart.getRevision() != cartRevision) {
|
||||
request.setAttribute("error", "Der Warenkorb wurde zwischenzeitlich bearbeitet. Daher die Kaufvorgang nicht abgeschlossen werden. Bitte versuchen Sie es erneut.");
|
||||
response.setStatus(HttpServletResponse.SC_CONFLICT);
|
||||
return "shop/checkout";
|
||||
}
|
||||
|
||||
// Must be refetched for persitence.
|
||||
user = userRepository.findById(user.id).get();
|
||||
|
||||
CreateOrderAction action = new CreateOrderAction(
|
||||
user,
|
||||
expectedPrice,
|
||||
Address.fromString(address),
|
||||
PaymentMethod.fromCreditCarNumber(cardnumber),
|
||||
bookingEntryRepository.getByUser(user.id).orElse(BookingAccountEntry.newUser(user)),
|
||||
bookingEntryRepository.getByVat().orElse(BookingAccountEntry.newVat()),
|
||||
bookingEntryRepository.getByMain().orElse(BookingAccountEntry.newMain())
|
||||
);
|
||||
|
||||
for (ShoppingCart.ShoppingCartItem item : shoppingCart.getItems()) {
|
||||
Article article = articleRepository.findById(item.getArticleId()).get();
|
||||
action.addArticle(article, item.getAmount(), wbeseRepo.getByArticle(article.id));
|
||||
}
|
||||
|
||||
CreateOrderAction.Result result = null;
|
||||
try {
|
||||
result = action.finish();
|
||||
EnableTrackingAction.addTrackingInfo(result.customerOrder);
|
||||
|
||||
customerOderRepository.save(result.customerOrder);
|
||||
bookingRepository.saveAll(result.bookings);
|
||||
warehouseBookingRepository.save(result.warehouseBooking);
|
||||
|
||||
shoppingCart.clear();
|
||||
|
||||
} catch (CreateOrderAction.ArticleNotInStockException e) {
|
||||
request.setAttribute("error", "Der Artikel '" + e.getArticle().title + "' ist leider nicht mehr in ausreichender Menge verfügbar. Bitte passen Sie die Artikelmenge an.");
|
||||
return shopCheckout(session, request, shoppingCart);
|
||||
}
|
||||
|
||||
|
||||
return "shop/checkoutFinish";
|
||||
}
|
||||
|
||||
@GetMapping("/checkoutFinish")
|
||||
public String shopCheckoutFinishGET() {
|
||||
return "shop/checkoutFinish";
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,69 @@
|
||||
package org.hso.ecommerce.controller.shop;
|
||||
|
||||
import org.hso.ecommerce.action.shop.GetRandomArticlesAction;
|
||||
import org.hso.ecommerce.entities.shop.Article;
|
||||
import org.hso.ecommerce.repos.shop.ArticleRepository;
|
||||
Seil0
commented
Unused Import. Unused Import.
|
||||
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.HttpSession;
|
||||
import java.util.List;
|
||||
|
||||
@Controller
|
||||
//@RequestMapping("...")
|
||||
@RequestMapping("/")
|
||||
public class ShopIndexController {
|
||||
|
||||
@Autowired
|
||||
private final ArticleRepository articleRepository = null;
|
||||
|
||||
@GetMapping("/")
|
||||
public String home() {
|
||||
return "redirect:/shop/";
|
||||
}
|
||||
|
||||
@GetMapping("/shop/")
|
||||
public String shop(Model model, HttpSession session) {
|
||||
|
||||
List<Article> commercialArticles = GetRandomArticlesAction.getRandomArticles(8, articleRepository.getAdvertisedArticles());
|
||||
model.addAttribute("commercialArticles", commercialArticles);
|
||||
|
||||
boolean isLoggedIn = false;
|
||||
boolean hasOrders = false;
|
||||
|
||||
if (session != null && session.getAttribute("userId") != null) {
|
||||
long userId = (long) session.getAttribute("userId");
|
||||
isLoggedIn = true;
|
||||
|
||||
List<Article> suggestedArticles = articleRepository.getOrderedArticles(userId);
|
||||
suggestedArticles = suggestedArticles.size() > 3 ? suggestedArticles.subList(0, 4) : suggestedArticles; //only latest 4 articles
|
||||
if (suggestedArticles.size() > 0) {
|
||||
model.addAttribute("suggestedArticles", suggestedArticles);
|
||||
hasOrders = true;
|
||||
}
|
||||
}
|
||||
|
||||
model.addAttribute("isLoggedIn", isLoggedIn);
|
||||
model.addAttribute("hasOrders", hasOrders);
|
||||
|
||||
return "shop/index";
|
||||
}
|
||||
|
||||
@GetMapping("/about")
|
||||
public String about() {
|
||||
return "about";
|
||||
}
|
||||
|
||||
@GetMapping("/terms")
|
||||
public String terms() {
|
||||
return "terms";
|
||||
}
|
||||
|
||||
@GetMapping("/privacy")
|
||||
public String privacy() {
|
||||
return "privacy";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -14,12 +14,12 @@ public class Booking {
|
||||
// always >= 0
|
||||
public int amountCent;
|
||||
|
||||
@ManyToOne(optional = true)
|
||||
@ManyToOne(optional = true, cascade = CascadeType.ALL)
|
||||
public BookingAccountEntry source;
|
||||
|
||||
@ManyToOne(optional = true)
|
||||
@ManyToOne(optional = true, cascade = CascadeType.ALL)
|
||||
public BookingAccountEntry destination;
|
||||
|
||||
@OneToOne(optional = false)
|
||||
@OneToOne(optional = false, cascade = CascadeType.ALL)
|
||||
public BookingReason reason;
|
||||
}
|
||||
|
@ -16,13 +16,49 @@ public class BookingAccountEntry {
|
||||
|
||||
public int newSumCent;
|
||||
|
||||
@ManyToOne(optional = true)
|
||||
@ManyToOne(optional = true, cascade = CascadeType.ALL)
|
||||
public User userAccount;
|
||||
|
||||
@ManyToOne(optional = true)
|
||||
@ManyToOne(optional = true, cascade = CascadeType.ALL)
|
||||
public Supplier supplierAccount;
|
||||
|
||||
public boolean isMainAccount;
|
||||
public boolean isVATAccount;
|
||||
|
||||
public BookingAccountEntry copyAddAmount(int amountCent) {
|
||||
BookingAccountEntry e = new BookingAccountEntry();
|
||||
|
||||
e.userAccount = userAccount;
|
||||
e.supplierAccount = supplierAccount;
|
||||
e.isMainAccount = isMainAccount;
|
||||
e.isVATAccount = isVATAccount;
|
||||
|
||||
e.newSumCent = newSumCent + amountCent;
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
public static BookingAccountEntry newUser(User user) {
|
||||
BookingAccountEntry e = new BookingAccountEntry();
|
||||
e.userAccount = user;
|
||||
e.newSumCent = 0;
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
public static BookingAccountEntry newMain() {
|
||||
BookingAccountEntry e = new BookingAccountEntry();
|
||||
e.isMainAccount = true;
|
||||
e.newSumCent = 0;
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
public static BookingAccountEntry newVat() {
|
||||
BookingAccountEntry e = new BookingAccountEntry();
|
||||
e.isVATAccount = true;
|
||||
e.newSumCent = 0;
|
||||
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
@ -22,9 +22,21 @@ public class BookingReason {
|
||||
@ManyToOne(optional = true)
|
||||
public CustomerOrder customerOrder;
|
||||
|
||||
@ManyToOne(optional = true)
|
||||
@OneToOne(optional = true, cascade = CascadeType.ALL)
|
||||
public CustomerPayment customerPayment;
|
||||
|
||||
@ManyToOne(optional = true)
|
||||
public SupplierOrder supplierOrder;
|
||||
|
||||
// Default Constructor is needed for construction by ORM
|
||||
public BookingReason() {
|
||||
}
|
||||
|
||||
Seil0
commented
Das kann auch weg. Das kann auch weg.
CodeSteak
commented
Nope, ORM braucht nen leeren Konstruktor. Ich mach ein Kommentar drüber. Nope, ORM braucht nen leeren Konstruktor. Ich mach ein Kommentar drüber. 713c8ebe86faffcde94f076956bdc5d02fe3ddaa
Seil0
commented
Ich meinte auch das Semikolon. Ich meinte auch das Semikolon.
|
||||
public BookingReason(CustomerOrder order) {
|
||||
this.customerOrder = order;
|
||||
}
|
||||
|
||||
public BookingReason(CustomerPayment customerPayment) {
|
||||
this.customerPayment = customerPayment;
|
||||
}
|
||||
}
|
||||
|
@ -7,4 +7,11 @@ import javax.validation.constraints.NotNull;
|
||||
public class PaymentMethod {
|
||||
@NotNull
|
||||
public String creditCardNumber;
|
||||
|
||||
public static PaymentMethod fromCreditCarNumber(String cardnumber) {
|
||||
PaymentMethod m = new PaymentMethod();
|
||||
m.creditCardNumber = cardnumber;
|
||||
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,24 @@ import javax.persistence.Embeddable;
|
||||
|
||||
@Embeddable
|
||||
public class Address {
|
||||
public String name;
|
||||
public String addressString;
|
||||
public String name = "";
|
||||
public String addressString = "";
|
||||
public String country = "DE";
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name + "\n" + addressString;
|
||||
}
|
||||
|
||||
public static Address fromString(String addr) {
|
||||
Address a = new Address();
|
||||
|
||||
String[] arr = addr.split("\n", 2);
|
||||
a.name = arr[0];
|
||||
if (arr.length > 1) {
|
||||
a.addressString = arr[1];
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
@ -32,9 +32,18 @@ public class Article {
|
||||
public String description;
|
||||
|
||||
@OneToOne(optional = true)
|
||||
@Basic(fetch = FetchType.LAZY)
|
||||
public Image image;
|
||||
|
||||
@ManyToMany
|
||||
@JoinTable(name = "article_categories_bindings")
|
||||
public Set<Category> categories = new HashSet<>();
|
||||
|
||||
public int getVat() {
|
||||
return (shopPricePerUnitNetCent * related.vatPercent) / 100;
|
||||
}
|
||||
|
||||
public int getPriceGross() {
|
||||
return shopPricePerUnitNetCent + getVat();
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ public class CustomerOrder {
|
||||
|
||||
@OneToMany(
|
||||
targetEntity = CustomerOrderPosition.class,
|
||||
mappedBy = "order"
|
||||
mappedBy = "order", cascade = CascadeType.ALL
|
||||
)
|
||||
public List<CustomerOrderPosition> positions = new ArrayList<>();
|
||||
|
||||
|
@ -11,7 +11,5 @@ public class Image {
|
||||
@Basic
|
||||
public long id;
|
||||
|
||||
@Lob
|
||||
@Column(name = "data", columnDefinition = "BLOB", nullable = false)
|
||||
private byte[] data;
|
||||
public String path;
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
package org.hso.ecommerce.entities.shop;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
// Not a db entity. Just for session storage
|
||||
public class ShoppingCart {
|
||||
|
||||
private final static int MAX_ITEMS = 10;
|
||||
|
||||
private int revision;
|
||||
private ArrayList<ShoppingCartItem> items;
|
||||
|
||||
public ShoppingCart() {
|
||||
clear();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
items = new ArrayList<>();
|
||||
revision = (int) Math.round(Math.random() * 0xFFFF);
|
||||
}
|
||||
|
||||
public List<ShoppingCartItem> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
public int getItemCount() {
|
||||
int count = 0;
|
||||
|
||||
for (ShoppingCartItem i : items) {
|
||||
count += i.getAmount();
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public int getRevision() {
|
||||
return revision;
|
||||
}
|
||||
|
||||
public void addArticle(Article article, int quantity) {
|
||||
this.revision++;
|
||||
|
||||
for (ShoppingCartItem i : items) {
|
||||
if (i.getArticleId() == article.id) {
|
||||
i.addAmount(quantity);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
items.add(new ShoppingCartItem(quantity, article));
|
||||
}
|
||||
|
||||
public void setArticleCount(Article article, Integer quantity) {
|
||||
this.revision++;
|
||||
|
||||
boolean found = false;
|
||||
for (ShoppingCartItem i : items) {
|
||||
if (i.getArticleId() == article.id) {
|
||||
i.setAmount(quantity);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
items.add(new ShoppingCartItem(quantity, article));
|
||||
}
|
||||
|
||||
items.removeIf(i -> i.getAmount() <= 0);
|
||||
}
|
||||
|
||||
public static class ShoppingCartItem {
|
||||
private int amount;
|
||||
private final long articleId;
|
||||
|
||||
public ShoppingCartItem(int amount, Article article) {
|
||||
this.amount = amount;
|
||||
this.articleId = article.id;
|
||||
}
|
||||
|
||||
public int getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void addAmount(int amount) {
|
||||
this.amount += amount;
|
||||
if (this.amount > MAX_ITEMS) {
|
||||
this.amount = MAX_ITEMS;
|
||||
}
|
||||
}
|
||||
|
||||
public long getArticleId() {
|
||||
return articleId;
|
||||
}
|
||||
|
||||
public void setAmount(Integer amount) {
|
||||
this.amount = amount;
|
||||
if (this.amount > MAX_ITEMS) {
|
||||
this.amount = MAX_ITEMS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -19,4 +19,6 @@ public class ArticleOffer {
|
||||
public String articleNumber;
|
||||
|
||||
public int vatPercent;
|
||||
|
||||
public boolean shouldBeAdvertised;
|
||||
}
|
||||
|
@ -30,10 +30,10 @@ public class User {
|
||||
public boolean isEmployee;
|
||||
|
||||
@Embedded
|
||||
private Address defaultDeliveryAddress;
|
||||
public Address defaultDeliveryAddress;
|
||||
|
||||
@Embedded
|
||||
private PaymentMethod defaultPayment;
|
||||
public PaymentMethod defaultPayment;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
|
@ -0,0 +1,17 @@
|
||||
package org.hso.ecommerce.entities.warehouse;
|
||||
|
||||
import javax.persistence.*;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Entity
|
||||
@Table(name = "warehouse_slots")
|
||||
public class Slot {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Basic
|
||||
public long id;
|
||||
|
||||
@NotNull
|
||||
@Column(unique = true)
|
||||
public int slotNum;
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
package org.hso.ecommerce.entities.warehouse;
|
||||
|
||||
import org.hso.ecommerce.entities.booking.BookingReason;
|
||||
|
||||
import javax.persistence.*;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.ArrayList;
|
||||
@ -21,7 +23,11 @@ public class WarehouseBooking {
|
||||
public boolean isDone;
|
||||
|
||||
@OneToMany(
|
||||
mappedBy = "booking"
|
||||
mappedBy = "booking", cascade = CascadeType.ALL
|
||||
)
|
||||
public List<WarehouseBookingPosition> positions = new ArrayList<>();
|
||||
|
||||
// TODO FIX ME
|
||||
@OneToOne(optional = false, cascade = CascadeType.ALL)
|
||||
public BookingReason reason;
|
||||
}
|
||||
|
@ -23,10 +23,6 @@ public class WarehouseBookingPosition {
|
||||
|
||||
public int amount; // positive or negative
|
||||
|
||||
@ManyToOne(optional = true)
|
||||
public WarehouseBookingPositionSlotEntry source;
|
||||
|
||||
@ManyToOne(optional = true)
|
||||
public WarehouseBookingPositionSlotEntry destination;
|
||||
|
||||
@ManyToOne(optional = true, cascade = CascadeType.ALL)
|
||||
public WarehouseBookingPositionSlotEntry slotEntry;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package org.hso.ecommerce.entities.warehouse;
|
||||
import org.hso.ecommerce.entities.shop.Article;
|
||||
|
||||
import javax.persistence.*;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Entity
|
||||
@Table(name = "warehouse_booking_position_entries")
|
||||
@ -13,11 +14,28 @@ public class WarehouseBookingPositionSlotEntry {
|
||||
@Basic
|
||||
public long id;
|
||||
|
||||
@NotNull
|
||||
@ManyToOne
|
||||
public Article article;
|
||||
|
||||
public int newSumArticles;
|
||||
public int newSumWarehousePosition;
|
||||
@NotNull
|
||||
Seil0
commented
; > ' ; > '
CodeSteak
commented
removed removed bd2aeb63f6ea5a3c0d2f78cde2ff8f5691061f30
|
||||
public int newSumSlot;
|
||||
|
||||
public int slot;
|
||||
@NotNull
|
||||
@ManyToOne
|
||||
public Slot slot;
|
||||
|
||||
public WarehouseBookingPositionSlotEntry copyAddAmount(int amount) {
|
||||
WarehouseBookingPositionSlotEntry e = new WarehouseBookingPositionSlotEntry();
|
||||
|
||||
e.article = article;
|
||||
e.slot = slot;
|
||||
|
||||
e.newSumSlot = newSumSlot + amount;
|
||||
|
||||
assert e.article.warehouseUnitsPerSlot >= e.newSumSlot;
|
||||
assert e.newSumSlot >= 0;
|
||||
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
@ -23,4 +23,12 @@ public class WarehouseBookingReason {
|
||||
public CustomerOrder customerOrder;
|
||||
|
||||
public boolean isManuel;
|
||||
|
||||
// Default Constructor is needed for construction by ORM
|
||||
public WarehouseBookingReason() {
|
||||
}
|
||||
|
||||
public WarehouseBookingReason(CustomerOrder order) {
|
||||
this.customerOrder = order;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,25 @@
|
||||
package org.hso.ecommerce.repos.booking;
|
||||
|
||||
import org.hso.ecommerce.entities.booking.BookingAccountEntry;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
public interface BookingAccountEntryRepository extends JpaRepository<BookingAccountEntry, Long> {
|
||||
|
||||
@Query(value = "SELECT * FROM booking_account_entries as e WHERE e.user_account_id = :user ORDER BY e.id DESC LIMIT 1", nativeQuery = true)
|
||||
Optional<BookingAccountEntry> getByUser(Long user);
|
||||
|
||||
@Query(value = "SELECT * FROM booking_account_entries as e WHERE e.is_main_account = 1 ORDER BY e.id DESC LIMIT 1", nativeQuery = true)
|
||||
Optional<BookingAccountEntry> getByMain();
|
||||
|
||||
@Query(value = "SELECT * FROM booking_account_entries as e WHERE e.isvataccount = 1 ORDER BY e.id DESC LIMIT 1", nativeQuery = true)
|
||||
Optional<BookingAccountEntry> getByVat();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,12 @@
|
||||
package org.hso.ecommerce.repos.booking;
|
||||
|
||||
import org.hso.ecommerce.entities.booking.Booking;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface BookingRepository extends JpaRepository<Booking, Long> {
|
||||
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,27 @@
|
||||
package org.hso.ecommerce.repos.shop;
|
||||
|
||||
import org.hso.ecommerce.entities.shop.Article;
|
||||
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;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface ArticleRepository extends JpaRepository<Article, Long> {
|
||||
|
||||
@Query("SELECT a FROM Article a WHERE a.id = :articleId")
|
||||
Article findArticleById(@Param("articleId") long articleId);
|
||||
|
||||
|
||||
@Query("SELECT a FROM Article a JOIN a.related ao WHERE ao.shouldBeAdvertised = true")
|
||||
List<Article> getAdvertisedArticles();
|
||||
|
||||
|
||||
@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);
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,11 @@
|
||||
package org.hso.ecommerce.repos.shop;
|
||||
|
||||
import org.hso.ecommerce.entities.shop.CustomerOrder;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface CustomerOderRepository extends JpaRepository<CustomerOrder, Long> {
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,17 @@
|
||||
package org.hso.ecommerce.repos.warehouse;
|
||||
|
||||
import org.hso.ecommerce.entities.warehouse.Slot;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
public interface SlotRepository extends JpaRepository<Slot, Long> {
|
||||
|
||||
@Query("SELECT s FROM Slot s WHERE s.slotNum = :slotNum")
|
||||
Optional<Slot> findBySlotNum(int slotNum);
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package org.hso.ecommerce.repos.warehouse;
|
||||
|
||||
import org.hso.ecommerce.entities.warehouse.WarehouseBookingPositionSlotEntry;
|
||||
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 WarehouseBookingPositionSlotEntryRepository extends JpaRepository<WarehouseBookingPositionSlotEntry, Long> {
|
||||
|
||||
@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);
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,11 @@
|
||||
package org.hso.ecommerce.repos.warehouse;
|
||||
|
||||
import org.hso.ecommerce.entities.warehouse.WarehouseBooking;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface WarehouseBookingRepository extends JpaRepository<WarehouseBooking, Long> {
|
||||
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ spring.resources.cache.cachecontrol.maxAge=P0D
|
||||
# LOGGING
|
||||
logging.level.org.springframework.web=WARN
|
||||
# DATABASE
|
||||
spring.datasource.url=jdbc:sqlite:./test.db
|
||||
spring.datasource.url=jdbc:sqlite:./e-commerce.db
|
||||
spring.datasource.driverClassName=org.sqlite.JDBC
|
||||
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.SQLiteDialect
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
|
@ -1,7 +0,0 @@
|
||||
CREATE TABLE "customers" (
|
||||
"id" INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
"lastname" TEXT,
|
||||
"firstname" TEXT,
|
||||
"username" TEXT,
|
||||
"password" TEXT
|
||||
);
|
@ -1,277 +1,100 @@
|
||||
<svg id="mainImage_create" data-name="mainImage" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 171.2 81.5">
|
||||
<style id="svgStyle">
|
||||
@import url('https://fonts.googleapis.com/css?family=Merriweather');
|
||||
.changeColor {
|
||||
fill: #4f86ed;
|
||||
}
|
||||
|
||||
#title {
|
||||
font-size: 50%;
|
||||
font-family: 'Merriweather', serif;
|
||||
}
|
||||
|
||||
.cls-1 {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.cls-7 {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.cls-2 {
|
||||
fill: #fff;
|
||||
}
|
||||
|
||||
.cls-10,
|
||||
.cls-11,
|
||||
.cls-12,
|
||||
.cls-14,
|
||||
.cls-16,
|
||||
.cls-3 {
|
||||
fill: none;
|
||||
}
|
||||
|
||||
.cls-3 {
|
||||
stroke: #5c7690;
|
||||
}
|
||||
|
||||
.cls-10,
|
||||
.cls-11,
|
||||
.cls-12,
|
||||
.cls-3 {
|
||||
stroke-miterlimit: 10;
|
||||
}
|
||||
|
||||
.cls-14,
|
||||
.cls-15,
|
||||
.cls-16,
|
||||
.cls-3 {
|
||||
stroke-width: 0.5px;
|
||||
}
|
||||
|
||||
.cls-4 {
|
||||
fill: #ffe1d9;
|
||||
}
|
||||
|
||||
.cls-5 {
|
||||
fill: #ffcfbf;
|
||||
}
|
||||
|
||||
.cls-6 {
|
||||
fill: #fecbb6;
|
||||
}
|
||||
|
||||
.cls-9 {
|
||||
fill: #fecb02;
|
||||
}
|
||||
|
||||
.cls-10,
|
||||
.cls-12 {
|
||||
stroke: #d26f51;
|
||||
}
|
||||
|
||||
.cls-10,
|
||||
.cls-11 {
|
||||
stroke-width: 0.38px;
|
||||
}
|
||||
|
||||
.cls-11 {
|
||||
stroke: #000;
|
||||
}
|
||||
|
||||
.cls-12 {
|
||||
stroke-width: 0.19px;
|
||||
}
|
||||
|
||||
.cls-13 {
|
||||
opacity: 0.45;
|
||||
}
|
||||
|
||||
.cls-14,
|
||||
.cls-15,
|
||||
.cls-16 {
|
||||
stroke: #b0bec5;
|
||||
stroke-linejoin: round;
|
||||
}
|
||||
|
||||
.cls-15 {
|
||||
fill: #edf0f2;
|
||||
}
|
||||
|
||||
.cls-16 {
|
||||
stroke-linecap: round;
|
||||
}
|
||||
|
||||
.cls-17 {
|
||||
font-family: 'PT Sans', sans-serif;
|
||||
font-size: 49.87px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.cls-18 {
|
||||
fill: #fffdbb;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------
|
||||
SVG Animate
|
||||
---------------------------*/
|
||||
.earMove {
|
||||
transition: all ease-in-out 2s;
|
||||
transform-origin: 50% 50%;
|
||||
animation: earmove 1.5s linear infinite alternate;
|
||||
}
|
||||
|
||||
.faceMove {
|
||||
transition: all ease-in-out 2s;
|
||||
transform-origin: 50% 50%;
|
||||
animation: move 1.5s linear infinite alternate;
|
||||
}
|
||||
|
||||
.neckMove {
|
||||
transition: all ease-in-out 2s;
|
||||
transform-origin: 50% 50%;
|
||||
animation: neck 1.5s linear infinite alternate;
|
||||
}
|
||||
|
||||
|
||||
@keyframes earmove {
|
||||
0% {
|
||||
transform: translateX(-0.3px) translateY(0.6px);
|
||||
}
|
||||
30% {
|
||||
transform: translateX(-0.3px) translateY(0.6px);
|
||||
}
|
||||
|
||||
60% {
|
||||
transform: translateX(-0.7px) translateY(0px);
|
||||
}
|
||||
|
||||
70% {
|
||||
transform: translateX(-0.7px) translateY(-0.3px);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(-0.7px) translateY(-0.3px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes move {
|
||||
0% {
|
||||
transform: translateX(-0.3px) translateY(0.6px);
|
||||
}
|
||||
30% {
|
||||
transform: translateX(-0.3px) translateY(0.6px);
|
||||
}
|
||||
|
||||
60% {
|
||||
transform: translateX(2px) translateY(0px);
|
||||
}
|
||||
|
||||
70% {
|
||||
transform: translateX(2px) translateY(-0.3px);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(2px) translateY(-0.3px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes neck {
|
||||
0% {
|
||||
transform: translateY(0.7px);
|
||||
}
|
||||
50% {
|
||||
transform: translateY(0.7px);
|
||||
}
|
||||
100% {
|
||||
transform: translateY(0px);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<path id="c-1" class="changeColor cls-1"
|
||||
d="M46.62,52.5c5.78,4.9,21.14,8.4,39.19,8.4s33.41-3.5,39.19-8.4c-5.78-4.9-21.14-8.4-39.19-8.4S52.41,47.6,46.62,52.5Z"
|
||||
style="fill: rgb(0, 21, 255);"></path>
|
||||
<path class="cls-2"
|
||||
d="M99.73,47.71H68.65a7.13,7.13,0,0,0-7.13,7.13V60a152.58,152.58,0,0,0,24.3,1.83,157.87,157.87,0,0,0,21.05-1.35V54.84A7.13,7.13,0,0,0,99.73,47.71Z"></path>
|
||||
<path class="cls-3"
|
||||
d="M123.56,55.81C115,58.94,101.27,61,85.81,61c-26,0-47-5.71-47-12.76,0-3.45,5.05-6.58,13.25-8.88"></path>
|
||||
<path class="cls-3" d="M55.37,38.47a140,140,0,0,1,30.44-3c26,0,47,5.71,47,12.76,0,2.4-2.44,4.65-6.69,6.57"></path>
|
||||
<path class="cls-3" d="M53.41,38.95l.94-.24"></path>
|
||||
<path class="cls-4"
|
||||
d="M91.68,47.71l-.75-11.2L79.15,43.84l-1.69,3.87H75.79c0,3.36,3.76,6.08,8.4,6.08s8.4-2.72,8.4-6.08Z"></path>
|
||||
<path class="cls-5 neckMove"
|
||||
d="M78,46.53a27.19,27.19,0,0,0,6.41.82c3.1,0,7.11-2.19,7.11-2.19l-.42-6.2L79.15,43.84Z"></path>
|
||||
<polygon class="earMove" points="92.59 32.22 92.59 28.5 76.77 27.71 76.77 32.22 92.59 32.22"></polygon>
|
||||
<circle class="cls-6 earMove" cx="78.06" cy="34.04" r="2.47"></circle>
|
||||
<path class="cls-4"
|
||||
d="M81.74,57.06,60.63,49.72h0A6.72,6.72,0,1,0,57.7,62.49H93.25C93.25,56.78,81.74,57.06,81.74,57.06Z"></path>
|
||||
<path class="cls-4"
|
||||
d="M77.46,25H90.92a0,0,0,0,1,0,0V39.38a6.73,6.73,0,0,1-6.73,6.73h0a6.73,6.73,0,0,1-6.73-6.73V25A0,0,0,0,1,77.46,25Z"></path>
|
||||
<rect id="c-2" class="changeColor cls-7" x="74.82" y="26.48" width="19.14" height="2.45"
|
||||
transform="translate(1.29 -3.65) rotate(2.49)" style="fill: rgb(0, 21, 255);"></rect>
|
||||
<path id="c-3" class="changeColor cls-7"
|
||||
d="M84.36,18.69h.5a7.8,7.8,0,0,1,7.8,7.8v0a0,0,0,0,1,0,0H76.56a0,0,0,0,1,0,0v0A7.8,7.8,0,0,1,84.36,18.69Z"
|
||||
transform="translate(1.06 -3.66) rotate(2.49)" style="fill: rgb(0, 21, 255);"></path>
|
||||
<polygon id="c-4" class="changeColor cls-8"
|
||||
points="82.44 23.89 92.18 24.32 92.59 24.34 92.48 26.84 80.96 26.33 82.44 23.89"
|
||||
style="fill: rgb(0, 21, 255);"></polygon>
|
||||
<circle class="cls-9 faceMove" cx="78.72" cy="23.73" r="3.73"
|
||||
transform="translate(51.58 101.34) rotate(-87.51)"></circle>
|
||||
<circle class="cls-2 faceMove" cx="78.72" cy="23.73" r="2.36"
|
||||
transform="translate(51.58 101.34) rotate(-87.51)"></circle>
|
||||
<circle class="cls-4 earMove" cx="90.92" cy="34.04" r="2.47"></circle>
|
||||
<path class="cls-4"
|
||||
d="M112.2,53l-9.87-21.92-3-5.48-11.86-.22,7.42,3.35H91.55l5.82,4.58,2,22.26h0A6.72,6.72,0,1,0,112.2,53Z"></path>
|
||||
<ellipse class="faceMove" cx="80.09" cy="33.12" rx="0.53" ry="0.59"></ellipse>
|
||||
<ellipse class="faceMove" cx="86.34" cy="33.12" rx="0.53" ry="0.59"></ellipse>
|
||||
<polyline class="cls-10 faceMove" points="84.19 31.08 81.74 37.01 84.39 37.01"></polyline>
|
||||
<path class="cls-10 faceMove" d="M83.06,40.36a4,4,0,0,1,2.75-1"></path>
|
||||
<line class="cls-11 faceMove" x1="81.07" y1="30.33" x2="78.47" y2="30.58"></line>
|
||||
<line class="cls-11 faceMove" x1="86.34" y1="30.45" x2="88.15" y2="31.08"></line>
|
||||
<line class="cls-12" x1="106.86" y1="47.82" x2="110.99" y2="46.11"></line>
|
||||
<line class="cls-12" x1="107.43" y1="49.9" x2="111.55" y2="48.19"></line>
|
||||
<line class="cls-12" x1="107.99" y1="51.98" x2="112.11" y2="50.27"></line>
|
||||
<g class="cls-13">
|
||||
<rect class="cls-14" x="85.81" y="2.46" width="10.77" height="3.5"></rect>
|
||||
<rect class="cls-15" x="96.58" y="2.46" width="10.77" height="3.5"></rect>
|
||||
<rect class="cls-14" x="92.19" y="5.95" width="10.77" height="3.5"></rect>
|
||||
<line class="cls-16" x1="107.36" y1="5.95" x2="109.63" y2="5.95"></line>
|
||||
<line class="cls-16" x1="110.68" y1="5.95" x2="111.57" y2="5.95"></line>
|
||||
</g>
|
||||
<g class="cls-13">
|
||||
<rect class="cls-16" x="125" y="23.12" width="10.77" height="3.5"></rect>
|
||||
<rect class="cls-15" x="130.39" y="26.62" width="10.77" height="3.5"></rect>
|
||||
<rect class="cls-16" x="119.62" y="26.62" width="10.77" height="3.5"></rect>
|
||||
<line class="cls-16" x1="141.16" y1="26.62" x2="145.73" y2="26.62"></line>
|
||||
<line class="cls-16" x1="125" y1="23.12" x2="115.4" y2="23.12"></line>
|
||||
<line class="cls-16" x1="117.95" y1="26.62" x2="115.4" y2="26.62"></line>
|
||||
</g>
|
||||
<g class="cls-13">
|
||||
<rect class="cls-16" x="39.34" y="16.12" width="10.77" height="3.5"></rect>
|
||||
<rect class="cls-16" x="39.34" y="23.11" width="10.77" height="3.5"></rect>
|
||||
<rect class="cls-16" x="50.11" y="23.11" width="10.77" height="3.5"></rect>
|
||||
<rect class="cls-16" x="50.11" y="16.12" width="10.77" height="3.5"></rect>
|
||||
<rect class="cls-15" x="44" y="19.61" width="10.77" height="3.5"></rect>
|
||||
<rect class="cls-16" x="33.23" y="19.61" width="10.77" height="3.5"></rect>
|
||||
<line class="cls-16" x1="60.89" y1="19.61" x2="65.51" y2="19.61"></line>
|
||||
<line class="cls-16" x1="39.34" y1="16.12" x2="35.46" y2="16.12"></line>
|
||||
<line class="cls-16" x1="36.45" y1="26.61" x2="33.23" y2="26.61"></line>
|
||||
<line class="cls-16" x1="63.2" y1="23.11" x2="65.51" y2="23.11"></line>
|
||||
</g>
|
||||
<polyline class="cls-3" points="115.4 58.12 115.4 38.27 120.2 37.01"></polyline>
|
||||
<polyline class="cls-3" points="129.01 53.21 129.01 43.14 131.74 42.13"></polyline>
|
||||
<path class="cls-3" d="M115.4,42.13a53.27,53.27,0,0,1,8,2A42,42,0,0,1,129,47"></path>
|
||||
<path class="cls-3" d="M115.4,47.34a53.27,53.27,0,0,1,8,2A42,42,0,0,1,129,52.22"></path>
|
||||
<path class="cls-3" d="M115.4,52.56a53.27,53.27,0,0,1,8,2l1,.42"></path>
|
||||
<path class="cls-18 faceMove"
|
||||
d="M78.84,26.09l0-4.71L68.05,18.32a.91.91,0,0,0-.45-.13c-1.17,0-2.11,2.46-2.11,5.5s.95,5.5,2.11,5.5a.9.9,0,0,0,.44-.12Z"></path>
|
||||
<path class="cls-5" d="M57.7,62.49H93.25A3.67,3.67,0,0,0,92.92,61H53.43A6.69,6.69,0,0,0,57.7,62.49Z"></path>
|
||||
<path class="cls-12" d="M88.15,60.27s1.7.95,1.7,2.22"></path>
|
||||
<path class="cls-5" d="M101.81,61a6.68,6.68,0,0,0,8.51,0Z"></path>
|
||||
<polygon class="cls-5" points="90.92 30.25 77.46 29.69 77.46 28.64 90.92 29.22 90.92 30.25"></polygon>
|
||||
<text id="title" transform="matrix(1 0 0 1 44.7249 78)">Oops, Page not found</text>
|
||||
<svg id="fd59ce54-f850-4dfc-bc34-dd7d379d600e" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" width="1074.392"
|
||||
height="584.231" viewBox="0 0 1074.392 584.231">
|
||||
<title>page not found</title>
|
||||
<ellipse cx="540.64346" cy="549.3094" rx="527.5" ry="34.9216" fill="#f2f2f2"/>
|
||||
<path d="M583.47969,324.89424c-85.94407,0-147.651,55.13938-147.651,183.79791,0,145.813,61.70691,184.41057,147.651,184.41057s151.327-42.27352,151.327-184.41057C734.80664,356.75255,669.42376,324.89424,583.47969,324.89424Zm.56495,319.80837c-59.52686,0-90.62592-34.92288-90.62592-135.9163,0-89.11185,32.37209-136.10461,91.899-136.10461s91.899,30.86774,91.899,136.10461C677.21663,607.23367,643.5715,644.70261,584.04464,644.70261Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="#2f2e41"/>
|
||||
<path d="M384.36531,591.40121H348.831V486.76183A20.95585,20.95585,0,0,0,327.87517,465.806h-8.32638a20.95585,20.95585,0,0,0-20.95586,20.95585V591.40121H198.36285a11.96327,11.96327,0,0,1-10.57763-17.552l106.0824-200.78034A20.95585,20.95585,0,0,0,284.28724,344.33l-6.26231-2.9572a20.95585,20.95585,0,0,0-27.4293,9.07005L121.21416,592.4754a28.41578,28.41578,0,0,0-3.35584,13.39612v0a28.41583,28.41583,0,0,0,28.41584,28.41583H298.59293v66.16727a25.119,25.119,0,0,0,25.119,25.119h.00005a25.119,25.119,0,0,0,25.119-25.119V634.28739h35.53428a21.44307,21.44307,0,0,0,21.44307-21.44307v0A21.44307,21.44307,0,0,0,384.36531,591.40121Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="#16a085"/>
|
||||
<path d="M1042.36183,591.40121h-35.53428V486.76183A20.95585,20.95585,0,0,0,985.87169,465.806h-8.32638a20.95585,20.95585,0,0,0-20.95586,20.95585V591.40121H856.35937a11.96326,11.96326,0,0,1-10.57763-17.552L951.86413,373.06891A20.95586,20.95586,0,0,0,942.28376,344.33l-6.26231-2.9572a20.95586,20.95586,0,0,0-27.42931,9.07005L779.21068,592.4754a28.41578,28.41578,0,0,0-3.35584,13.39612v0a28.41583,28.41583,0,0,0,28.41583,28.41583H956.58945v66.16727a25.119,25.119,0,0,0,25.119,25.119h0a25.119,25.119,0,0,0,25.119-25.119V634.28739h35.53428a21.44307,21.44307,0,0,0,21.44307-21.44307v0A21.44307,21.44307,0,0,0,1042.36183,591.40121Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="#16a085"/>
|
||||
<path d="M394.16787,579.148H358.63358V474.50864a20.95585,20.95585,0,0,0-20.95585-20.95586h-8.32638a20.95586,20.95586,0,0,0-20.95586,20.95586V579.148H208.16541a11.96327,11.96327,0,0,1-10.57763-17.552L303.67017,360.81572a20.95586,20.95586,0,0,0-9.58037-28.73893l-6.26231-2.9572a20.95586,20.95586,0,0,0-27.42931,9.07L131.01672,580.2222a28.41582,28.41582,0,0,0-3.35584,13.39613v0a28.41583,28.41583,0,0,0,28.41583,28.41583H308.39549v66.16727a25.119,25.119,0,0,0,25.119,25.119h.00005a25.119,25.119,0,0,0,25.119-25.119V622.0342h35.53429a21.44307,21.44307,0,0,0,21.44307-21.44307v0A21.44307,21.44307,0,0,0,394.16787,579.148Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="none" stroke="#3f3d56" stroke-miterlimit="10"/>
|
||||
<path d="M1060.74162,579.148h-35.53428V474.50864a20.95586,20.95586,0,0,0-20.95586-20.95586H995.9251a20.95586,20.95586,0,0,0-20.95586,20.95586V579.148H874.73916a11.96327,11.96327,0,0,1-10.57763-17.552L970.24392,360.81572a20.95586,20.95586,0,0,0-9.58037-28.73893l-6.26231-2.9572a20.95586,20.95586,0,0,0-27.42931,9.07L797.59047,580.2222a28.41582,28.41582,0,0,0-3.35584,13.39613v0a28.41583,28.41583,0,0,0,28.41583,28.41583H974.96924v66.16727a25.119,25.119,0,0,0,25.119,25.119h0a25.119,25.119,0,0,0,25.119-25.119V622.0342h35.53428a21.44307,21.44307,0,0,0,21.44307-21.44307v0A21.44307,21.44307,0,0,0,1060.74162,579.148Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="none" stroke="#3f3d56" stroke-miterlimit="10"/>
|
||||
<path d="M603.0848,313.86637c-85.94407,0-147.651,55.13937-147.651,183.79791,0,145.813,61.70691,184.41057,147.651,184.41057s151.327-42.27352,151.327-184.41057C754.41175,345.72467,689.02887,313.86637,603.0848,313.86637Zm.565,319.80836c-59.52686,0-90.62592-34.92287-90.62592-135.91629,0-89.11185,32.37209-136.10461,91.899-136.10461s91.899,30.86774,91.899,136.10461C696.82174,596.20579,663.17661,633.67473,603.64975,633.67473Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="none" stroke="#3f3d56" stroke-miterlimit="10"/>
|
||||
<circle cx="471.14108" cy="18.25044" r="12.90118" fill="#2f2e41"/>
|
||||
<ellipse cx="502.60736" cy="46.88476" rx="36.18622" ry="46.88476" fill="#2f2e41"/>
|
||||
<path d="M565.66136,237.49419c-18.1276,0-33.1413-17.27052-35.77576-39.80484a60.9759,60.9759,0,0,0-.41046,7.07991c0,25.89373,16.20114,46.88476,36.18622,46.88476s36.18623-20.991,36.18623-46.88476a60.9759,60.9759,0,0,0-.41046-7.07991C598.80267,220.22367,583.789,237.49419,565.66136,237.49419Z"
|
||||
transform="translate(-63.054 -157.8845)" opacity="0.1"/>
|
||||
<path d="M639.29619,342.07326c-.77711,3.19345-4.12792,5.751-7.83881,7.53791-7.80188,3.75682-17.4253,4.87788-26.7597,5.25418a45.17622,45.17622,0,0,1-7.1445-.132,20.5371,20.5371,0,0,1-12.25052-5.63141,1.68086,1.68086,0,0,1,.04371-2.84388c4.9694-5.45888,13.2622-8.80605,21.61613-11.21609,6.3344-1.82743,17.3813-6.56089,24.29013-5.9221C637.94444,329.73864,640.2774,338.04112,639.29619,342.07326Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="#3f3d56"/>
|
||||
<path d="M639.29619,342.07326c-.77711,3.19345-4.12792,5.751-7.83881,7.53791-7.80188,3.75682-17.4253,4.87788-26.7597,5.25418a45.17622,45.17622,0,0,1-7.1445-.132,20.5371,20.5371,0,0,1-12.25052-5.63141,1.68086,1.68086,0,0,1,.04371-2.84388c4.9694-5.45888,13.2622-8.80605,21.61613-11.21609,6.3344-1.82743,17.3813-6.56089,24.29013-5.9221C637.94444,329.73864,640.2774,338.04112,639.29619,342.07326Z"
|
||||
transform="translate(-63.054 -157.8845)" opacity="0.1"/>
|
||||
<path d="M540.09786,318.2059a19.76967,19.76967,0,0,0-1.1987,15.07476,26.33914,26.33914,0,0,0,8.82921,12.49683c10.09467,8.09163,23.98784,9.20512,36.92477,9.09278a284.6495,284.6495,0,0,0,33.90525-2.32384,40.53788,40.53788,0,0,0,11.00143-2.55442c4.22242-1.82679,7.93282-5.17756,9.436-9.5257s.43625-9.67246-3.13383-12.57428c-3.13686-2.54969-7.46265-2.9004-11.49775-3.14289l-23.08764-1.38745c2.281-2.30839,5.31816-3.614,8.09586-5.29216,3.68523-2.22642,6.13358-5.96455,8.81312-9.33471a129.00143,129.00143,0,0,1,13.4386-13.817c.75138,4.31038,3.4782,7.8499,6.68733,10.824s6.90841,5.36845,10.2439,8.20013c8.0786,6.85838,13.89583,16.1669,22.39215,22.50043a43.82885,43.82885,0,0,0,16.04862-8.0122l-3.30209-5.98141a3.94,3.94,0,0,0-1.24459-1.55282c-.93465-.575-2.13975-.27872-3.225-.44144-2.90082-.435-4.16771-3.784-5.306-6.48737-3.12491-7.42173-9.108-13.17993-14.21783-19.40381a98.00854,98.00854,0,0,1-9.99577-14.72284c-1.71652-3.10162-3.288-6.33107-5.61746-9.00321s-5.59358-4.773-9.1385-4.78051c-3.13222-.00662-6.02122,1.58355-8.71422,3.18308a230.47679,230.47679,0,0,0-23.63018,16.09894c-3.94376,3.0617-7.86306,6.29645-12.48933,8.17393-1.94748.79035-4.00044,1.33052-5.86924,2.29223-3.27313,1.6844-5.75721,4.53435-8.43128,7.06415C566.27712,311.89225,553.219,317.73841,540.09786,318.2059Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="#3f3d56"/>
|
||||
<path d="M588.3737,253.98251a23.77444,23.77444,0,0,1-1.73379,8.03335,10.04492,10.04492,0,0,1-5.76772,5.57269,12.37513,12.37513,0,0,1-5.62306.18249,10.88232,10.88232,0,0,1-4.58151-1.56071c-2.16484-1.48837-3.24415-4.14413-3.63748-6.74325-.39333-2.596-.21714-5.24857-.46885-7.86342a42.94439,42.94439,0,0,0-1.202-6.25549c-.16993-.68282-.343-1.36248-.51294-2.04216-.16674-.67967-.33037-1.35935-.48141-2.039-.13847-.63878-.26745-1.28068-.37761-1.92574-.09123-.54436-.173-1.09189-.23285-1.64255a18.42329,18.42329,0,0,0-.80867-4.81118,14.60727,14.60727,0,0,0-1.68659-2.854c-.28635-.40906-.56326-.81811-.81815-1.24292a5.88984,5.88984,0,0,1-.97226-3.74763,3.286,3.286,0,0,1,.14788-.601c.02516-.07552.05347-.151.085-.2234A1.80187,1.80187,0,0,0,560.932,223.07a3.43341,3.43341,0,0,0-.14788-1.77783,11.31808,11.31808,0,0,0-.95974-2.28761c-.2643-.47829-1.16108-1.34046-1.16738-1.888-.0126-1.10132,2.13972-1.98867,3.01134-2.42291a16.79623,16.79623,0,0,1,8.59657-1.74323c1.90369.129,3.9679.71428,5.0189,2.30962.944,1.438.81807,3.30081,1.22085,4.97169a1.47068,1.47068,0,0,0,.29892.66393,1.34135,1.34135,0,0,0,.73948.33982,4.54948,4.54948,0,0,0,1.416.05666h.00315a2.93138,2.93138,0,0,0,.37128-.05351,4.957,4.957,0,0,0,2.03271-.8779q.58531-.15576,1.18-.25488a.25112.25112,0,0,0,.04725-.00945c1.57646,4.97482,1.781,10.30836,3.07111,15.37444.63874,2.52044,1.55442,5.00943,1.6834,7.60225.00945.11327.0126.2297.01575.34612.0189.83386-.04717,1.674-.0126,2.50472a6.981,6.981,0,0,0,.12591,1.1139,15.61121,15.61121,0,0,0,.52546,1.74325l.00945.02831c.05977.18251.11643.36817.16363.55381.03457.1353.06607.26747.09127.40277l.00311.00943A14.93754,14.93754,0,0,1,588.3737,253.98251Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="#fbbebe"/>
|
||||
<circle cx="503.23669" cy="44.99678" r="18.56511" fill="#fbbebe"/>
|
||||
<path d="M684.15711,304.03278a30.445,30.445,0,0,0-5.236-14.10317q.72216,4.29513,1.44748,8.58714a3.214,3.214,0,0,1-3.36688-1.03523,10.33663,10.33663,0,0,1-1.76529-3.27565,67.46571,67.46571,0,0,0-8.2095-14.73567c-11.81876-.98489-23.50223-5.88418-33.89555-11.59532-10.39643-5.708-20.12582-12.5519-30.38382-18.50217a43.57346,43.57346,0,0,0-5.54436-2.832c-3.20954-1.287-6.81242-1.95406-9.85526-3.46759-.2045-.1007-.409-.20767-.61043-.31781a12.57834,12.57834,0,0,1-1.94459-1.30584,10.34363,10.34363,0,0,1-.93139-.8559,20.35115,20.35115,0,0,1-3.55886-5.95341c-1.63308-3.61232-2.21524-7.97041-3.84517-11.58274a11.20292,11.20292,0,0,1,2.50156-1.76525h.00315c.13213-.06924.2643-.13532.39962-.19824a11.9404,11.9404,0,0,1,2.00437-.73317q.58531-.15576,1.18-.25488a.25112.25112,0,0,0,.04725-.00945,11.56564,11.56564,0,0,1,5.49085.43424c2.58652.87477,4.76711,2.62115,6.94148,4.27313a114.02006,114.02006,0,0,1,10.14787,8.04908c1.79357,1.718,3.4298,3.606,5.35868,5.16676a42.14393,42.14393,0,0,0,5.05662,3.35116q15.65613,9.32658,31.31525,18.65005c3.53365,2.1051,7.07046,4.21019,10.52553,6.438,5.24855,3.38578,10.30828,7.05474,15.36493,10.72057q4.46978,3.23787,8.93647,6.47889a9.72771,9.72771,0,0,1,2.533,2.3411,8.4724,8.4724,0,0,1,1.12337,3.433A31.3874,31.3874,0,0,1,684.15711,304.03278Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="#fbbebe"/>
|
||||
<path d="M592.97726,267.9441c-1.25235,5.61674-6.92888,9.012-9.89617,13.94586-3.68784,6.12335-2.18378,13.241-.79922,20.25484q-3.79485,3.27095-7.59285,6.54186c-1.39708,1.19886-2.79417,2.404-4.29827,3.46444a57.35064,57.35064,0,0,1-6.85966,3.93956q-3.3606,1.72752-6.72119,3.45814a32.1282,32.1282,0,0,1-6.57961,2.78793c-4.41473,1.13278-9.10318.33982-13.4707-.97232a6.08761,6.08761,0,0,1-1.47264-.601,2.39351,2.39351,0,0,1-.69854-.63248,3.91067,3.91067,0,0,1-.44365-2.53933c.44365-7.35052,2.24036-14.54686,4.03081-21.68971a85.2598,85.2598,0,0,1,3.84832-12.57708,85.0766,85.0766,0,0,1,5.41538-10.151,68.36751,68.36751,0,0,1,7.92948-11.51353,18.47881,18.47881,0,0,0,3.67525-4.73882c1.11706-2.54876.686-5.472.91252-8.24732a17.14844,17.14844,0,0,1,1.63312-6.0069v-.00315a17.09326,17.09326,0,0,1,1.74321-2.88232q.45788,1.06671.91568,2.13027.30209.69855.59783,1.394.38706.89679.7678,1.78728,1.09973,2.55823,2.19637,5.11327a21.58968,21.58968,0,0,0,3.33538,5.944,6.49923,6.49923,0,0,0,11.12337-.85275,21.26125,21.26125,0,0,0,2.27185-6.0132,19.21547,19.21547,0,0,0,.25175-7.83509c-.75835-5.00945-2.88862-10.12585-4.43678-14.77972a14.94511,14.94511,0,0,1-1.07927-4.871,3.35144,3.35144,0,0,1,.05662-.56011c.00945-.04719.0189-.09754.02834-.14473a11.9404,11.9404,0,0,1,2.00437-.73317q.58531-.15576,1.18-.25488,2.04378,11.06355,4.09377,22.12709c.0315.17307.0661.34613.09756.52234.19509,1.05726.39333,2.11454.61358,3.16865.19828.95657.41223,1.91.65137,2.85715l.00945.02831c.08182.321.16678.63877.2549.95658l.00311.00943c.2423.86848.5129,1.73065.81811,2.58024C590.93825,257.47528,594.16355,262.62946,592.97726,267.9441Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="#16a085"/>
|
||||
<path d="M668.32144,346.87707a6.58269,6.58269,0,0,0,.61,3.14328c1.16192,2.12353,3.94981,2.60625,6.36228,2.80484a188.37688,188.37688,0,0,0,42.2657-1.28774,4.88565,4.88565,0,0,0,2.15136-.66766c1.98985-1.39509.76329-4.7951-1.40951-5.88355s-4.75126-.82614-7.1353-1.29748a22.47912,22.47912,0,0,1-6.67794-2.89617q-7.25234-4.16669-14.293-8.68808c-2.79453-1.79464-6.09272-3.70993-9.23987-2.64587C672.43,332.34264,668.26533,337.68065,668.32144,346.87707Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="#3f3d56"/>
|
||||
<path d="M564.43732,240.87367v.00315c-.022.13215-.04406.26116-.07237.39018-.0346.214-.07551.43108-.11642.645-.39018,1.99812-.86847,3.98678-1.41913,5.96287-1.5104,5.45939-3.53366,10.83069-5.54121,16.12332q-8.08055,21.28692-16.16423,42.577c-1.35936,3.57457-2.71554,7.15228-4.26054,10.65448-.516,1.16741-1.04782,2.34424-1.57647,3.53368-1.89427,4.25737-3.713,8.65322-4.31716,13.18436a27.44976,27.44976,0,0,0-.19194,9.04027c.60416,2.97042,2.40718,5.8716,5.22969,6.96977,1.37823.53808,3.35113,1.25865,2.97355,2.69037-.2045.78665-1.09817,1.17055-1.90057,1.3027a7.31234,7.31234,0,0,1-5.966-1.718c-1.50725-1.33732-2.66518-3.41725-4.66959-3.64065-1.38767-.151-2.66518.67966-3.93643,1.26178-5.18564,2.36942-11.22719.71114-16.674-.9723.42794-2.20579,2.64318-3.65953,4.84267-4.10006,2.19949-.44367,4.47449-.129,6.718-.18879a3.50958,3.50958,0,0,0,2.04216-.52549,3.70545,3.70545,0,0,0,1.10132-1.88169,78.96356,78.96356,0,0,0,3.21273-13.14661c.7237-4.66645,1.02581-9.40527,2.05787-14.01507.80241-3.59661,2.0422-7.07991,3.10572-10.61044a224.68238,224.68238,0,0,0,5.0598-22.07674,78.02019,78.02019,0,0,0,1.42543-9.36751c.17935-2.6117.09438-5.236.34609-7.83826a60.8877,60.8877,0,0,1,2.11141-9.99683q1.44427-5.34769,2.88547-10.68911c1.42544-5.2706,2.95465-10.74572,6.567-14.84264a13.96159,13.96159,0,0,1,10.02834-4.78915,9.8819,9.8819,0,0,1,2.13027.22969c.11639.02831.23285.05664.34923.0881a8.63447,8.63447,0,0,1,2.17437.89995c1.11388-.708,1.68025-.45942,2.41974.63246a6.97319,6.97319,0,0,1,.88107,3.79485A52.42378,52.42378,0,0,1,564.43732,240.87367Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="#fbbebe"/>
|
||||
<path d="M565.66136,245.0461l-.0472.04719-.25486.25488-2.5299,2.52675-1.23976-5.20767-4.25109-17.854a9.8819,9.8819,0,0,1,2.13027.22969,3.286,3.286,0,0,1,.14788-.601l.20135.68911,1.44118,4.90245,2.72811,9.30773.45,1.53241v.00315Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="#16a085"/>
|
||||
<path d="M581.71523,188.0873a12.58165,12.58165,0,0,1-3.70049,8.89583,12.31392,12.31392,0,0,1-1.36008,1.17634,12.52812,12.52812,0,0,1-7.53567,2.52415H554.023a12.5902,12.5902,0,0,1,0-25.18037h15.096A12.62919,12.62919,0,0,1,581.71523,188.0873Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="#2f2e41"/>
|
||||
<circle cx="532.81499" cy="18.25044" r="12.90118" fill="#2f2e41"/>
|
||||
<path d="M595.55433,163.23377c-.15825,0-.31505.00628-.472.01193a12.89776,12.89776,0,0,1,0,25.77849c.15694.00565.31374.01193.472.01193a12.90117,12.90117,0,1,0,0-25.80235Z"
|
||||
transform="translate(-63.054 -157.8845)" opacity="0.1"/>
|
||||
<path d="M534.19508,163.23377c.15825,0,.31505.00628.472.01193a12.89776,12.89776,0,0,0,0,25.77849c-.157.00565-.31375.01193-.472.01193a12.90118,12.90118,0,0,1,0-25.80235Z"
|
||||
transform="translate(-63.054 -157.8845)" opacity="0.1"/>
|
||||
<path d="M576.65466,198.15947a12.52812,12.52812,0,0,1-7.53567,2.52415H554.023a12.52833,12.52833,0,0,1-7.53574-2.52415Z"
|
||||
transform="translate(-63.054 -157.8845)" opacity="0.1"/>
|
||||
<path d="M674.13958,291.64042s3.25228,9.37161,6.229,6.87633L677.996,286.26693Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="#fbbebe"/>
|
||||
<path d="M1069.91781,577.43414a20.81252,20.81252,0,1,0,2.7716-39.91524l.52093,10.7122-5.06814-9.18045a20.734,20.734,0,0,0-10.68367,11.72261,20.40847,20.40847,0,0,0-1.19713,5.62986A20.80856,20.80856,0,0,0,1069.91781,577.43414Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="#57b894"/>
|
||||
<path d="M1094.99516,701.67756c-1.78906-9.11027,5.9633-17.1868,13.62086-22.43651s16.605-10.40779,19.21775-19.31684c3.755-12.80387-7.43-24.52981-16.13564-34.64176a125.30044,125.30044,0,0,1-16.52359-24.55738c-1.81107-3.5325-3.47558-7.22528-3.95221-11.16626-.68641-5.67546,1.13693-11.32309,2.9739-16.73673q9.17925-27.05169,19.62843-53.65005"
|
||||
transform="translate(-63.054 -157.8845)" fill="none" stroke="#3f3d56" stroke-miterlimit="10"/>
|
||||
<path d="M1070.77493,574.6762a20.81252,20.81252,0,1,0,2.7716-39.91524l.52093,10.7122-5.06815-9.18045a20.734,20.734,0,0,0-10.68366,11.72261,20.40847,20.40847,0,0,0-1.19713,5.62986A20.80855,20.80855,0,0,0,1070.77493,574.6762Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="none" stroke="#3f3d56" stroke-miterlimit="10"/>
|
||||
<path d="M1092.45136,515.47266a20.78819,20.78819,0,0,1,14.97993-13.19764l1.71361,10.18378,3.177-10.69566a20.81,20.81,0,1,1-19.87057,13.70952Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="#57b894"/>
|
||||
<path d="M1093.59418,511.7954a20.7882,20.7882,0,0,1,14.97993-13.19763l1.71361,10.18378,3.177-10.69567a20.81,20.81,0,1,1-19.87057,13.70952Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="none" stroke="#3f3d56" stroke-miterlimit="10"/>
|
||||
<path d="M1108.04474,625.48885a20.81,20.81,0,0,0,18.419-37.02267l-2.44121,8.21926-1.73105-10.30382a.36183.36183,0,0,0-.053-.0201,20.81113,20.81113,0,1,0-14.1938,39.12733Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="#57b894"/>
|
||||
<path d="M1109.035,621.76417a20.81,20.81,0,0,0,18.419-37.02267l-2.44121,8.21926-1.73105-10.30382a.3621.3621,0,0,0-.053-.0201,20.81113,20.81113,0,1,0-14.1938,39.12733Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="none" stroke="#3f3d56" stroke-miterlimit="10"/>
|
||||
<path d="M1086.37782,660.05148a20.80131,20.80131,0,1,0,4.01058-16.29737l9.27267,13.95654-12.66994-7.40768A20.61638,20.61638,0,0,0,1086.37782,660.05148Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="#57b894"/>
|
||||
<path d="M1087.23494,657.29354a20.80131,20.80131,0,1,0,4.01058-16.29737l9.27267,13.95655-12.66994-7.40769A20.61626,20.61626,0,0,0,1087.23494,657.29354Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="none" stroke="#3f3d56" stroke-miterlimit="10"/>
|
||||
<path d="M72.06146,628.13325a13.67421,13.67421,0,1,0,1.821-26.225l.34227,7.03811-3.32987-6.03172a13.62263,13.62263,0,0,0-7.01936,7.702,13.40883,13.40883,0,0,0-.78654,3.69893A13.6716,13.6716,0,0,0,72.06146,628.13325Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="#57b894"/>
|
||||
<path d="M88.53774,709.76344c-1.17545-5.98561,3.918-11.292,8.94915-14.7412s10.90978-6.8381,12.62642-12.69151c2.46711-8.41238-4.88167-16.11653-10.60142-22.76027A82.32442,82.32442,0,0,1,88.6556,643.43581a22.20962,22.20962,0,0,1-2.59668-7.33643c-.451-3.72888.747-7.43947,1.95391-10.99634q6.03093-17.77346,12.89623-35.24906"
|
||||
transform="translate(-63.054 -157.8845)" fill="none" stroke="#3f3d56" stroke-miterlimit="10"/>
|
||||
<path d="M72.62461,626.32123a13.6742,13.6742,0,1,0,1.821-26.225l.34227,7.03812L71.458,601.10258a13.62262,13.62262,0,0,0-7.01936,7.702,13.40912,13.40912,0,0,0-.78654,3.69892A13.67158,13.67158,0,0,0,72.62461,626.32123Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="none" stroke="#3f3d56" stroke-miterlimit="10"/>
|
||||
<path d="M86.86641,587.42343a13.65822,13.65822,0,0,1,9.84209-8.67109l1.12587,6.69093,2.08737-7.02725a13.67252,13.67252,0,1,1-13.05533,9.00741Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="#57b894"/>
|
||||
<path d="M87.61727,585.0074a13.65822,13.65822,0,0,1,9.84209-8.67108l1.12587,6.69093L100.6726,576a13.67252,13.67252,0,1,1-13.05533,9.0074Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="none" stroke="#3f3d56" stroke-miterlimit="10"/>
|
||||
<path d="M97.11155,659.70607a13.67255,13.67255,0,0,0,12.10164-24.32457l-1.60392,5.4002-1.13733-6.76979a.238.238,0,0,0-.0348-.0132,13.67329,13.67329,0,1,0-9.32559,25.70736Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="#57b894"/>
|
||||
<path d="M97.76214,657.25889a13.67255,13.67255,0,0,0,12.10164-24.32457l-1.60392,5.4002-1.13733-6.7698a.238.238,0,0,0-.0348-.0132,13.67329,13.67329,0,1,0-9.32559,25.70737Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="none" stroke="#3f3d56" stroke-miterlimit="10"/>
|
||||
<path d="M82.876,682.41435a13.66684,13.66684,0,1,0,2.635-10.70767l6.09231,9.16971-8.32438-4.867A13.54535,13.54535,0,0,0,82.876,682.41435Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="#57b894"/>
|
||||
<path d="M83.43913,680.60233a13.66684,13.66684,0,1,0,2.635-10.70767l6.09231,9.16971-8.32439-4.867A13.54535,13.54535,0,0,0,83.43913,680.60233Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="none" stroke="#3f3d56" stroke-miterlimit="10"/>
|
||||
<ellipse cx="480.946" cy="319.1155" rx="17" ry="22" fill="#2f2e41"/>
|
||||
<ellipse cx="573.446" cy="319.6155" rx="17" ry="22" fill="#2f2e41"/>
|
||||
<path d="M623.5,542.5c0,9.94-13.88,18-31,18s-31-8.06-31-18c0-8.61,10.41-15.81,24.32-17.57a50.10353,50.10353,0,0,1,6.68-.43,50.69869,50.69869,0,0,1,11.13,1.2C615.25,528.29,623.5,534.84,623.5,542.5Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="#2f2e41"/>
|
||||
<ellipse cx="484.946" cy="314.1155" rx="17" ry="22" fill="none" stroke="#3f3d56" stroke-miterlimit="10"/>
|
||||
<ellipse cx="577.446" cy="314.6155" rx="17" ry="22" fill="none" stroke="#3f3d56" stroke-miterlimit="10"/>
|
||||
<ellipse cx="533.446" cy="379.6155" rx="31" ry="18" fill="none" stroke="#3f3d56" stroke-miterlimit="10"/>
|
||||
<path d="M604,527.2a4.93658,4.93658,0,0,1-1.32,3.392A4.33873,4.33873,0,0,1,599.5,532h-10a4.66433,4.66433,0,0,1-4.5-4.8,4.90458,4.90458,0,0,1,.82-2.74134A47.02,47.02,0,0,1,592.5,524a47.66454,47.66454,0,0,1,11.13,1.28A5.06656,5.06656,0,0,1,604,527.2Z"
|
||||
transform="translate(-63.054 -157.8845)" fill="#fff"/>
|
||||
<circle cx="484.946" cy="308.1155" r="5" fill="#fff"/>
|
||||
<circle cx="577.946" cy="308.1155" r="5" fill="#fff"/>
|
||||
<circle cx="582.946" cy="355.1155" r="5" fill="#16a085" opacity="0.3"/>
|
||||
<circle cx="460.946" cy="355.1155" r="5" fill="#16a085" opacity="0.3"/>
|
||||
</svg>
|
||||
|
||||
<!-- <h1 id="title">404 Page not found</h1> -->
|
||||
<!-- <button id="newBtn" class="btn" disabled>→ Back to Home</button> -->
|
||||
|
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 21 KiB |
@ -1,277 +1,75 @@
|
||||
<svg id="mainImage_create" data-name="mainImage" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 171.2 81.5">
|
||||
<style id="svgStyle">
|
||||
@import url('https://fonts.googleapis.com/css?family=Merriweather');
|
||||
.changeColor {
|
||||
fill: #4f86ed;
|
||||
}
|
||||
|
||||
#title {
|
||||
font-size: 50%;
|
||||
font-family: 'Merriweather', serif;
|
||||
}
|
||||
|
||||
.cls-1 {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.cls-7 {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.cls-2 {
|
||||
fill: #fff;
|
||||
}
|
||||
|
||||
.cls-10,
|
||||
.cls-11,
|
||||
.cls-12,
|
||||
.cls-14,
|
||||
.cls-16,
|
||||
.cls-3 {
|
||||
fill: none;
|
||||
}
|
||||
|
||||
.cls-3 {
|
||||
stroke: #5c7690;
|
||||
}
|
||||
|
||||
.cls-10,
|
||||
.cls-11,
|
||||
.cls-12,
|
||||
.cls-3 {
|
||||
stroke-miterlimit: 10;
|
||||
}
|
||||
|
||||
.cls-14,
|
||||
.cls-15,
|
||||
.cls-16,
|
||||
.cls-3 {
|
||||
stroke-width: 0.5px;
|
||||
}
|
||||
|
||||
.cls-4 {
|
||||
fill: #ffe1d9;
|
||||
}
|
||||
|
||||
.cls-5 {
|
||||
fill: #ffcfbf;
|
||||
}
|
||||
|
||||
.cls-6 {
|
||||
fill: #fecbb6;
|
||||
}
|
||||
|
||||
.cls-9 {
|
||||
fill: #fecb02;
|
||||
}
|
||||
|
||||
.cls-10,
|
||||
.cls-12 {
|
||||
stroke: #d26f51;
|
||||
}
|
||||
|
||||
.cls-10,
|
||||
.cls-11 {
|
||||
stroke-width: 0.38px;
|
||||
}
|
||||
|
||||
.cls-11 {
|
||||
stroke: #000;
|
||||
}
|
||||
|
||||
.cls-12 {
|
||||
stroke-width: 0.19px;
|
||||
}
|
||||
|
||||
.cls-13 {
|
||||
opacity: 0.45;
|
||||
}
|
||||
|
||||
.cls-14,
|
||||
.cls-15,
|
||||
.cls-16 {
|
||||
stroke: #b0bec5;
|
||||
stroke-linejoin: round;
|
||||
}
|
||||
|
||||
.cls-15 {
|
||||
fill: #edf0f2;
|
||||
}
|
||||
|
||||
.cls-16 {
|
||||
stroke-linecap: round;
|
||||
}
|
||||
|
||||
.cls-17 {
|
||||
font-family: 'PT Sans', sans-serif;
|
||||
font-size: 49.87px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.cls-18 {
|
||||
fill: #fffdbb;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------
|
||||
SVG Animate
|
||||
---------------------------*/
|
||||
.earMove {
|
||||
transition: all ease-in-out 2s;
|
||||
transform-origin: 50% 50%;
|
||||
animation: earmove 1.5s linear infinite alternate;
|
||||
}
|
||||
|
||||
.faceMove {
|
||||
transition: all ease-in-out 2s;
|
||||
transform-origin: 50% 50%;
|
||||
animation: move 1.5s linear infinite alternate;
|
||||
}
|
||||
|
||||
.neckMove {
|
||||
transition: all ease-in-out 2s;
|
||||
transform-origin: 50% 50%;
|
||||
animation: neck 1.5s linear infinite alternate;
|
||||
}
|
||||
|
||||
|
||||
@keyframes earmove {
|
||||
0% {
|
||||
transform: translateX(-0.3px) translateY(0.6px);
|
||||
}
|
||||
30% {
|
||||
transform: translateX(-0.3px) translateY(0.6px);
|
||||
}
|
||||
|
||||
60% {
|
||||
transform: translateX(-0.7px) translateY(0px);
|
||||
}
|
||||
|
||||
70% {
|
||||
transform: translateX(-0.7px) translateY(-0.3px);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(-0.7px) translateY(-0.3px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes move {
|
||||
0% {
|
||||
transform: translateX(-0.3px) translateY(0.6px);
|
||||
}
|
||||
30% {
|
||||
transform: translateX(-0.3px) translateY(0.6px);
|
||||
}
|
||||
|
||||
60% {
|
||||
transform: translateX(2px) translateY(0px);
|
||||
}
|
||||
|
||||
70% {
|
||||
transform: translateX(2px) translateY(-0.3px);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(2px) translateY(-0.3px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes neck {
|
||||
0% {
|
||||
transform: translateY(0.7px);
|
||||
}
|
||||
50% {
|
||||
transform: translateY(0.7px);
|
||||
}
|
||||
100% {
|
||||
transform: translateY(0px);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<path id="c-1" class="changeColor cls-1"
|
||||
d="M46.62,52.5c5.78,4.9,21.14,8.4,39.19,8.4s33.41-3.5,39.19-8.4c-5.78-4.9-21.14-8.4-39.19-8.4S52.41,47.6,46.62,52.5Z"
|
||||
style="fill: rgb(255, 5, 18);"></path>
|
||||
<path class="cls-2"
|
||||
d="M99.73,47.71H68.65a7.13,7.13,0,0,0-7.13,7.13V60a152.58,152.58,0,0,0,24.3,1.83,157.87,157.87,0,0,0,21.05-1.35V54.84A7.13,7.13,0,0,0,99.73,47.71Z"></path>
|
||||
<path class="cls-3"
|
||||
d="M123.56,55.81C115,58.94,101.27,61,85.81,61c-26,0-47-5.71-47-12.76,0-3.45,5.05-6.58,13.25-8.88"></path>
|
||||
<path class="cls-3" d="M55.37,38.47a140,140,0,0,1,30.44-3c26,0,47,5.71,47,12.76,0,2.4-2.44,4.65-6.69,6.57"></path>
|
||||
<path class="cls-3" d="M53.41,38.95l.94-.24"></path>
|
||||
<path class="cls-4"
|
||||
d="M91.68,47.71l-.75-11.2L79.15,43.84l-1.69,3.87H75.79c0,3.36,3.76,6.08,8.4,6.08s8.4-2.72,8.4-6.08Z"></path>
|
||||
<path class="cls-5 neckMove"
|
||||
d="M78,46.53a27.19,27.19,0,0,0,6.41.82c3.1,0,7.11-2.19,7.11-2.19l-.42-6.2L79.15,43.84Z"></path>
|
||||
<polygon class="earMove" points="92.59 32.22 92.59 28.5 76.77 27.71 76.77 32.22 92.59 32.22"></polygon>
|
||||
<circle class="cls-6 earMove" cx="78.06" cy="34.04" r="2.47"></circle>
|
||||
<path class="cls-4"
|
||||
d="M81.74,57.06,60.63,49.72h0A6.72,6.72,0,1,0,57.7,62.49H93.25C93.25,56.78,81.74,57.06,81.74,57.06Z"></path>
|
||||
<path class="cls-4"
|
||||
d="M77.46,25H90.92a0,0,0,0,1,0,0V39.38a6.73,6.73,0,0,1-6.73,6.73h0a6.73,6.73,0,0,1-6.73-6.73V25A0,0,0,0,1,77.46,25Z"></path>
|
||||
<rect id="c-2" class="changeColor cls-7" x="74.82" y="26.48" width="19.14" height="2.45"
|
||||
transform="translate(1.29 -3.65) rotate(2.49)" style="fill: rgb(255, 5, 18);"></rect>
|
||||
<path id="c-3" class="changeColor cls-7"
|
||||
d="M84.36,18.69h.5a7.8,7.8,0,0,1,7.8,7.8v0a0,0,0,0,1,0,0H76.56a0,0,0,0,1,0,0v0A7.8,7.8,0,0,1,84.36,18.69Z"
|
||||
transform="translate(1.06 -3.66) rotate(2.49)" style="fill: rgb(255, 5, 18);"></path>
|
||||
<polygon id="c-4" class="changeColor cls-8"
|
||||
points="82.44 23.89 92.18 24.32 92.59 24.34 92.48 26.84 80.96 26.33 82.44 23.89"
|
||||
style="fill: rgb(255, 5, 18);"></polygon>
|
||||
<circle class="cls-9 faceMove" cx="78.72" cy="23.73" r="3.73"
|
||||
transform="translate(51.58 101.34) rotate(-87.51)"></circle>
|
||||
<circle class="cls-2 faceMove" cx="78.72" cy="23.73" r="2.36"
|
||||
transform="translate(51.58 101.34) rotate(-87.51)"></circle>
|
||||
<circle class="cls-4 earMove" cx="90.92" cy="34.04" r="2.47"></circle>
|
||||
<path class="cls-4"
|
||||
d="M112.2,53l-9.87-21.92-3-5.48-11.86-.22,7.42,3.35H91.55l5.82,4.58,2,22.26h0A6.72,6.72,0,1,0,112.2,53Z"></path>
|
||||
<ellipse class="faceMove" cx="80.09" cy="33.12" rx="0.53" ry="0.59"></ellipse>
|
||||
<ellipse class="faceMove" cx="86.34" cy="33.12" rx="0.53" ry="0.59"></ellipse>
|
||||
<polyline class="cls-10 faceMove" points="84.19 31.08 81.74 37.01 84.39 37.01"></polyline>
|
||||
<path class="cls-10 faceMove" d="M83.06,40.36a4,4,0,0,1,2.75-1"></path>
|
||||
<line class="cls-11 faceMove" x1="81.07" y1="30.33" x2="78.47" y2="30.58"></line>
|
||||
<line class="cls-11 faceMove" x1="86.34" y1="30.45" x2="88.15" y2="31.08"></line>
|
||||
<line class="cls-12" x1="106.86" y1="47.82" x2="110.99" y2="46.11"></line>
|
||||
<line class="cls-12" x1="107.43" y1="49.9" x2="111.55" y2="48.19"></line>
|
||||
<line class="cls-12" x1="107.99" y1="51.98" x2="112.11" y2="50.27"></line>
|
||||
<g class="cls-13">
|
||||
<rect class="cls-14" x="85.81" y="2.46" width="10.77" height="3.5"></rect>
|
||||
<rect class="cls-15" x="96.58" y="2.46" width="10.77" height="3.5"></rect>
|
||||
<rect class="cls-14" x="92.19" y="5.95" width="10.77" height="3.5"></rect>
|
||||
<line class="cls-16" x1="107.36" y1="5.95" x2="109.63" y2="5.95"></line>
|
||||
<line class="cls-16" x1="110.68" y1="5.95" x2="111.57" y2="5.95"></line>
|
||||
</g>
|
||||
<g class="cls-13">
|
||||
<rect class="cls-16" x="125" y="23.12" width="10.77" height="3.5"></rect>
|
||||
<rect class="cls-15" x="130.39" y="26.62" width="10.77" height="3.5"></rect>
|
||||
<rect class="cls-16" x="119.62" y="26.62" width="10.77" height="3.5"></rect>
|
||||
<line class="cls-16" x1="141.16" y1="26.62" x2="145.73" y2="26.62"></line>
|
||||
<line class="cls-16" x1="125" y1="23.12" x2="115.4" y2="23.12"></line>
|
||||
<line class="cls-16" x1="117.95" y1="26.62" x2="115.4" y2="26.62"></line>
|
||||
</g>
|
||||
<g class="cls-13">
|
||||
<rect class="cls-16" x="39.34" y="16.12" width="10.77" height="3.5"></rect>
|
||||
<rect class="cls-16" x="39.34" y="23.11" width="10.77" height="3.5"></rect>
|
||||
<rect class="cls-16" x="50.11" y="23.11" width="10.77" height="3.5"></rect>
|
||||
<rect class="cls-16" x="50.11" y="16.12" width="10.77" height="3.5"></rect>
|
||||
<rect class="cls-15" x="44" y="19.61" width="10.77" height="3.5"></rect>
|
||||
<rect class="cls-16" x="33.23" y="19.61" width="10.77" height="3.5"></rect>
|
||||
<line class="cls-16" x1="60.89" y1="19.61" x2="65.51" y2="19.61"></line>
|
||||
<line class="cls-16" x1="39.34" y1="16.12" x2="35.46" y2="16.12"></line>
|
||||
<line class="cls-16" x1="36.45" y1="26.61" x2="33.23" y2="26.61"></line>
|
||||
<line class="cls-16" x1="63.2" y1="23.11" x2="65.51" y2="23.11"></line>
|
||||
</g>
|
||||
<polyline class="cls-3" points="115.4 58.12 115.4 38.27 120.2 37.01"></polyline>
|
||||
<polyline class="cls-3" points="129.01 53.21 129.01 43.14 131.74 42.13"></polyline>
|
||||
<path class="cls-3" d="M115.4,42.13a53.27,53.27,0,0,1,8,2A42,42,0,0,1,129,47"></path>
|
||||
<path class="cls-3" d="M115.4,47.34a53.27,53.27,0,0,1,8,2A42,42,0,0,1,129,52.22"></path>
|
||||
<path class="cls-3" d="M115.4,52.56a53.27,53.27,0,0,1,8,2l1,.42"></path>
|
||||
<path class="cls-18 faceMove"
|
||||
d="M78.84,26.09l0-4.71L68.05,18.32a.91.91,0,0,0-.45-.13c-1.17,0-2.11,2.46-2.11,5.5s.95,5.5,2.11,5.5a.9.9,0,0,0,.44-.12Z"></path>
|
||||
<path class="cls-5" d="M57.7,62.49H93.25A3.67,3.67,0,0,0,92.92,61H53.43A6.69,6.69,0,0,0,57.7,62.49Z"></path>
|
||||
<path class="cls-12" d="M88.15,60.27s1.7.95,1.7,2.22"></path>
|
||||
<path class="cls-5" d="M101.81,61a6.68,6.68,0,0,0,8.51,0Z"></path>
|
||||
<polygon class="cls-5" points="90.92 30.25 77.46 29.69 77.46 28.64 90.92 29.22 90.92 30.25"></polygon>
|
||||
<text id="title" transform="matrix(1 0 0 1 44.7249 78)">Oops, something went wrong</text>
|
||||
<svg id="aa03ddf9-f8f2-4819-a4ce-be9b0a220741" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" width="1119.60911"
|
||||
height="699" viewBox="0 0 1119.60911 699">
|
||||
<title>server down</title>
|
||||
<circle cx="292.60911" cy="213" r="213" fill="#f2f2f2"/>
|
||||
<path d="M31.39089,151.64237c0,77.49789,48.6181,140.20819,108.70073,140.20819"
|
||||
transform="translate(-31.39089 -100.5)" fill="#2f2e41"/>
|
||||
<path d="M140.09162,291.85056c0-78.36865,54.255-141.78356,121.30372-141.78356"
|
||||
transform="translate(-31.39089 -100.5)" fill="#16a085"/>
|
||||
<path d="M70.77521,158.66768c0,73.61476,31.00285,133.18288,69.31641,133.18288"
|
||||
transform="translate(-31.39089 -100.5)" fill="#16a085"/>
|
||||
<path d="M140.09162,291.85056c0-100.13772,62.7103-181.16788,140.20819-181.16788"
|
||||
transform="translate(-31.39089 -100.5)" fill="#2f2e41"/>
|
||||
<path d="M117.22379,292.83905s15.41555-.47479,20.06141-3.783,23.713-7.2585,24.86553-1.95278,23.16671,26.38821,5.76263,26.5286-40.43935-2.711-45.07627-5.53549S117.22379,292.83905,117.22379,292.83905Z"
|
||||
transform="translate(-31.39089 -100.5)" fill="#a8a8a8"/>
|
||||
<path d="M168.224,311.78489c-17.40408.14042-40.43933-2.71094-45.07626-5.53548-3.53126-2.151-4.93843-9.86945-5.40926-13.43043-.32607.014-.51463.02-.51463.02s.97638,12.43276,5.61331,15.2573,27.67217,5.67589,45.07626,5.53547c5.02386-.04052,6.7592-1.82793,6.66391-4.47526C173.87935,310.756,171.96329,311.75474,168.224,311.78489Z"
|
||||
transform="translate(-31.39089 -100.5)" opacity="0.2"/>
|
||||
<ellipse cx="198.60911" cy="424.5" rx="187" ry="25.43993" fill="#3f3d56"/>
|
||||
<ellipse cx="198.60911" cy="424.5" rx="157" ry="21.35866" opacity="0.1"/>
|
||||
<ellipse cx="836.60911" cy="660.5" rx="283" ry="38.5" fill="#3f3d56"/>
|
||||
<ellipse cx="310.60911" cy="645.5" rx="170" ry="23.12721" fill="#3f3d56"/>
|
||||
<path d="M494,726.5c90,23,263-30,282-90" transform="translate(-31.39089 -100.5)" fill="none" stroke="#2f2e41"
|
||||
stroke-miterlimit="10" stroke-width="2"/>
|
||||
<path d="M341,359.5s130-36,138,80-107,149-17,172" transform="translate(-31.39089 -100.5)" fill="none"
|
||||
stroke="#2f2e41" stroke-miterlimit="10" stroke-width="2"/>
|
||||
<path d="M215.40233,637.78332s39.0723-10.82,41.47675,24.04449-32.15951,44.78287-5.10946,51.69566"
|
||||
transform="translate(-31.39089 -100.5)" fill="none" stroke="#2f2e41" stroke-miterlimit="10" stroke-width="2"/>
|
||||
<path d="M810.09554,663.73988,802.218,714.03505s-38.78182,20.60284-11.51335,21.20881,155.73324,0,155.73324,0,24.84461,0-14.54318-21.81478l-7.87756-52.719Z"
|
||||
transform="translate(-31.39089 -100.5)" fill="#2f2e41"/>
|
||||
<path d="M785.21906,734.69812c6.193-5.51039,16.9989-11.252,16.9989-11.252l7.87756-50.2952,113.9216.10717,7.87756,49.582c9.185,5.08711,14.8749,8.987,18.20362,11.97818,5.05882-1.15422,10.58716-5.44353-18.20362-21.38921l-7.87756-52.719-113.9216,3.02983L802.218,714.03506S769.62985,731.34968,785.21906,734.69812Z"
|
||||
transform="translate(-31.39089 -100.5)" opacity="0.1"/>
|
||||
<rect x="578.43291" y="212.68859" width="513.25314" height="357.51989" rx="18.04568" fill="#2f2e41"/>
|
||||
<rect x="595.70294" y="231.77652" width="478.71308" height="267.83694" fill="#3f3d56"/>
|
||||
<circle cx="835.05948" cy="223.29299" r="3.02983" fill="#f2f2f2"/>
|
||||
<path d="M1123.07694,621.32226V652.6628a18.04341,18.04341,0,0,1-18.04568,18.04568H627.86949A18.04341,18.04341,0,0,1,609.8238,652.6628V621.32226Z"
|
||||
transform="translate(-31.39089 -100.5)" fill="#2f2e41"/>
|
||||
<polygon
|
||||
points="968.978 667.466 968.978 673.526 642.968 673.526 642.968 668.678 643.417 667.466 651.452 645.651 962.312 645.651 968.978 667.466"
|
||||
fill="#2f2e41"/>
|
||||
<path d="M1125.828,762.03359c-.59383,2.539-2.83591,5.21743-7.90178,7.75032-18.179,9.08949-55.1429-2.42386-55.1429-2.42386s-28.4804-4.84773-28.4804-17.573a22.72457,22.72457,0,0,1,2.49658-1.48459c7.64294-4.04351,32.98449-14.02122,77.9177.42248a18.73921,18.73921,0,0,1,8.54106,5.59715C1125.07908,756.45353,1126.50669,759.15715,1125.828,762.03359Z"
|
||||
transform="translate(-31.39089 -100.5)" fill="#2f2e41"/>
|
||||
<path d="M1125.828,762.03359c-22.251,8.526-42.0843,9.1622-62.43871-4.975-10.26507-7.12617-19.59089-8.88955-26.58979-8.75618,7.64294-4.04351,32.98449-14.02122,77.9177.42248a18.73921,18.73921,0,0,1,8.54106,5.59715C1125.07908,756.45353,1126.50669,759.15715,1125.828,762.03359Z"
|
||||
transform="translate(-31.39089 -100.5)" opacity="0.1"/>
|
||||
<ellipse cx="1066.53846" cy="654.13477" rx="7.87756" ry="2.42386" fill="#f2f2f2"/>
|
||||
<circle cx="835.05948" cy="545.66686" r="11.51335" fill="#f2f2f2"/>
|
||||
<polygon points="968.978 667.466 968.978 673.526 642.968 673.526 642.968 668.678 643.417 667.466 968.978 667.466"
|
||||
opacity="0.1"/>
|
||||
<rect x="108.60911" y="159" width="208" height="242" fill="#2f2e41"/>
|
||||
<rect x="87.60911" y="135" width="250" height="86" fill="#3f3d56"/>
|
||||
<rect x="87.60911" y="237" width="250" height="86" fill="#3f3d56"/>
|
||||
<rect x="87.60911" y="339" width="250" height="86" fill="#3f3d56"/>
|
||||
<rect x="271.60911" y="150" width="16" height="16" fill="#16a085" opacity="0.4"/>
|
||||
<rect x="294.60911" y="150" width="16" height="16" fill="#16a085" opacity="0.8"/>
|
||||
<rect x="317.60911" y="150" width="16" height="16" fill="#16a085"/>
|
||||
<rect x="271.60911" y="251" width="16" height="16" fill="#16a085" opacity="0.4"/>
|
||||
<rect x="294.60911" y="251" width="16" height="16" fill="#16a085" opacity="0.8"/>
|
||||
<rect x="317.60911" y="251" width="16" height="16" fill="#16a085"/>
|
||||
<rect x="271.60911" y="352" width="16" height="16" fill="#16a085" opacity="0.4"/>
|
||||
<rect x="294.60911" y="352" width="16" height="16" fill="#16a085" opacity="0.8"/>
|
||||
<rect x="317.60911" y="352" width="16" height="16" fill="#16a085"/>
|
||||
<circle cx="316.60911" cy="538" r="79" fill="#2f2e41"/>
|
||||
<rect x="280.60911" y="600" width="24" height="43" fill="#2f2e41"/>
|
||||
<rect x="328.60911" y="600" width="24" height="43" fill="#2f2e41"/>
|
||||
<ellipse cx="300.60911" cy="643.5" rx="20" ry="7.5" fill="#2f2e41"/>
|
||||
<ellipse cx="348.60911" cy="642.5" rx="20" ry="7.5" fill="#2f2e41"/>
|
||||
<circle cx="318.60911" cy="518" r="27" fill="#fff"/>
|
||||
<circle cx="318.60911" cy="518" r="9" fill="#3f3d56"/>
|
||||
<path d="M271.36733,565.03228c-6.37889-28.56758,14.01185-57.43392,45.544-64.47477s62.2651,10.41,68.644,38.9776-14.51861,39.10379-46.05075,46.14464S277.74622,593.59986,271.36733,565.03228Z"
|
||||
transform="translate(-31.39089 -100.5)" fill="#16a085"/>
|
||||
<ellipse cx="417.21511" cy="611.34365" rx="39.5" ry="12.40027"
|
||||
transform="translate(-238.28665 112.98044) rotate(-23.17116)" fill="#2f2e41"/>
|
||||
<ellipse cx="269.21511" cy="664.34365" rx="39.5" ry="12.40027"
|
||||
transform="translate(-271.07969 59.02084) rotate(-23.17116)" fill="#2f2e41"/>
|
||||
<path d="M394,661.5c0,7.732-19.90861,23-42,23s-43-14.268-43-22,20.90861-6,43-6S394,653.768,394,661.5Z"
|
||||
transform="translate(-31.39089 -100.5)" fill="#fff"/>
|
||||
</svg>
|
||||
|
||||
<!-- <h1 id="title">404 Page not found</h1> -->
|
||||
<!-- <button id="newBtn" class="btn" disabled>→ Back to Home</button> -->
|
||||
|
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 6.8 KiB |
@ -9,10 +9,8 @@
|
||||
<nav th:replace="fragments/header :: header">Header</nav>
|
||||
<main>
|
||||
<div class='content-width'>
|
||||
<h1>Error 404</h1>
|
||||
<h1>Ein Fehler ist aufgetreten. Die gewünschte Ressource konnte nicht gefunden werden</h1>
|
||||
<div>
|
||||
<p>Ein Fehler ist aufgetreten. Die gewünschte Ressource konnte nicht gefunden werden.</p>
|
||||
<!-- animation from https://github.com/blairlee227/IlluStatus, licensed MIT -->
|
||||
<img th:src="@{/img/error_404_illustatus.svg}"/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -9,10 +9,8 @@
|
||||
<nav th:replace="fragments/header :: header">Header</nav>
|
||||
<main>
|
||||
<div class='content-width'>
|
||||
<h1>Error 500</h1>
|
||||
<h1>Ein Fehler ist aufgetreten. Bitte versuche es später nocheinmal.</h1>
|
||||
<div>
|
||||
<p>Ein Fehler ist aufgetreten. Bitte versuche es später nocheinmal.</p>
|
||||
<!-- animation from https://github.com/blairlee227/IlluStatus, licensed MIT -->
|
||||
<img th:src="@{/img/error_generic_illustatus.svg}"/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -26,7 +26,7 @@
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<a class="button" th:href="@{/shop/checkout}">Warenkorb</a>
|
||||
<a class="button" th:href="@{/shop/checkout}">Warenkorb (<span th:text="${shoppingCart.itemCount}"></span>)</a>
|
||||
</div>
|
||||
<div th:if="${error}" class="error" id="error-msg">
|
||||
<div class="content-width bar-flex">
|
||||
|
@ -19,32 +19,29 @@
|
||||
<div class="detailgrid">
|
||||
<div class="s">
|
||||
|
||||
<h1>Tolle Kamera</h1>
|
||||
<h1 th:text="${article.title}"></h1>
|
||||
<script th:src="@{/js/back.js}"></script>
|
||||
<div class="back" data-group="shop" data-insert="true"></div>
|
||||
|
||||
<h2>25.14 EUR</h2>
|
||||
<p>
|
||||
Eine TOLLE Kamera <br>
|
||||
Jaja du denkst jetzt bestimmt: "Bei dem Preis kann sie gar nich sooo TOLL sein". <br>
|
||||
Aber glaub mir, sie is echt echt TOLL! <br>
|
||||
Indianerehrenwort!
|
||||
</p>
|
||||
<h2><span th:text="${#numbers.formatDecimal(article.getPriceGross() * 0.01, 1, 'POINT', 2, 'COMMA')}"></span><span> EUR</span></h2>
|
||||
<p th:text="${article.description}"></p>
|
||||
</div>
|
||||
<div class="s">
|
||||
<img th:src="@{/img/product-1.jpg}"/>
|
||||
<img th:src="@{/shop/articles/{id}/image.jpg(id=${article.id})}"/>
|
||||
</div>
|
||||
<div class="s"></div>
|
||||
<form class="s" method="POST">
|
||||
<div class="detailgrid m">
|
||||
<h2>50.28 EUR</h2>
|
||||
<h2><span th:text="${#numbers.formatDecimal(article.getPriceGross() * 0.01, 1, 'POINT', 2, 'COMMA')}"></span><span> EUR</span></h2>
|
||||
<div>
|
||||
<label class="nolinebreak">Menge:</label>
|
||||
<select size="1">
|
||||
<option>2</option>
|
||||
<select name="quantity" size="1">
|
||||
<option th:each="quantity : ${#numbers.sequence(1,10)}"
|
||||
th:value="${quantity}"
|
||||
th:text="${quantity}"></option>
|
||||
</select>
|
||||
</div>
|
||||
<h3 class="no-margin secondarytext">Auf Lager</h3>
|
||||
<h3 class="no-margin secondarytext" th:text="${inStock} ? 'AUF LAGER' : 'NICHT AUF LAGER'"></h3>
|
||||
<button class="no-margin secondary" name="fastcheckout" value="false">In den Einkaufswagen
|
||||
</button>
|
||||
<button class="no-margin" name="fastcheckout" value="true">Schneller Checkout</button>
|
||||
@ -56,26 +53,13 @@
|
||||
<div class="sidebar-layout">
|
||||
<div></div>
|
||||
<div>
|
||||
<h1>Weitere Schnäpchen</h1>
|
||||
<h1>Weitere Schnäppchen</h1>
|
||||
<div class='grid m base shadow'>
|
||||
<section><a th:href="@{/shop/articles/1234}" class="section">
|
||||
<img th:src="@{/img/product-4.jpg}">
|
||||
<h2>Kamera Stativ.</h2>
|
||||
<p class='price'> 25.14 EUR</p>
|
||||
<p>
|
||||
Das Stativ der Zukunft! Jetzt kaufen und verwenden für
|
||||
wackelfreie Bilder aus der Zukunft!.
|
||||
</p>
|
||||
</a>
|
||||
</section>
|
||||
|
||||
<section><a th:href="@{/shop/articles/1234}" class="section">
|
||||
<img th:src="@{/img/product-5.jpg}">
|
||||
<h2>Bluetooth Ersatzfernbedinung</h2>
|
||||
<p class='price'> 10.14 EUR</p>
|
||||
<p>
|
||||
Kann alles und jeden ausknippsen.
|
||||
</p>
|
||||
<section th:each="article: ${commercialArticles}"><a th:href="@{/shop/articles/{id}(id = ${article.id})}" class="section">
|
||||
<img th:src="@{/shop/articles/{id}/image.jpg(id=${article.id})}"/>
|
||||
<h2 th:text="${article.title}"></h2>
|
||||
<p class='price'><span th:text="${#numbers.formatDecimal(article.getPriceGross() * 0.01, 1, 'POINT', 2, 'COMMA')}"></span><span> EUR</span></p>
|
||||
<p th:text="${article.description}"></p>
|
||||
</a>
|
||||
</section>
|
||||
</div>
|
||||
|
@ -21,7 +21,17 @@
|
||||
</div>
|
||||
<nav></nav>
|
||||
</div>
|
||||
<main class="content-width sidebar-layout" style="min-height: 100vh;">
|
||||
<main th:if="${checkoutItems.size() == 0}">
|
||||
<div class="detailflex m">
|
||||
<h2> Noch keine Artikel im Warenkorb. </h2>
|
||||
<p>
|
||||
<img th:src="@{/img/undraw_successful_purchase_secondary.svg}"/>
|
||||
</p>
|
||||
<a class="button" th:href="@{/}"> Weiter shoppen </a>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
<main th:if="${checkoutItems.size() > 0}" class="content-width sidebar-layout" style="min-height: 100vh;">
|
||||
<div style="max-width: 45em; width: 100%;">
|
||||
<table>
|
||||
<tr>
|
||||
@ -31,91 +41,32 @@
|
||||
<th>Menge</th>
|
||||
<th></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>100,50 EUR</td>
|
||||
<td>
|
||||
<select size="1">
|
||||
<option value="1" selected>1</option>
|
||||
<option value="2">2</option>
|
||||
<option value="3">3</option>
|
||||
<option value="4">4</option>
|
||||
<option value="5">5</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<button class="small">Entfernen</button>
|
||||
</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>63,95 EUR</td>
|
||||
<td>
|
||||
<select size="1">
|
||||
<option value="1" selected>1</option>
|
||||
<option value="2">2</option>
|
||||
<option value="3">3</option>
|
||||
<option value="4">4</option>
|
||||
<option value="5">5</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<button>Entfernen</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a th:href="@{/shop/articles/4151}"><img th:src="@{/img/product-3.jpg}" class="s"/><a/></td>
|
||||
<td><a th:href="@{/shop/articles/4151}">USB-Magic Light<a/></td>
|
||||
<td>11,90 EUR</td>
|
||||
<td>
|
||||
<select size="1">
|
||||
<option value="1">1</option>
|
||||
<option value="2" selected>2</option>
|
||||
<option value="3">3</option>
|
||||
<option value="4">4</option>
|
||||
<option value="5">5</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<button>Entfernen</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a th:href="@{/shop/articles/4151}"><img th:src="@{/img/product-4.jpg}" class="s"/><a/></td>
|
||||
<td><a th:href="@{/shop/articles/4151}">3D Magic Stativ<a/></td>
|
||||
<td>15,99 EUR</td>
|
||||
<td>
|
||||
<select size="1">
|
||||
<option value="1">1</option>
|
||||
<option value="2">2</option>
|
||||
<option value="3">3</option>
|
||||
<option value="4">4</option>
|
||||
<option value="5" selected>5</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<button>Entfernen</button>
|
||||
</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}">Ersatzfernbedinung<a/></td>
|
||||
<td>7,95 EUR</td>
|
||||
<td>
|
||||
<select size="1">
|
||||
<option value="1" selected>1</option>
|
||||
<option value="2">2</option>
|
||||
<option value="3">3</option>
|
||||
<option value="4">4</option>
|
||||
<option value="5">5</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<button>Entfernen</button>
|
||||
</td>
|
||||
</tr>
|
||||
<th:block th:each="item : ${checkoutItems}">
|
||||
<tr>
|
||||
<td><a th:href="@{/shop/articles/{id}(id = ${item.article.id})}"><img
|
||||
th:src="@{/shop/articles/{id}/image.jpg(id=${item.article.id})}" class="s"/></a></td>
|
||||
|
||||
<td><a th:href="@{/shop/articles/{id}(id = ${item.article.id})}"
|
||||
th:text="${item.article.title}"></a></td>
|
||||
<td><span
|
||||
th:text="${#numbers.formatDecimal(item.article.getPriceGross() * 0.01, 1, 'POINT', 2, 'COMMA')}"></span>
|
||||
EUR <b>x</b></td>
|
||||
<td>
|
||||
<form method="POST" th:action="@{/shop/articles/{id}(id = ${item.article.id})}">
|
||||
<input type="hidden" name="fastcheckout" value="true"/>
|
||||
<input type="hidden" name="set_amount" value="true"/>
|
||||
<select name="quantity" size="1">
|
||||
<option th:value="${item.amount}" th:text="${item.amount}" selected></option>
|
||||
<option value="0">Entfernen</option>
|
||||
<option th:each="quantity : ${#numbers.sequence(1,10)}"
|
||||
th:value="${quantity}"
|
||||
th:text="${quantity}"></option>
|
||||
</select>
|
||||
<button class="small">Ändern</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<th:block>
|
||||
</table>
|
||||
</div>
|
||||
<form method="POST" th:action="@{/shop/checkoutFinish}" style="min-width: 30em; max-width: 45em;">
|
||||
@ -124,11 +75,16 @@
|
||||
<h1>Checkout</h1>
|
||||
</div>
|
||||
<div th:if="${user}">
|
||||
<input type="hidden" name="shopping_cart_revision" th:value="${shoppingCart.getRevision()}"/>
|
||||
<input type="hidden" name="expected_total" th:value="${checkoutTotals.total}"/>
|
||||
|
||||
<h2>Lieferadresse:</h2>
|
||||
<textarea rows="5" class="full-width" type="text" name="address"
|
||||
placeholder="Optional: Zusatz Optional: Unternehmen Straße Hausnummer Postleitzeit Ort Land">
|
||||
placeholder="Name Optional: Zusatz Optional: Unternehmen Straße Hausnummer Postleitzeit Ort Land"
|
||||
th:text="${user.defaultDeliveryAddress != null ? user.defaultDeliveryAddress.toString() : ''}"
|
||||
required>
|
||||
Max Mustermann
|
||||
Musterstraße 42
|
||||
Musterstraße 4
|
||||
42424 Mustertal
|
||||
</textarea>
|
||||
</div>
|
||||
@ -138,12 +94,10 @@ Musterstraße 42
|
||||
<input type="radio" name="type" value="priv" id="payment-card" required checked>
|
||||
<label for="payment-card">Kartenzahlung</label> <br/>
|
||||
<input class="full-width" type="text" id="cardnumber" name="cardnumber" placeholder="Kartennummer"
|
||||
th:value="${user.defaultPayment != null ? user.defaultPayment.creditCardNumber : ''}"
|
||||
pattern="[0-9]{6,16}"
|
||||
required/>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<input class="" type="checkbox" id="bonus" name="bonus" checked/>
|
||||
<label for="bonus"><h3>10 gesammelte Bonuspunkte verwenden</h3></label>
|
||||
</fieldset>
|
||||
</div>
|
||||
<div>
|
||||
<h2>Bestellübersicht</h2>
|
||||
@ -151,23 +105,26 @@ Musterstraße 42
|
||||
<table>
|
||||
<tr>
|
||||
<th>Artikel (Netto)</th>
|
||||
<th>200,29 EUR</th>
|
||||
</tr>
|
||||
<tr th:if="${user}">
|
||||
<th>Bonuspunkte</th>
|
||||
<th>-5,00 EUR</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Umsatzsteuer (19%)</th>
|
||||
<th>35,00 EUR</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Umsatzsteuer (7%)</th>
|
||||
<th>2,50 EUR</th>
|
||||
<th><span
|
||||
th:text="${#numbers.formatDecimal(checkoutTotals.net * 0.01, 1, 'POINT', 2, 'COMMA')}"></span>
|
||||
EUR
|
||||
</th>
|
||||
</tr>
|
||||
<th:block th:each="item : ${checkoutTotals.vatAmounts.entrySet()}">
|
||||
<tr>
|
||||
<th>Umsatzsteuer (<span th:text="${item.getKey()}"></span>%)</th>
|
||||
<th><span
|
||||
th:text="${#numbers.formatDecimal(item.getValue() * 0.01, 1, 'POINT', 2, 'COMMA')}"></span>
|
||||
EUR
|
||||
</th>
|
||||
</tr>
|
||||
</th:block>
|
||||
<tr class="secondary">
|
||||
<th>Gesamt:</th>
|
||||
<th>240,79 EUR</th>
|
||||
<th><span
|
||||
th:text="${#numbers.formatDecimal(checkoutTotals.total * 0.01, 1, 'POINT', 2, 'COMMA')}"></span>
|
||||
EUR
|
||||
</th>
|
||||
</tr>
|
||||
<tr th:if="${user}" class="secondary">
|
||||
<th colspan="2" class=" no-padding"></th>
|
||||
|
@ -17,55 +17,17 @@
|
||||
<h1>Angebote</h1>
|
||||
<script th:src="@{/js/back.js}"></script>
|
||||
<div class="back" data-group="shop" data-name="Zurück zur Startseite." data-insert="false"></div>
|
||||
<div class='grid m base shadow'>
|
||||
<section><a th:href="@{/shop/articles/1234}" class="section">
|
||||
<div th:if="${commercialArticles.size() == 0}">
|
||||
<h1>Momentan gibt es keine Angebote</h1>
|
||||
</div>
|
||||
<div class='grid m base shadow' th:if="${commercialArticles.size() != 0}">
|
||||
<section th:each="article: ${commercialArticles}">
|
||||
<a th:href="@{/shop/articles/{id}(id=${article.id})}" class="section">
|
||||
|
||||
<img th:src="@{/img/product-1.jpg}"/>
|
||||
<h2>Lorem Ipsum</h2>
|
||||
<p class='price'> 25.14 EUR</p>
|
||||
<p>
|
||||
Als Gregor Samsa eines Morgens aus unruhigen Träumen erwachte.
|
||||
</p>
|
||||
</a>
|
||||
</section>
|
||||
<section><a th:href="@{/shop/articles/1234}" class="section">
|
||||
|
||||
<img th:src="@{/img/product-2.jpg}"/>
|
||||
<h2>Lorem Ipsum</h2>
|
||||
<p class='price'> 10.14 EUR</p>
|
||||
<p>
|
||||
Als Gregor Samsa eines Morgens aus unruhigen Träumen erwachte.
|
||||
</p>
|
||||
</a>
|
||||
</section>
|
||||
<section><a th:href="@{/shop/articles/1234}" class="section">
|
||||
|
||||
<img th:src="@{/img/product-3.jpg}"/>
|
||||
<h2>Lorem Ipsum</h2>
|
||||
<p class='price'> 25.14 EUR</p>
|
||||
<p>
|
||||
Als Gregor Samsa eines Morgens aus unruhigen Träumen erwachte.
|
||||
</p>
|
||||
</a>
|
||||
</section>
|
||||
<section><a th:href="@{/shop/articles/1234}" class="section">
|
||||
|
||||
<img th:src="@{/img/product-4.jpg}"/>
|
||||
<h2>Lorem Ipsum</h2>
|
||||
<p class='price'> 10.14 EUR</p>
|
||||
<p>
|
||||
Als Gregor Samsa eines Morgens aus unruhigen Träumen erwachte.
|
||||
</p>
|
||||
</a>
|
||||
</section>
|
||||
<section>
|
||||
<a th:href="@{/shop/articles/1234}" class="section">
|
||||
<img th:src="@{/img/product-5.jpg}"/>
|
||||
<h2>Lorem Ipsum</h2>
|
||||
<p class='price'> 44.14 EUR</p>
|
||||
<p>
|
||||
Als Gregor Samsa eines Morgens aus unruhigen Träumen erwachte.
|
||||
</p>
|
||||
<img th:src="@{/shop/articles/{id}/image.jpg(id=${article.id})}"/>
|
||||
<h2 th:text="${article.title}" />
|
||||
<p class='price'><span th:text="${#numbers.formatDecimal(article.getPriceGross() * 0.01, 1, 'POINT', 2, 'COMMA')}"></span><span> EUR</span></p>
|
||||
<p th:text="${article.description}" />
|
||||
</a>
|
||||
</section>
|
||||
<section class="spacer"></section>
|
||||
@ -79,7 +41,9 @@
|
||||
<div class=''>
|
||||
<div class='content-width'>
|
||||
<h1>Personalisierte Empfehlungen</h1>
|
||||
<div class="grid l">
|
||||
|
||||
<!-- if a User is NOT logged in-->
|
||||
<div class="grid l" th:if="${isLoggedIn == false}">
|
||||
<img th:src="@{/img/undraw_successful_purchase_secondary.svg}"/>
|
||||
<div>
|
||||
<h2>Werde jetzt Kunde</h2>
|
||||
@ -90,6 +54,26 @@
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- If User is logged in but hasn't ordered anything yet-->
|
||||
<div th:if="${isLoggedIn == true and hasOrders == false}">
|
||||
<h1>Jetzt Shoppen und Empfehlungen erhalten!</h1>
|
||||
</div>
|
||||
|
||||
<!-- If User is logged in and has ordered something before-->
|
||||
<div th:if="${hasOrders == true}">
|
||||
<div class='grid m base shadow'>
|
||||
<section th:each="article: ${suggestedArticles}">
|
||||
<a th:href="@{/shop/articles/{id}(id=${article.id})}" class="section">
|
||||
|
||||
<img th:src="@{/shop/articles/{id}/image.jpg(id=${article.id})}"/>
|
||||
<h2 th:text="${article.title}" />
|
||||
<p class='price'><span th:text="${#numbers.formatDecimal(article.getPriceGross() * 0.01, 1, 'POINT', 2, 'COMMA')}"></span><span> EUR</span></p>
|
||||
<p th:text="${article.description}" />
|
||||
</a>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="vertical-spacer s"></div>
|
||||
</div>
|
||||
|
"should_be_advertised" fehlt hier.
@Hannes, your change
fixed it