feature/reorder_cronjob #27
2
.gitignore
vendored
2
.gitignore
vendored
@ -91,3 +91,5 @@ local.properties
|
|||||||
prototype/*.db
|
prototype/*.db
|
||||||
|
|
||||||
prototype/images
|
prototype/images
|
||||||
|
prototype/data
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ buildscript {
|
|||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.2.2.RELEASE")
|
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.2.7.RELEASE")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ dependencies {
|
|||||||
// implementation 'org.springframework.session:spring-session-jdbc'
|
// implementation 'org.springframework.session:spring-session-jdbc'
|
||||||
implementation 'com.github.gwenn:sqlite-dialect:0.1.0'
|
implementation 'com.github.gwenn:sqlite-dialect:0.1.0'
|
||||||
implementation 'org.springframework.boot:spring-boot-devtools'
|
implementation 'org.springframework.boot:spring-boot-devtools'
|
||||||
implementation 'org.xerial:sqlite-jdbc:3.28.0'
|
implementation 'org.xerial:sqlite-jdbc:3.31.1'
|
||||||
testCompile("org.springframework.boot:spring-boot-starter-test")
|
testCompile("org.springframework.boot:spring-boot-starter-test")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BIN
prototype/gradle/wrapper/gradle-wrapper.jar
vendored
BIN
prototype/gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
@ -1,5 +1,5 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.4-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
22
prototype/gradlew
vendored
Executable file → Normal file
22
prototype/gradlew
vendored
Executable file → Normal file
@ -1,5 +1,21 @@
|
|||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright 2015 the original author or authors.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
##
|
##
|
||||||
## Gradle start up script for UN*X
|
## Gradle start up script for UN*X
|
||||||
@ -28,7 +44,7 @@ APP_NAME="Gradle"
|
|||||||
APP_BASE_NAME=`basename "$0"`
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
DEFAULT_JVM_OPTS=""
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD="maximum"
|
MAX_FD="maximum"
|
||||||
@ -109,8 +125,8 @@ if $darwin; then
|
|||||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# For Cygwin, switch paths to Windows format before running java
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
if $cygwin ; then
|
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
18
prototype/gradlew.bat
vendored
18
prototype/gradlew.bat
vendored
@ -1,3 +1,19 @@
|
|||||||
|
@rem
|
||||||
|
@rem Copyright 2015 the original author or authors.
|
||||||
|
@rem
|
||||||
|
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@rem you may not use this file except in compliance with the License.
|
||||||
|
@rem You may obtain a copy of the License at
|
||||||
|
@rem
|
||||||
|
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@rem
|
||||||
|
@rem Unless required by applicable law or agreed to in writing, software
|
||||||
|
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@rem See the License for the specific language governing permissions and
|
||||||
|
@rem limitations under the License.
|
||||||
|
@rem
|
||||||
|
|
||||||
@if "%DEBUG%" == "" @echo off
|
@if "%DEBUG%" == "" @echo off
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
@rem
|
@rem
|
||||||
@ -14,7 +30,7 @@ set APP_BASE_NAME=%~n0
|
|||||||
set APP_HOME=%DIRNAME%
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
set DEFAULT_JVM_OPTS=
|
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||||
|
|
||||||
@rem Find java.exe
|
@rem Find java.exe
|
||||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
INSERT INTO article_offers ("manufacturer", "article_number", "vat_percent", "should_be_advertised")
|
INSERT INTO article_offers ("manufacturer", "article_number", "price_per_unit_net", "title", "vat_percent", "should_be_advertised")
|
||||||
VALUES ("McDonalds", "1", 7, 1);
|
VALUES ("McDonalds", "1", 4242, "McPizza", 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")
|
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);
|
VALUES (1, 19.99, 10, 1, 15, "Huge Hamburger", "This huge Hamburger is awesome!", NULL);
|
||||||
|
@ -52,6 +52,12 @@ public class RequestController {
|
|||||||
return "login";
|
return "login";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!user.get().isActive) {
|
||||||
|
request.setAttribute("error", "User ist deaktiviert.");
|
||||||
|
response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
|
||||||
|
return "login";
|
||||||
|
}
|
||||||
|
|
||||||
session.setAttribute("userId", user.get().getId());
|
session.setAttribute("userId", user.get().getId());
|
||||||
|
|
||||||
if (gto != null && gto.startsWith("/")) {
|
if (gto != null && gto.startsWith("/")) {
|
||||||
@ -69,53 +75,11 @@ public class RequestController {
|
|||||||
return "redirect:/";
|
return "redirect:/";
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/register")
|
|
||||||
public String register() {
|
|
||||||
return "register";
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/register")
|
|
||||||
public String registerPost(
|
|
||||||
@RequestParam("username") String username,
|
|
||||||
@RequestParam("password") String password,
|
|
||||||
@RequestParam("password2") String password2,
|
|
||||||
@RequestParam("type") String type
|
|
||||||
) {
|
|
||||||
|
|
||||||
return "redirect:/";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/shop/search")
|
|
||||||
public String shopSearch() {
|
|
||||||
return "shop/search";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/intern/")
|
@GetMapping("/intern/")
|
||||||
public String intern() {
|
public String intern() {
|
||||||
return "intern/index";
|
return "intern/index";
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/intern/listedArticles/")
|
|
||||||
public String internListedArticles() {
|
|
||||||
return "intern/listedArticles/index";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/intern/listedArticles/{id}")
|
|
||||||
public String internListedArticlesId() {
|
|
||||||
return "intern/listedArticles/id";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@GetMapping("/intern/articles/")
|
|
||||||
public String internArticles() {
|
|
||||||
return "intern/articles/index";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/intern/articles/{id}")
|
|
||||||
public String internArticlesId() {
|
|
||||||
return "intern/articles/id";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/intern/customers/")
|
@GetMapping("/intern/customers/")
|
||||||
public String internCustomers() {
|
public String internCustomers() {
|
||||||
return "intern/customers/index";
|
return "intern/customers/index";
|
||||||
@ -155,6 +119,15 @@ public class RequestController {
|
|||||||
public String internSupplierOrdersId() {
|
public String internSupplierOrdersId() {
|
||||||
return "intern/supplierOrders/id";
|
return "intern/supplierOrders/id";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
@GetMapping("/intern/suppliersOffers")
|
||||||
|
public String internSuppliersOffers() {
|
||||||
|
return "intern/offeredArticles/index";
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
@GetMapping("/intern/accounting/")
|
@GetMapping("/intern/accounting/")
|
||||||
public String accounting() {
|
public String accounting() {
|
||||||
|
@ -24,6 +24,7 @@ public class LoginIntercepter implements HandlerInterceptor {
|
|||||||
|
|
||||||
HttpSession session = request.getSession();
|
HttpSession session = request.getSession();
|
||||||
Object userId = session.getAttribute("userId");
|
Object userId = session.getAttribute("userId");
|
||||||
|
Optional<User> user = null;
|
||||||
|
|
||||||
if (request.getRequestURI().startsWith("/user/")) {
|
if (request.getRequestURI().startsWith("/user/")) {
|
||||||
System.out.println("USER");
|
System.out.println("USER");
|
||||||
@ -43,10 +44,24 @@ public class LoginIntercepter implements HandlerInterceptor {
|
|||||||
response.sendRedirect("/login");
|
response.sendRedirect("/login");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
user = userRepository.findById((Long) userId);
|
||||||
|
|
||||||
|
if(user.isPresent() && !user.get().isEmployee)
|
||||||
|
{
|
||||||
|
session.setAttribute("afterLogin", request.getRequestURI());
|
||||||
|
response.sendRedirect("/");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!request.getRequestURI().startsWith("/login")) {
|
||||||
|
session.removeAttribute("afterLogin");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userId != null) {
|
if (userId != null) {
|
||||||
Optional<User> user = userRepository.findById((Long) userId);
|
if (user == null)
|
||||||
|
user = userRepository.findById((Long) userId);
|
||||||
user.ifPresent(value -> request.setAttribute("user", value));
|
user.ifPresent(value -> request.setAttribute("user", value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,74 @@
|
|||||||
|
package org.hso.ecommerce.controller;
|
||||||
|
|
||||||
|
import org.hso.ecommerce.entities.shop.Address;
|
||||||
|
import org.hso.ecommerce.entities.user.User;
|
||||||
|
import org.hso.ecommerce.repos.user.UserRepository;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class RegisterController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private final UserRepository userRepository = null;
|
||||||
|
|
||||||
|
@PostMapping("/register")
|
||||||
|
public String registerPost(
|
||||||
|
HttpServletRequest request,
|
||||||
|
HttpServletResponse response,
|
||||||
|
@RequestParam("username") String username,
|
||||||
|
@RequestParam("password") String password,
|
||||||
|
@RequestParam("password2") String password2,
|
||||||
|
@RequestParam("salutation") String salutation,
|
||||||
|
@RequestParam("name") String name,
|
||||||
|
@RequestParam("address") String address,
|
||||||
|
@RequestParam("type") String type,
|
||||||
|
@RequestParam("ad") String ad
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Optional<User> user = userRepository.findByEmail(username);
|
||||||
|
if (user.isPresent()) {
|
||||||
|
request.setAttribute("error", "Email Adresse existiert bereits!");
|
||||||
|
response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
|
||||||
|
return "register";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!password.equals(password2)){
|
||||||
|
request.setAttribute("error", "Passwörter sind nicht gleich");
|
||||||
|
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
||||||
|
return "register";
|
||||||
|
}
|
||||||
|
|
||||||
|
//set values for new user
|
||||||
|
User newUser = new User();
|
||||||
|
newUser.email = username;
|
||||||
|
newUser.setPassword(password);
|
||||||
|
newUser.email = username;
|
||||||
|
newUser.isEmployee = false;
|
||||||
|
//TODO for salutation, type, ad are no attributes/fields in the class/database. Add when they are there.
|
||||||
|
|
||||||
|
newUser.isActive = true;
|
||||||
|
newUser.created = new java.sql.Timestamp(System.currentTimeMillis());
|
||||||
|
|
||||||
|
Address newAddress = new Address();
|
||||||
|
newAddress.name = name;
|
||||||
|
newAddress.addressString = address;
|
||||||
|
newUser.defaultDeliveryAddress = newAddress;
|
||||||
|
|
||||||
|
userRepository.save(newUser); // save newUser
|
||||||
|
|
||||||
|
return "redirect:/login";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/register")
|
||||||
|
public String register() {
|
||||||
|
return "register";
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,364 @@
|
|||||||
package org.hso.ecommerce.controller.intern;
|
package org.hso.ecommerce.controller.intern;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
|
import org.hso.ecommerce.entities.shop.Article;
|
||||||
|
import org.hso.ecommerce.entities.shop.Category;
|
||||||
|
import org.hso.ecommerce.entities.shop.Image;
|
||||||
|
import org.hso.ecommerce.entities.supplier.ArticleOffer;
|
||||||
|
import org.hso.ecommerce.repos.shop.ArticleRepository;
|
||||||
|
import org.hso.ecommerce.repos.shop.CategoryRepository;
|
||||||
|
import org.hso.ecommerce.repos.shop.ImageRepository;
|
||||||
|
import org.hso.ecommerce.repos.shop.OffersRepository;
|
||||||
|
import org.hso.ecommerce.repos.warehouse.WarehouseBookingPositionSlotEntryRepository;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.util.DigestUtils;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.servlet.view.RedirectView;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
//@RequestMapping("...")
|
@RequestMapping("intern/articles")
|
||||||
public class InternArticleController {
|
public class InternArticleController {
|
||||||
|
@Autowired
|
||||||
|
private final ArticleRepository articleRepository = null;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private final WarehouseBookingPositionSlotEntryRepository warehouseEntryRepository = null;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private final CategoryRepository categoryRepository = null;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private final OffersRepository offersRepository = null;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private final ImageRepository imageRepository = null;
|
||||||
|
|
||||||
|
@GetMapping("/")
|
||||||
|
public String internListedArticles(Model model) {
|
||||||
|
|
||||||
|
List<UImodelArticles> totals = new ArrayList<UImodelArticles>();
|
||||||
|
|
||||||
|
for (Article article : articleRepository.findAll()) {
|
||||||
|
UImodelArticles tmp = new UImodelArticles();
|
||||||
|
tmp.addListedArticle(article, warehouseEntryRepository.getArticleStock(article.id).orElse(0));
|
||||||
|
totals.add(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
model.addAttribute("ListedArticles", totals);
|
||||||
|
return "intern/listedArticles/index";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public String internListedArticlesId(Model model, @PathVariable String id) {
|
||||||
|
|
||||||
|
int articleid = Integer.parseInt(id);
|
||||||
|
|
||||||
|
UImodelArticle total = new UImodelArticle();
|
||||||
|
|
||||||
|
total.addArticle(articleRepository.findArticleById(articleid),
|
||||||
|
warehouseEntryRepository.getArticleStock(articleid).orElse(0));
|
||||||
|
|
||||||
|
model.addAttribute("ArticleID", total);
|
||||||
|
|
||||||
|
return "intern/listedArticles/id";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/{id}/saveChanges")
|
||||||
|
public RedirectView saveChanges(@PathVariable(required = true) int id,
|
||||||
|
@RequestParam(value = "title", required = true) String title,
|
||||||
|
@RequestParam(value = "description", required = true) String description,
|
||||||
|
@RequestParam(value = "units-per-slot", required = true) String warehouseUnitsPerSlot,
|
||||||
|
@RequestParam(value = "price_netto", required = true) String pricenetto,
|
||||||
|
@RequestParam(value = "reorderMaxPrice", required = true) String reorderMaxPrice,
|
||||||
|
@RequestParam(value = "autobuy", required = true) Boolean shouldReorder,
|
||||||
|
@RequestParam(value = "categories", required = true) String categories,
|
||||||
|
@RequestParam(value = "img", required = true) MultipartFile imgFile) {
|
||||||
|
|
||||||
|
Article tmpArticle = articleRepository.findArticleById(id); // get the old article
|
||||||
|
|
||||||
|
String[] separatedCategories = categories.split("\n");
|
||||||
|
|
||||||
|
tmpArticle.categories.clear();
|
||||||
|
|
||||||
|
// loop through all categories strings and create a new category if a new one;
|
||||||
|
// also adds the categorys to the article
|
||||||
|
for (String category : separatedCategories) {
|
||||||
|
tmpArticle.categories.add(categoryRepository.findCategoryByName(category.trim())
|
||||||
|
.orElseGet(() -> new Category(category.trim())));
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpArticle.shouldReorder = shouldReorder;
|
||||||
|
tmpArticle.reorderMaxPrice = (int) (Float.parseFloat(reorderMaxPrice) * 100);
|
||||||
|
tmpArticle.shopPricePerUnitNetCent = (int) (Float.parseFloat(pricenetto) * 100);
|
||||||
|
tmpArticle.warehouseUnitsPerSlot = Integer.parseInt(warehouseUnitsPerSlot);
|
||||||
|
tmpArticle.title = title;
|
||||||
|
updateImage(tmpArticle, imgFile);
|
||||||
|
tmpArticle.description = description;
|
||||||
|
|
||||||
|
articleRepository.save(tmpArticle); // save updated article
|
||||||
|
return new RedirectView("../"); // return to overview page
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/addArticle/{id}")
|
||||||
|
public RedirectView addArticle(@PathVariable(required = true) String id) {
|
||||||
|
// article is not already listed, create new one
|
||||||
|
int offeredArticleID = Integer.parseInt(id);
|
||||||
|
|
||||||
|
Article tmpArticle = new Article();
|
||||||
|
|
||||||
|
ArticleOffer offeredArticle = offersRepository.findOfferedArticleById(offeredArticleID);
|
||||||
|
|
||||||
|
// set default values
|
||||||
|
tmpArticle.description = "";
|
||||||
|
tmpArticle.reorderMaxPrice = 0;
|
||||||
|
tmpArticle.shopPricePerUnitNetCent = offeredArticle.pricePerUnitNet;
|
||||||
|
tmpArticle.shouldReorder = false;
|
||||||
|
tmpArticle.title = offeredArticle.title;
|
||||||
|
tmpArticle.warehouseUnitsPerSlot = 1;
|
||||||
|
setDefaultImage(tmpArticle);
|
||||||
|
tmpArticle.related = offeredArticle;
|
||||||
|
articleRepository.save(tmpArticle); // save new article
|
||||||
|
|
||||||
|
// return to edit article page
|
||||||
|
return new RedirectView("../" + articleRepository.findArticleIDByRelatedID(offeredArticleID).get());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setDefaultImage(Article article) {
|
||||||
|
String defaultImagePath = "./data/img/no_product_img.jpg"; // path + name of default img
|
||||||
|
Optional<Integer> imageID = imageRepository.findImageIDByPath(defaultImagePath); // get default img
|
||||||
|
|
||||||
|
if (imageID.isPresent()) {
|
||||||
|
// default img is in DB
|
||||||
|
article.image = imageRepository.findImageById(imageID.get()); // set default img to new article
|
||||||
|
} else {
|
||||||
|
// default img is not in DB
|
||||||
|
File tmpFile = new File(defaultImagePath);
|
||||||
|
// test if default img file exits
|
||||||
|
if (!tmpFile.exists()) {
|
||||||
|
// fallback if the file not exists
|
||||||
|
// create new file
|
||||||
|
BufferedImage bufferedImage = new BufferedImage(422, 428, BufferedImage.TYPE_INT_RGB);
|
||||||
|
try {
|
||||||
|
ImageIO.write(bufferedImage, "jpg", new File(defaultImagePath)); // save new file on disk
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Image defaultImage = new Image();
|
||||||
|
defaultImage.path = defaultImagePath; // set new file to default img
|
||||||
|
imageRepository.save(defaultImage); // save default img
|
||||||
|
article.image = defaultImage; // set default img to new article
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateImage(Article article, MultipartFile imgFile) {
|
||||||
|
// check if a file is present
|
||||||
|
if (imgFile.getSize() > 0) {
|
||||||
|
try {
|
||||||
|
// get file name based on MD5 hash
|
||||||
|
String fileName = DigestUtils.md5DigestAsHex(imgFile.getBytes()) + ".jpg";
|
||||||
|
// check if img is already in system
|
||||||
|
Optional<Integer> imageID = imageRepository.findImageIDByPath("./data/img/" + fileName);
|
||||||
|
if (imageID.isPresent()) {
|
||||||
|
article.image = imageRepository.findImageById(imageID.get()); // add existing img to article
|
||||||
|
} else {
|
||||||
|
// write new img file to disk
|
||||||
|
Files.newOutputStream(Paths.get("./data/img/", fileName)).write(imgFile.getBytes());
|
||||||
|
// create new img
|
||||||
|
Image newImage = new Image();
|
||||||
|
newImage.path = "./data/img/" + fileName; // set new file to new img
|
||||||
|
imageRepository.save(newImage); // save new img
|
||||||
|
article.image = newImage; // set new img to article
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
setDefaultImage(article); // if upload failed, reset to default img
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class UImodelArticles {
|
||||||
|
|
||||||
|
public String imgPath;
|
||||||
|
|
||||||
|
public String title;
|
||||||
|
|
||||||
|
public String price;
|
||||||
|
|
||||||
|
public String price_netto;
|
||||||
|
|
||||||
|
public String categorie;
|
||||||
|
|
||||||
|
public int stock;
|
||||||
|
|
||||||
|
public long offer_id;
|
||||||
|
|
||||||
|
public long id;
|
||||||
|
|
||||||
|
void addListedArticle(Article article, int stock) {
|
||||||
|
this.imgPath = article.image.path;
|
||||||
|
this.title = article.title;
|
||||||
|
this.price_netto = String.format("%.2f", ((float) article.shopPricePerUnitNetCent / 100));
|
||||||
|
this.price = String.format("%.2f", ((float) article.getPriceGross() / 100));
|
||||||
|
|
||||||
|
StringBuilder result = new StringBuilder();
|
||||||
|
|
||||||
|
for (Category temp : article.categories) {
|
||||||
|
result.append(temp.name + " ");
|
||||||
|
}
|
||||||
|
this.categorie = result.toString();
|
||||||
|
|
||||||
|
this.stock = stock;
|
||||||
|
this.offer_id = article.related.id;
|
||||||
|
this.id = article.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class UImodelArticle {
|
||||||
|
|
||||||
|
public String imgPath;
|
||||||
|
public String title;
|
||||||
|
public String price;
|
||||||
|
public String price_netto;
|
||||||
|
public String reorderMaxPrice;
|
||||||
|
public String categorie;
|
||||||
|
public int stock;
|
||||||
|
public long offer_id;
|
||||||
|
public long id;
|
||||||
|
public boolean shouldReorder;
|
||||||
|
public String warehouseUnitsPerSlot;
|
||||||
|
public String description;
|
||||||
|
|
||||||
|
public String getImgPath() {
|
||||||
|
return imgPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setImgPath(String imgPath) {
|
||||||
|
this.imgPath = imgPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPrice() {
|
||||||
|
return price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrice(String price) {
|
||||||
|
this.price = price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPrice_netto() {
|
||||||
|
return price_netto;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrice_netto(String price_netto) {
|
||||||
|
this.price_netto = price_netto;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReorderMaxPrice() {
|
||||||
|
return reorderMaxPrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReorderMaxPrice(String reorderMaxPrice) {
|
||||||
|
this.reorderMaxPrice = reorderMaxPrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCategorie() {
|
||||||
|
return categorie;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCategorie(String categorie) {
|
||||||
|
this.categorie = categorie;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStock() {
|
||||||
|
return stock;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStock(int stock) {
|
||||||
|
this.stock = stock;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getOffer_id() {
|
||||||
|
return offer_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOffer_id(long offer_id) {
|
||||||
|
this.offer_id = offer_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isShouldReorder() {
|
||||||
|
return shouldReorder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setShouldReorder(boolean shouldReorder) {
|
||||||
|
this.shouldReorder = shouldReorder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getWarehouseUnitsPerSlot() {
|
||||||
|
return warehouseUnitsPerSlot;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWarehouseUnitsPerSlot(String warehouseUnitsPerSlot) {
|
||||||
|
this.warehouseUnitsPerSlot = warehouseUnitsPerSlot;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addArticle(Article article, int stock) {
|
||||||
|
this.imgPath = article.image.path;
|
||||||
|
this.title = article.title;
|
||||||
|
this.price_netto = String.format("%.2f", ((float) article.shopPricePerUnitNetCent / 100));
|
||||||
|
this.price = String.format("%.2f", ((float) article.getPriceGross() / 100));
|
||||||
|
|
||||||
|
StringBuilder result = new StringBuilder();
|
||||||
|
|
||||||
|
for (Category temp : article.categories) {
|
||||||
|
result.append(temp.name);
|
||||||
|
result.append("\n");
|
||||||
|
}
|
||||||
|
this.categorie = result.toString();
|
||||||
|
|
||||||
|
this.stock = stock;
|
||||||
|
this.offer_id = article.related.id;
|
||||||
|
this.id = article.id;
|
||||||
|
this.reorderMaxPrice = String.format("%.2f", ((float) article.reorderMaxPrice / 100));
|
||||||
|
this.shouldReorder = article.shouldReorder;
|
||||||
|
this.warehouseUnitsPerSlot = String.valueOf(article.warehouseUnitsPerSlot);
|
||||||
|
this.description = article.description;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,156 @@
|
|||||||
package org.hso.ecommerce.controller.intern.suppliers;
|
package org.hso.ecommerce.controller.intern.suppliers;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.hso.ecommerce.entities.supplier.ArticleOffer;
|
||||||
|
import org.hso.ecommerce.repos.shop.ArticleRepository;
|
||||||
|
import org.hso.ecommerce.repos.shop.OffersRepository;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
//@RequestMapping("...")
|
@RequestMapping("/intern/")
|
||||||
public class SupplierOfferController {
|
public class SupplierOfferController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private final OffersRepository offersRepository = null;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private final ArticleRepository articleRepository = null;
|
||||||
|
|
||||||
|
@GetMapping("supplierOffers")
|
||||||
|
public String internListedArticles(Model model) {
|
||||||
|
|
||||||
|
List<UImodelOfferedArticle> totals = new ArrayList<UImodelOfferedArticle>();
|
||||||
|
|
||||||
|
for (ArticleOffer article : offersRepository.findAll()) {
|
||||||
|
UImodelOfferedArticle tmp = new UImodelOfferedArticle();
|
||||||
|
tmp.addData(article, "supplierName01", 4884, articleRepository.findArticleIDByRelatedID(article.id)); //TODO display supplier name with link
|
||||||
|
totals.add(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
model.addAttribute("OfferedArticles", totals);
|
||||||
|
return "intern/offeredArticles/index";
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UImodelOfferedArticle {
|
||||||
|
|
||||||
|
long offer_id;
|
||||||
|
String title;
|
||||||
|
String manufacturer;
|
||||||
|
String articlenumber;
|
||||||
|
String supplierName;
|
||||||
|
int supplierId;
|
||||||
|
String price;
|
||||||
|
String ads;
|
||||||
|
int listedArticleId;
|
||||||
|
boolean offerIsListed; //true --> offered article is listed
|
||||||
|
|
||||||
|
public long getOffer_id() {
|
||||||
|
return offer_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOffer_id(long offer_id) {
|
||||||
|
this.offer_id = offer_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOfferIsListed() {
|
||||||
|
return offerIsListed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOfferIsListed(boolean offerIsListed) {
|
||||||
|
this.offerIsListed = offerIsListed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getManufacturer() {
|
||||||
|
return manufacturer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setManufacturer(String manufacturer) {
|
||||||
|
this.manufacturer = manufacturer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getArticlenumber() {
|
||||||
|
return articlenumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setArticlenumber(String articlenumber) {
|
||||||
|
this.articlenumber = articlenumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSupplierName() {
|
||||||
|
return supplierName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSupplierName(String supplierName) {
|
||||||
|
this.supplierName = supplierName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSupplierId() {
|
||||||
|
return supplierId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSupplierId(int supplierId) {
|
||||||
|
this.supplierId = supplierId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPrice() {
|
||||||
|
return price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrice(String price) {
|
||||||
|
this.price = price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAds() {
|
||||||
|
return ads;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAds(String ads) {
|
||||||
|
this.ads = ads;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getListedArticleId() {
|
||||||
|
return listedArticleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setListedArticleId(int listedArticleId) {
|
||||||
|
this.listedArticleId = listedArticleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addData(ArticleOffer article, String supplierName, int supplierId,
|
||||||
|
Optional<Integer> listedArticleId) {
|
||||||
|
|
||||||
|
this.offer_id = article.id;
|
||||||
|
this.title = article.title;
|
||||||
|
this.manufacturer = article.manufacturer;
|
||||||
|
this.articlenumber = article.articleNumber;
|
||||||
|
this.supplierName = supplierName;
|
||||||
|
this.supplierId = supplierId;
|
||||||
|
this.price = String.format("%.2f", ((float) article.pricePerUnitNet / 100));
|
||||||
|
this.ads = (article.shouldBeAdvertised) ? "Ja" : "Nein";
|
||||||
|
|
||||||
|
if (listedArticleId.isPresent()) {
|
||||||
|
// this offer is listed --> show link
|
||||||
|
this.listedArticleId = listedArticleId.get();
|
||||||
|
offerIsListed = true;
|
||||||
|
} else {
|
||||||
|
// this offer is not listed
|
||||||
|
offerIsListed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import org.hso.ecommerce.action.shop.GetRandomArticlesAction;
|
|||||||
import org.hso.ecommerce.entities.shop.Article;
|
import org.hso.ecommerce.entities.shop.Article;
|
||||||
import org.hso.ecommerce.entities.shop.ShoppingCart;
|
import org.hso.ecommerce.entities.shop.ShoppingCart;
|
||||||
import org.hso.ecommerce.repos.shop.ArticleRepository;
|
import org.hso.ecommerce.repos.shop.ArticleRepository;
|
||||||
|
import org.hso.ecommerce.repos.shop.CategoryRepository;
|
||||||
import org.hso.ecommerce.repos.warehouse.WarehouseBookingPositionSlotEntryRepository;
|
import org.hso.ecommerce.repos.warehouse.WarehouseBookingPositionSlotEntryRepository;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
@ -30,12 +31,17 @@ public class ShopArticleController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private final WarehouseBookingPositionSlotEntryRepository warehouseBookingPositionSlotEntryRepository = null;
|
private final WarehouseBookingPositionSlotEntryRepository warehouseBookingPositionSlotEntryRepository = null;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private final CategoryRepository categoryRepository = null;
|
||||||
|
|
||||||
@GetMapping("/{id}")
|
@GetMapping("/{id}")
|
||||||
public String shopArticlesById(Model model,
|
public String shopArticlesById(Model model,
|
||||||
@PathVariable("id") Long id,
|
@PathVariable("id") Long id,
|
||||||
HttpServletRequest request,
|
HttpServletRequest request,
|
||||||
HttpServletResponse response
|
HttpServletResponse response
|
||||||
) {
|
) {
|
||||||
|
model.addAttribute("categories", categoryRepository.getCategories()); //for sidebar
|
||||||
|
|
||||||
Article article = articleRepository.findArticleById(id);
|
Article article = articleRepository.findArticleById(id);
|
||||||
|
|
||||||
if (article == null) {
|
if (article == null) {
|
||||||
@ -45,14 +51,13 @@ public class ShopArticleController {
|
|||||||
}
|
}
|
||||||
model.addAttribute("article", article);
|
model.addAttribute("article", article);
|
||||||
|
|
||||||
//if (warehouseBookingPositionSlotEntryRepository.getByArticle(id).get(0).newSumSlot > 0) { //TODO: use this as soon as warehouse works
|
if (warehouseBookingPositionSlotEntryRepository.getByArticle(id).get(0).newSumSlot > 0) { //check if in Stock
|
||||||
if (true) {
|
|
||||||
model.addAttribute("inStock", true);
|
model.addAttribute("inStock", true);
|
||||||
} else {
|
} else {
|
||||||
model.addAttribute("inStock", false);
|
model.addAttribute("inStock", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Article> commercialArticles = GetRandomArticlesAction.getRandomArticles(3, articleRepository.getAdvertisedArticles());
|
List<Article> commercialArticles = GetRandomArticlesAction.getRandomArticles(3, articleRepository.getAdvertisedArticles()); //get 3 advertised Articles
|
||||||
model.addAttribute("commercialArticles", commercialArticles);
|
model.addAttribute("commercialArticles", commercialArticles);
|
||||||
|
|
||||||
return "shop/articles/id";
|
return "shop/articles/id";
|
||||||
@ -99,5 +104,4 @@ public class ShopArticleController {
|
|||||||
response.setContentType(MediaType.IMAGE_JPEG_VALUE);
|
response.setContentType(MediaType.IMAGE_JPEG_VALUE);
|
||||||
IOUtils.copy(in, response.getOutputStream());
|
IOUtils.copy(in, response.getOutputStream());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3,6 +3,7 @@ package org.hso.ecommerce.controller.shop;
|
|||||||
import org.hso.ecommerce.action.shop.GetRandomArticlesAction;
|
import org.hso.ecommerce.action.shop.GetRandomArticlesAction;
|
||||||
import org.hso.ecommerce.entities.shop.Article;
|
import org.hso.ecommerce.entities.shop.Article;
|
||||||
import org.hso.ecommerce.repos.shop.ArticleRepository;
|
import org.hso.ecommerce.repos.shop.ArticleRepository;
|
||||||
|
import org.hso.ecommerce.repos.warehouse.WarehouseBookingPositionSlotEntryRepository;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
@ -19,6 +20,9 @@ public class ShopIndexController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private final ArticleRepository articleRepository = null;
|
private final ArticleRepository articleRepository = null;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private final WarehouseBookingPositionSlotEntryRepository warehouseBookingPositionSlotEntryRepository = null;
|
||||||
|
|
||||||
@GetMapping("/")
|
@GetMapping("/")
|
||||||
public String home() {
|
public String home() {
|
||||||
return "redirect:/shop/";
|
return "redirect:/shop/";
|
||||||
@ -27,18 +31,18 @@ public class ShopIndexController {
|
|||||||
@GetMapping("/shop/")
|
@GetMapping("/shop/")
|
||||||
public String shop(Model model, HttpSession session) {
|
public String shop(Model model, HttpSession session) {
|
||||||
|
|
||||||
List<Article> commercialArticles = GetRandomArticlesAction.getRandomArticles(8, articleRepository.getAdvertisedArticles());
|
List<Article> commercialArticles = GetRandomArticlesAction.getRandomArticles(8, articleRepository.getAdvertisedArticles()); //get random advertised Articles
|
||||||
model.addAttribute("commercialArticles", commercialArticles);
|
model.addAttribute("commercialArticles", commercialArticles);
|
||||||
|
|
||||||
boolean isLoggedIn = false;
|
boolean isLoggedIn = false;
|
||||||
boolean hasOrders = false;
|
boolean hasOrders = false;
|
||||||
|
|
||||||
if (session != null && session.getAttribute("userId") != null) {
|
if (session != null && session.getAttribute("userId") != null) { //check if logged in
|
||||||
long userId = (long) session.getAttribute("userId");
|
long userId = (long) session.getAttribute("userId");
|
||||||
isLoggedIn = true;
|
isLoggedIn = true;
|
||||||
|
|
||||||
List<Article> suggestedArticles = articleRepository.getOrderedArticles(userId);
|
List<Article> suggestedArticles = articleRepository.getOrderedArticles(userId);
|
||||||
suggestedArticles = suggestedArticles.size() > 3 ? suggestedArticles.subList(0, 4) : suggestedArticles; //only latest 4 articles
|
suggestedArticles = suggestedArticles.size() > 3 ? suggestedArticles.subList(0, 4) : suggestedArticles; //only latest 4 ordered articles
|
||||||
if (suggestedArticles.size() > 0) {
|
if (suggestedArticles.size() > 0) {
|
||||||
model.addAttribute("suggestedArticles", suggestedArticles);
|
model.addAttribute("suggestedArticles", suggestedArticles);
|
||||||
hasOrders = true;
|
hasOrders = true;
|
||||||
@ -65,5 +69,4 @@ public class ShopIndexController {
|
|||||||
public String privacy() {
|
public String privacy() {
|
||||||
return "privacy";
|
return "privacy";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,48 @@
|
|||||||
package org.hso.ecommerce.controller.shop;
|
package org.hso.ecommerce.controller.shop;
|
||||||
|
|
||||||
|
import org.hso.ecommerce.entities.shop.Article;
|
||||||
|
import org.hso.ecommerce.repos.shop.ArticleRepository;
|
||||||
|
import org.hso.ecommerce.repos.shop.CategoryRepository;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
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 java.util.List;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
//@RequestMapping("...")
|
@RequestMapping("/shop/search")
|
||||||
public class ShopSearchController {
|
public class ShopSearchController {
|
||||||
}
|
|
||||||
|
@Autowired
|
||||||
|
private final ArticleRepository articleRepository = null;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private final CategoryRepository categoryRepository = null;
|
||||||
|
|
||||||
|
@GetMapping("")
|
||||||
|
public String searchArticles(@RequestParam(required = false, value = "term") String term,
|
||||||
|
@RequestParam(required = false, value = "category") String category,
|
||||||
|
Model model,
|
||||||
|
HttpServletRequest request,
|
||||||
|
HttpServletResponse response
|
||||||
|
) {
|
||||||
|
model.addAttribute("categories", categoryRepository.getCategories()); //for sidebar
|
||||||
|
|
||||||
|
if (term != null) { //if search by Term
|
||||||
|
List<Article> articles = articleRepository.getArticlesByTerm(term); //search by Term
|
||||||
|
model.addAttribute("articles", articles);
|
||||||
|
} else if (category != null) { //if search by Category
|
||||||
|
List<Article> articles = articleRepository.getArticlesByCategory(category); //search by Category
|
||||||
|
model.addAttribute("articles", articles);
|
||||||
|
} else {
|
||||||
|
request.setAttribute("error", "Es wurden keine Suchparameter angegeben.");
|
||||||
|
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
||||||
|
return "error/404";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "/shop/search";
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,10 @@
|
|||||||
package org.hso.ecommerce.entities.booking;
|
package org.hso.ecommerce.entities.booking;
|
||||||
|
|
||||||
import javax.persistence.Embeddable;
|
import javax.persistence.Embeddable;
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
|
|
||||||
@Embeddable
|
@Embeddable
|
||||||
public class PaymentMethod {
|
public class PaymentMethod {
|
||||||
@NotNull
|
|
||||||
public String creditCardNumber;
|
public String creditCardNumber;
|
||||||
|
|
||||||
public static PaymentMethod fromCreditCarNumber(String cardnumber) {
|
public static PaymentMethod fromCreditCarNumber(String cardnumber) {
|
||||||
|
@ -35,7 +35,7 @@ public class Article {
|
|||||||
@Basic(fetch = FetchType.LAZY)
|
@Basic(fetch = FetchType.LAZY)
|
||||||
public Image image;
|
public Image image;
|
||||||
|
|
||||||
@ManyToMany
|
@ManyToMany(cascade = CascadeType.ALL)
|
||||||
@JoinTable(name = "article_categories_bindings")
|
@JoinTable(name = "article_categories_bindings")
|
||||||
public Set<Category> categories = new HashSet<>();
|
public Set<Category> categories = new HashSet<>();
|
||||||
|
|
||||||
@ -46,4 +46,4 @@ public class Article {
|
|||||||
public int getPriceGross() {
|
public int getPriceGross() {
|
||||||
return shopPricePerUnitNetCent + getVat();
|
return shopPricePerUnitNetCent + getVat();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,7 +1,5 @@
|
|||||||
package org.hso.ecommerce.entities.shop;
|
package org.hso.ecommerce.entities.shop;
|
||||||
|
|
||||||
import org.hso.ecommerce.entities.shop.Article;
|
|
||||||
|
|
||||||
import javax.persistence.*;
|
import javax.persistence.*;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -22,4 +20,15 @@ public class Category {
|
|||||||
|
|
||||||
@ManyToMany(mappedBy = "categories")
|
@ManyToMany(mappedBy = "categories")
|
||||||
public Set<Article> articles = new HashSet<>();
|
public Set<Article> articles = new HashSet<>();
|
||||||
|
|
||||||
|
|
||||||
|
public Category() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Category (String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,12 @@ public class ArticleOffer {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public String manufacturer;
|
public String manufacturer;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public String title;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public int pricePerUnitNet;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public String articleNumber;
|
public String articleNumber;
|
||||||
@ -21,4 +27,6 @@ public class ArticleOffer {
|
|||||||
public int vatPercent;
|
public int vatPercent;
|
||||||
|
|
||||||
public boolean shouldBeAdvertised;
|
public boolean shouldBeAdvertised;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,21 +7,32 @@ import org.springframework.data.repository.query.Param;
|
|||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
public interface ArticleRepository extends JpaRepository<Article, Long> {
|
public interface ArticleRepository extends JpaRepository<Article, Long> {
|
||||||
|
|
||||||
@Query("SELECT a FROM Article a WHERE a.id = :articleId")
|
@Query("SELECT a FROM Article a WHERE a.id = :articleId")
|
||||||
Article findArticleById(@Param("articleId") long articleId);
|
Article findArticleById(@Param("articleId") long articleId);
|
||||||
|
|
||||||
|
@Query("SELECT a FROM Article a")
|
||||||
|
List<Article> findAll();
|
||||||
|
|
||||||
@Query("SELECT a FROM Article a JOIN a.related ao WHERE ao.shouldBeAdvertised = true")
|
@Query(value = "Select a.* from articles as a, article_offers as ao, warehouse_booking_position_entries as wbpe where a.related_id = ao.id and wbpe.article_id = a.id and ao.should_be_advertised = true group by wbpe.slot_id having max(wbpe.id) and wbpe.new_sum_slot != 0", nativeQuery = true)
|
||||||
List<Article> getAdvertisedArticles();
|
List<Article> getAdvertisedArticles();
|
||||||
|
|
||||||
|
@Query("SELECT a FROM CustomerOrderPosition cop JOIN cop.order co JOIN co.customer c JOIN cop.article a ORDER BY co.id DESC")
|
||||||
|
List<Article> getOrderedArticles();
|
||||||
|
|
||||||
@Query("SELECT a FROM CustomerOrderPosition cop JOIN cop.order co JOIN co.customer c JOIN cop.article a WHERE c.id = :customerId ORDER BY co.id DESC")
|
@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);
|
List<Article> getOrderedArticles(long customerId);
|
||||||
|
|
||||||
|
@Query(value = "SELECT a.id FROM articles a WHERE a.related_id = :relatedId", nativeQuery = true)
|
||||||
|
Optional<Integer> findArticleIDByRelatedID(@Param("relatedId") long relatedId);
|
||||||
|
|
||||||
|
@Query(value = "Select a.* from articles as a, warehouse_booking_position_entries as wbpe where wbpe.article_id = a.id and a.title LIKE %:term% group by wbpe.slot_id having max(wbpe.id) and wbpe.new_sum_slot != 0", nativeQuery = true)
|
||||||
|
List<Article> getArticlesByTerm(String term);
|
||||||
|
|
||||||
}
|
@Query(value = "Select a.* from articles as a, categories as c, article_categories_bindings as acb, warehouse_booking_position_entries as wbpe where wbpe.article_id = a.id and acb.articles_id = a.id and acb.categories_id = c.id and c.name = :category group by wbpe.slot_id having max(wbpe.id) and wbpe.new_sum_slot != 0", nativeQuery = true)
|
||||||
|
List<Article> getArticlesByCategory(String category);
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package org.hso.ecommerce.repos.shop;
|
||||||
|
|
||||||
|
import org.hso.ecommerce.entities.shop.Category;
|
||||||
|
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;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface CategoryRepository extends JpaRepository<Category, Long> {
|
||||||
|
|
||||||
|
@Query("SELECT a FROM Category a WHERE a.name = :name")
|
||||||
|
Optional<Category> findCategoryByName(@Param("name") String name);
|
||||||
|
|
||||||
|
@Query("SELECT c FROM Category c")
|
||||||
|
List<Category> getCategories();
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package org.hso.ecommerce.repos.shop;
|
||||||
|
|
||||||
|
import org.hso.ecommerce.entities.shop.Image;
|
||||||
|
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.Optional;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface ImageRepository extends JpaRepository<Image, Long> {
|
||||||
|
|
||||||
|
@Query("SELECT i.id FROM Image i WHERE i.path = :path")
|
||||||
|
Optional<Integer> findImageIDByPath(@Param("path") String path);
|
||||||
|
|
||||||
|
@Query("SELECT i FROM Image i WHERE i.id = :imageId")
|
||||||
|
Image findImageById(@Param("imageId") long imageId);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package org.hso.ecommerce.repos.shop;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hso.ecommerce.entities.supplier.ArticleOffer;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
|
import org.springframework.data.repository.query.Param;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface OffersRepository extends JpaRepository<ArticleOffer, Long> {
|
||||||
|
|
||||||
|
@Query("SELECT a FROM ArticleOffer a")
|
||||||
|
List<ArticleOffer> findAll();
|
||||||
|
|
||||||
|
@Query("SELECT a FROM ArticleOffer a WHERE a.id = :offeredarticleId")
|
||||||
|
ArticleOffer findOfferedArticleById(@Param("offeredarticleId") long offeredarticleId);
|
||||||
|
|
||||||
|
}
|
@ -6,12 +6,17 @@ import org.springframework.data.jpa.repository.Query;
|
|||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
public interface WarehouseBookingPositionSlotEntryRepository extends JpaRepository<WarehouseBookingPositionSlotEntry, Long> {
|
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)
|
@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);
|
List<WarehouseBookingPositionSlotEntry> getByArticle(long article);
|
||||||
|
|
||||||
|
|
||||||
|
@Query(value = "SELECT SUM(w.new_sum_slot) FROM warehouse_booking_position_entries as w WHERE w.article_id = :articleid", nativeQuery = true)
|
||||||
|
Optional<Integer> getArticleStock(long articleid);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,8 @@ spring.jpa.show-sql=true
|
|||||||
#server.servlet.session.persistent=true
|
#server.servlet.session.persistent=true
|
||||||
# ----------------------------------------
|
# ----------------------------------------
|
||||||
# WEB PROPERTIES
|
# WEB PROPERTIES
|
||||||
|
spring.servlet.multipart.max-file-size=10MB
|
||||||
|
spring.servlet.multipart.max-request-size=10MB
|
||||||
# ----------------------------------------
|
# ----------------------------------------
|
||||||
# EMBEDDED SERVER CONFIGURATION (ServerProperties)
|
# EMBEDDED SERVER CONFIGURATION (ServerProperties)
|
||||||
server.address=::1
|
server.address=::1
|
||||||
|
@ -278,7 +278,7 @@ img.s {
|
|||||||
}
|
}
|
||||||
|
|
||||||
img.m {
|
img.m {
|
||||||
width: var(--u8);
|
width: 20rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -11,7 +11,7 @@
|
|||||||
<div class='content-width bar-flex'>
|
<div class='content-width bar-flex'>
|
||||||
<a class="button no-padding" href="/"><img class="logo" th:src="@{/img/ecom-logo-base.svg}"></a>
|
<a class="button no-padding" href="/"><img class="logo" th:src="@{/img/ecom-logo-base.svg}"></a>
|
||||||
<form class='spacer input-icon secondary' th:action="@{/shop/search}" method="GET">
|
<form class='spacer input-icon secondary' th:action="@{/shop/search}" method="GET">
|
||||||
<input type="text" placeholder="Nach Produkten suchen..."/>
|
<input type="text" name="term" placeholder="Nach Produkten suchen..."/>
|
||||||
<button>Finden</button>
|
<button>Finden</button>
|
||||||
</form>
|
</form>
|
||||||
<a th:unless="${user}" class="button" th:href="@{/login}">Login</a>
|
<a th:unless="${user}" class="button" th:href="@{/login}">Login</a>
|
||||||
@ -38,7 +38,6 @@
|
|||||||
function toggle(id) {
|
function toggle(id) {
|
||||||
document.getElementById(id).classList.toggle("invisible");
|
document.getElementById(id).classList.toggle("invisible");
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<a class="secondary button error" href="javascript:void(0)" onclick="toggle('error-msg');">X</a>
|
<a class="secondary button error" href="javascript:void(0)" onclick="toggle('error-msg');">X</a>
|
||||||
</div>
|
</div>
|
||||||
@ -54,7 +53,6 @@
|
|||||||
function toggle(id) {
|
function toggle(id) {
|
||||||
document.getElementById(id).classList.toggle("invisible");
|
document.getElementById(id).classList.toggle("invisible");
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<a class="secondary button info" href="javascript:void(0)" onclick="toggle('info-msg');">X</a>
|
<a class="secondary button info" href="javascript:void(0)" onclick="toggle('info-msg');">X</a>
|
||||||
</div>
|
</div>
|
||||||
@ -62,5 +60,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
@ -13,11 +13,7 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<li><a th:href="@{/intern/}">Dashboard</a>
|
<li><a th:href="@{/intern/}">Dashboard</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a th:href="@{/intern/listedArticles/}">Gelistete Artikel</a>
|
<li><a th:href="@{/intern/articles/}">Gelistete Artikel</a>
|
||||||
<ul>
|
|
||||||
<li><a th:href="@{/intern/articles/}">Händlerangebote</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
</li>
|
||||||
<li><a th:href="@{/intern/accounting/}">Alle Buchungen</a>
|
<li><a th:href="@{/intern/accounting/}">Alle Buchungen</a>
|
||||||
<ul>
|
<ul>
|
||||||
@ -38,7 +34,7 @@
|
|||||||
<li><a th:href="@{/intern/suppliers/}">Lieferanten</a>
|
<li><a th:href="@{/intern/suppliers/}">Lieferanten</a>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a th:href="@{/intern/supplierOrders/}">Bestellungen</a></li>
|
<li><a th:href="@{/intern/supplierOrders/}">Bestellungen</a></li>
|
||||||
<li><a th:href="@{/intern/articles/}">> Händlerangebote</a></li>
|
<li><a th:href="@{/intern/supplierOffers}">> Händlerangebote</a></li>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
@ -7,15 +7,10 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<nav th:fragment="sidebar">
|
<nav th:fragment="sidebar (categories)">
|
||||||
<h1>Kategorien</h1>
|
<h1>Kategorien</h1>
|
||||||
<ul class="secondary">
|
<ul class="secondary">
|
||||||
<li><a href="/shop/search">Aufnahmegeräte</a></li>
|
<li th:each="category: ${categories}"><a th:href="@{/shop/search(category=${category.name})}" th:text="${category.name}"></a></li>
|
||||||
<li><a href="/shop/search">Computer</a></li>
|
|
||||||
<li><a href="/shop/search">Fernseher</a></li>
|
|
||||||
<li><a href="/shop/search">Handys</a></li>
|
|
||||||
<li><a href="/shop/search">Unterhaltungselektronik</a></li>
|
|
||||||
<li><a href="/shop/search">Sonstiges</a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
</body>
|
</body>
|
||||||
|
@ -1,140 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="de" dir="ltr" xmlns:th="http://www.thymeleaf.org">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=0.75, user-scalable=no">
|
|
||||||
|
|
||||||
<title>Händlerangebote</title>
|
|
||||||
<script th:src="@{/js/filterTable.js}"></script>
|
|
||||||
<link rel="stylesheet" th:href="@{/css/ecom.css}"/>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<nav th:replace="fragments/header :: header">Header</nav>
|
|
||||||
<div class="sidebar-layout content-width">
|
|
||||||
<nav></nav>
|
|
||||||
<div>
|
|
||||||
<h1>Übersicht der von Lieferanten angebotenen Artikel</h1>
|
|
||||||
|
|
||||||
<script th:src="@{/js/back.js}"></script>
|
|
||||||
<div class="back" data-group="intern" data-name="Zurück zur Übersicht der von Lieferanten angebotenen Artikel."
|
|
||||||
data-insert="false"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<main class="sidebar-layout content-width">
|
|
||||||
<nav th:replace="fragments/intern :: sidebar"></nav>
|
|
||||||
<div class="content-width">
|
|
||||||
<p>
|
|
||||||
<table id="main-table">
|
|
||||||
<tr>
|
|
||||||
<th colspan="7">
|
|
||||||
<input type="text" placeholder="Filtern" class="smaller jsFilterTable full-width"
|
|
||||||
data-target-id="main-table"></input>
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Name</th>
|
|
||||||
<th>Hersteller</th>
|
|
||||||
<th>Artikelnummer</th>
|
|
||||||
<th>Lieferant</th>
|
|
||||||
<th>Kaufpreis (Netto)</th>
|
|
||||||
<th>Werbungs-<br/>anfrage</th>
|
|
||||||
<th>Status</th>
|
|
||||||
</tr>
|
|
||||||
<!--**********************************************************-->
|
|
||||||
<tr data-group="5420">
|
|
||||||
<td>Kamera</td>
|
|
||||||
<td>Sonjizu</td>
|
|
||||||
<td>K48431587EX</td>
|
|
||||||
<td colspan="3"></td>
|
|
||||||
<td><a th:href="@{/intern/listedArticles/48670}">Gelistet 44048</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr data-group="5420">
|
|
||||||
<td colspan="3"></td>
|
|
||||||
<td><a th:href="@{/intern/suppliers/48670}">Hans Guck GmbH</a></td>
|
|
||||||
<td>584,50 EUR</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr data-group="5420">
|
|
||||||
<td colspan="3"></td>
|
|
||||||
<td><a th:href="@{/intern/suppliers/48670}">Cheap AG</a></td>
|
|
||||||
<td>84,54 EUR</td>
|
|
||||||
<td>X</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr data-group="5420">
|
|
||||||
<td colspan="3"></td>
|
|
||||||
<td><a th:href="@{/intern/suppliers/48670}">Not Cheap AG</a></td>
|
|
||||||
<td>184,54 EUR</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<!--**********************************************************-->
|
|
||||||
<tr data-group="1233">
|
|
||||||
<td>Earbuds</td>
|
|
||||||
<td>Sonjizu</td>
|
|
||||||
<td>G447#$X</td>
|
|
||||||
<td colspan="3"></td>
|
|
||||||
<td><a th:href="@{/intern/listedArticles/48670}">Gelistet 448</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr data-group="1233">
|
|
||||||
<td colspan="3"></td>
|
|
||||||
<td><a th:href="@{/intern/suppliers/48670}">Cheap AG</a></td>
|
|
||||||
<td>50,54 EUR</td>
|
|
||||||
<td>X</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
|
|
||||||
<!--**********************************************************-->
|
|
||||||
<tr data-group="42415">
|
|
||||||
<td>Mundschutz</td>
|
|
||||||
<td>Farma Corp</td>
|
|
||||||
<td>Mu-15415</td>
|
|
||||||
<td colspan="3"></td>
|
|
||||||
<td><a class="button smaller" th:href="@{/intern/listedArticles/48670}">Hinzufügen</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr data-group="42415">
|
|
||||||
<td colspan="3"></td>
|
|
||||||
<td><a th:href="@{/intern/suppliers/48670}">Cheap AG</a></td>
|
|
||||||
<td>150,54 EUR</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
|
|
||||||
</tr>
|
|
||||||
<tr data-group="42415">
|
|
||||||
<td colspan="3"></td>
|
|
||||||
<td><a th:href="@{/intern/suppliers/48670}">Not Cheap AG</a></td>
|
|
||||||
<td>250,54 EUR</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
|
|
||||||
<!--**********************************************************-->
|
|
||||||
<tr data-group="4580">
|
|
||||||
<td>Goldbaren</td>
|
|
||||||
<td>Bundesbank</td>
|
|
||||||
<td>G1KG</td>
|
|
||||||
<td colspan="3"></td>
|
|
||||||
<td><a th:href="@{/intern/listedArticles/48670}">Inaktiv 4888</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr data-group="4580">
|
|
||||||
<td colspan="3"></td>
|
|
||||||
<td><a th:href="@{/intern/suppliers/48670}">Cheap AG</a></td>
|
|
||||||
<td>10000,54 EUR</td>
|
|
||||||
<td>X</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
<footer th:replace="fragments/footer :: footer"></footer>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@ -1,119 +1,109 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="de" dir="ltr" xmlns:th="http://www.thymeleaf.org">
|
<html lang="de" dir="ltr" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
<head>
|
<meta charset="utf-8">
|
||||||
<meta charset="utf-8">
|
<meta name="viewport" content="width=device-width, initial-scale=0.75, user-scalable=no">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=0.75, user-scalable=no">
|
<title>Bearbeiten: Artikel</title>
|
||||||
|
<script th:src="@{/js/filterTable.js}"></script>
|
||||||
<title>Gelistete Artikel</title>
|
<link rel="stylesheet" th:href="@{/css/ecom.css}"/>
|
||||||
<script th:src="@{/js/filterTable.js}"></script>
|
</head>
|
||||||
<link rel="stylesheet" th:href="@{/css/ecom.css}"/>
|
<body>
|
||||||
</head>
|
<nav th:replace="fragments/header :: header">Header</nav>
|
||||||
|
<div class="sidebar-layout content-width">
|
||||||
<body>
|
<nav></nav>
|
||||||
<nav th:replace="fragments/header :: header">Header</nav>
|
<div>
|
||||||
<div class="sidebar-layout content-width">
|
<h1>Artikel bearbeiten</h1>
|
||||||
<nav></nav>
|
<script th:src="@{/js/back.js}"></script>
|
||||||
<div>
|
<div class="back" data-group="intern" data-insert="true"></div>
|
||||||
<h1>Gelisteter Artikel 8450</h1>
|
</div>
|
||||||
|
</div>
|
||||||
<script th:src="@{/js/back.js}"></script>
|
<main class="sidebar-layout content-width">
|
||||||
<div class="back" data-group="intern" data-insert="true"></div>
|
<nav th:replace="fragments/intern :: sidebar"></nav>
|
||||||
</div>
|
<div class="content-width">
|
||||||
</div>
|
<h2>Gelisteter Artikel ID <span th:text="${ArticleID.id}"></span></h2>
|
||||||
<main class="sidebar-layout content-width">
|
<form class="detailgrid" action="#" th:action="@{/intern/articles/{id}/saveChanges(id = ${ArticleID.id})}" th:object="${ArticleID}" method="POST" enctype="multipart/form-data">
|
||||||
<nav th:replace="fragments/intern :: sidebar"></nav>
|
<p class="m">
|
||||||
<div class="content-width">
|
<label for="title">Titel</label>
|
||||||
<h2>Gelisteter Artikel 8450</h2>
|
<input class=" full-width" type="text" id="title" name="title" required="required" pattern="[A-Za-z0-9]{1,20}" th:value="${ArticleID.title}"/>
|
||||||
<form class="detailgrid">
|
</p>
|
||||||
<p class="m">
|
<p class="s">
|
||||||
<label for="title">Titel</label>
|
<label for="ref-article">Refernzierter Artikel</label>
|
||||||
<input class=" full-width" type="text" name="title" value="Kamera"/>
|
<input class="" type="text" id="ref_disabled" th:value="${ArticleID.offer_id}" disabled/>
|
||||||
</p>
|
|
||||||
<p class="s">
|
<input type="hidden" id="ref_hidden" th:value="${ArticleID.offer_id}" name="ref-article" />
|
||||||
<label for="ref-article">Refernzierter Artikel</label>
|
|
||||||
<input class="" type="text" name="ref-article" value="8405" disabled/>
|
<td><a th:href="${'/intern/supplierOffers/#q=' + {ArticleID.id}}">Details</a></td>
|
||||||
<td><a th:href="@{/intern/articles/#q=%2044048}">Details</a></td>
|
</p>
|
||||||
</p>
|
<div class="spacer"></div>
|
||||||
<div class="spacer"></div>
|
<div class="m">
|
||||||
<div class="m">
|
<p>
|
||||||
<p>
|
<label for="img">Bild Hochladen</label>
|
||||||
<label for="img">Bild Hochladen</label>
|
<input class="full-width" type="file" id="image" name="img"/>
|
||||||
<input class="full-width" type="file" name="img"/>
|
</p>
|
||||||
</p>
|
<p>
|
||||||
<p>
|
<img th:src="@{/shop/articles/{id}/image.jpg(id=${ArticleID.id})}" class="m"/>
|
||||||
<img th:src="@{/img/product-1.jpg}" class="m"/>
|
</p>
|
||||||
</p>
|
</div>
|
||||||
</div>
|
<div class="s">
|
||||||
<div class="s">
|
<p>
|
||||||
<p>
|
<label for="price">Preis (Netto)</label>
|
||||||
<label for="price">Preis (Netto)</label>
|
<input class="" type="number" step="0.01" name="price_netto" th:value="${ArticleID.price_netto}"/> EUR <br/>
|
||||||
<input class="" type="number" step="0.01" name="price" value="84.45"/> EUR <br/>
|
(19% Mwst.)
|
||||||
(19% Mwst.)
|
<!-- Info von article ref--> <br/>
|
||||||
<!-- Info von article ref--> <br/>
|
= <span th:text="${ArticleID.price}"></span> EUR Brutto
|
||||||
= 105.98 EUR Brutto
|
</p>
|
||||||
</p>
|
<p>
|
||||||
<p>
|
<label for="max-price-buy">Maximaler Einkaufspreis (Netto)</label>
|
||||||
<label for="max-price-buy">Maximaler Einkaufspreis (Netto)</label>
|
<input class="" type="number" id="reorderMaxPrice" step="0.01" name="reorderMaxPrice" th:value="${ArticleID.reorderMaxPrice}"/> EUR
|
||||||
<input class="" type="number" step="0.01" name="price" value="80.98"/> EUR
|
</p>
|
||||||
</p>
|
<div>
|
||||||
<div>
|
<fieldset>
|
||||||
<fieldset>
|
<input type="radio" name="autobuy" value="true" id="autobuy-yes" th:checked="${ArticleID.shouldReorder}" required>
|
||||||
<input type="radio" name="autobuy" value="true" id="autobuy-yes" checked required>
|
|
||||||
<label for="autobuy-yes"> Automatisch nachbestellen.</label> <br/>
|
<label for="autobuy-yes"> Automatisch nachbestellen.</label> <br/>
|
||||||
<input type="radio" name="autobuy" value="false" id="autobuy-no" required>
|
<input type="radio" name="autobuy" value="false" id="autobuy-no" th:checked="${!ArticleID.shouldReorder}" required>
|
||||||
<label for="autobuy-no"> Nicht mehr nachkaufen.</label> <br/>
|
<label for="autobuy-no"> Nicht mehr nachkaufen.</label> <br/>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="m">
|
||||||
|
<label for="tags">Kategorien</label>
|
||||||
|
<p>
|
||||||
|
Bitte jede Kategorien in eine eigene Zeile
|
||||||
|
</p>
|
||||||
|
<textarea name="categories" id="categories" class="full-width" rows="6"th:inline="text">[[${ArticleID.categorie}]]
|
||||||
|
|
||||||
<div class="m">
|
|
||||||
<label for="tags">Kategorien</label>
|
|
||||||
<p>
|
|
||||||
Bitte jede Kategorien in eine eigene Zeile
|
|
||||||
</p>
|
|
||||||
<textarea name="tags" class="full-width" rows="6">
|
|
||||||
Überwachung
|
|
||||||
Elektronik
|
|
||||||
</textarea>
|
</textarea>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="s">
|
||||||
<div class="s">
|
<p>
|
||||||
<p>
|
<label for="price">Einheiten pro Lagerplatz</label>
|
||||||
<label for="price">Einheiten pro Lagerplatz</label>
|
<input class="" type="number" id="units-per-slot" name="units-per-slot" th:value="${ArticleID.warehouseUnitsPerSlot}"/>
|
||||||
<input class="" type="number" name="units-per-slot" value="20"/>
|
</p>
|
||||||
</p>
|
<p>
|
||||||
<p>
|
<b>Lagerbestand: <span th:text="${ArticleID.stock}"></span></b>
|
||||||
<b>Lagerbestand: 12</b>
|
</p>
|
||||||
</p>
|
<p>
|
||||||
<p>
|
Der Wert wird nur für zukünftige Lagerbuchungen verwendet.
|
||||||
Der Wert wird nur für zukünftige Lagerbuchungen verwendet.
|
Bei Problemen kann können Einheiten aus- und wieder eingebucht werden.
|
||||||
Bei Problemen kann können Einheiten aus- und wieder eingebucht werden.
|
<!-- TODO: set link g-->
|
||||||
<!-- TODO: set link g-->
|
</p>
|
||||||
</p>
|
<p>
|
||||||
<p>
|
<a href="/todo" class="button smaller">Lagerbuchung</a>
|
||||||
<a href="/todo" class="button smaller">Lagerbuchung</a>
|
</p>
|
||||||
|
</div>
|
||||||
</p>
|
<p class="l">
|
||||||
</div>
|
<label for="description">Beschreibung</label>
|
||||||
|
<textarea name="description" id="description" class="full-width" rows="15" th:inline="text">[[${ArticleID.description}]]
|
||||||
<p class="l">
|
</textarea>
|
||||||
<label for="description">Beschreibung</label>
|
</p>
|
||||||
<textarea name="description" class="full-width" rows="15">
|
<div class="l">
|
||||||
Eine TOLLE Kamera
|
<button type="submit">Änderungen speichern</button>
|
||||||
Jaja du denkst jetzt bestimmt: "Bei dem Preis kann sie gar nich sooo TOLL sein".
|
<button type="reset">Zurücksetzen</button>
|
||||||
Aber glaub mir, sie is echt echt TOLL!
|
<button onclick="history.back()">Änderungen verwerfen</button>
|
||||||
Indianerehrenwort!
|
</div>
|
||||||
</textarea>
|
</form>
|
||||||
</p>
|
</div>
|
||||||
<div class="l">
|
</main>
|
||||||
<button type="submit">Änderungen speichern</button>
|
<footer th:replace="fragments/footer :: footer"></footer>
|
||||||
<button type="reset">Zurücksetzen</button>
|
</body>
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
<footer th:replace="fragments/footer :: footer"></footer>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,109 +1,69 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="de" dir="ltr" xmlns:th="http://www.thymeleaf.org">
|
<html lang="de" dir="ltr" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
<head>
|
<meta charset="utf-8">
|
||||||
<meta charset="utf-8">
|
<meta name="viewport" content="width=device-width, initial-scale=0.75, user-scalable=no">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=0.75, user-scalable=no">
|
<title>Gelistete Artikel</title>
|
||||||
|
<script th:src="@{/js/filterTable.js}"></script>
|
||||||
<title>Gelistete Artikel</title>
|
<link rel="stylesheet" th:href="@{/css/ecom.css}"/>
|
||||||
<script th:src="@{/js/filterTable.js}"></script>
|
</head>
|
||||||
<link rel="stylesheet" th:href="@{/css/ecom.css}"/>
|
<body>
|
||||||
</head>
|
<nav th:replace="fragments/header :: header">Header</nav>
|
||||||
|
<div class="sidebar-layout content-width">
|
||||||
<body>
|
<nav></nav>
|
||||||
<nav th:replace="fragments/header :: header">Header</nav>
|
<div>
|
||||||
<div class="sidebar-layout content-width">
|
<h1>Gelistete Artikel</h1>
|
||||||
<nav></nav>
|
<script th:src="@{/js/back.js}"></script>
|
||||||
<div>
|
<div class="back" data-group="intern" data-name="Zurück zu den gelisteten Artikeln." data-insert="false"></div>
|
||||||
<h1>Gelistete Artikel</h1>
|
</div>
|
||||||
|
</div>
|
||||||
<script th:src="@{/js/back.js}"></script>
|
<main class="sidebar-layout content-width">
|
||||||
<div class="back" data-group="intern" data-name="Zurück zu den gelisteten Artikeln." data-insert="false"></div>
|
<nav th:replace="fragments/intern :: sidebar"></nav>
|
||||||
</div>
|
<div class="content-width">
|
||||||
</div>
|
<p>
|
||||||
<main class="sidebar-layout content-width">
|
Weitere Artikel können über Artikelübersicht der Lieferanten hinzugefügt werden.
|
||||||
<nav th:replace="fragments/intern :: sidebar"></nav>
|
<a class="button smaller" th:href="@{/intern/supplierOffers}"> Jetzt Hinzufügen </a>
|
||||||
<div class="content-width">
|
</p>
|
||||||
<h2>Artikel Hinzufügen</h2>
|
<p>
|
||||||
<p>
|
<table id="main-table">
|
||||||
Weitere Artikel können über Artikelübersicht gelistet werden.
|
<tr>
|
||||||
<a class="button smaller" th:href="@{/intern/articles/}"> Jetzt Hinzufügen </a>
|
<th colspan="9">
|
||||||
</p>
|
<input type="text" placeholder="Filtern" class="smaller jsFilterTable full-width"
|
||||||
|
data-target-id="main-table"></input>
|
||||||
<p>
|
</th>
|
||||||
<table id="main-table">
|
</tr>
|
||||||
<tr>
|
<thead>
|
||||||
<th colspan="8">
|
<tr>
|
||||||
<input type="text" placeholder="Filtern" class="smaller jsFilterTable full-width"
|
<th>Bild</th>
|
||||||
data-target-id="main-table"></input>
|
<th>Name</th>
|
||||||
</th>
|
<th>Preis</th>
|
||||||
</tr>
|
<th>(Netto)</th>
|
||||||
<tr>
|
<th>Kategorien</th>
|
||||||
<th>Bild</th>
|
<th>Lagerbestand</th>
|
||||||
<th>Name</th>
|
<th>Angebots ID</th>
|
||||||
<th>Preis</th>
|
<th>Artikel ID</th>
|
||||||
<th>(Netto)</th>
|
<th>Aktion</th>
|
||||||
<th>Kategorien</th>
|
</tr>
|
||||||
<th>Lagerbestand (Aktiv)</th>
|
</thead>
|
||||||
<th>Artikel</th>
|
<tbody>
|
||||||
<th>Id (bearbeiten)</th>
|
<tr th:each="article : ${ListedArticles}">
|
||||||
</tr>
|
<td><img th:src="@{/shop/articles/{id}/image.jpg(id=${article.id})}" class="s"/></td>
|
||||||
|
<td><span th:text="${article.title}"></span></td>
|
||||||
<tr>
|
<td><span th:text="${article.price}"></span> €</td>
|
||||||
<td><img th:src="@{/img/product-1.jpg}" class="s"/></td>
|
<td><span th:text="${article.price_netto}"></span> €</td>
|
||||||
<td>Kamera</td>
|
<td><span th:text="${article.categorie}"></span></td>
|
||||||
<td>100,50 EUR</td>
|
<td><span th:text="${article.stock}"></span></td>
|
||||||
<td> (84.45 EUR)</td>
|
<td><a th:href="${'/intern/supplierOffers/#q=' + {article.title}}" th:text="${article.offer_id}"></a></td>
|
||||||
<td>Úberwachung, Elektronik</td>
|
<td><a th:href="@{/intern/articles/{id}(id = ${article.id})}" th:text="${article.id}"></a></td>
|
||||||
<td>301 <span class="checked"></span></td>
|
<td>
|
||||||
<td><a th:href="@{/intern/articles/#q=%2044048}">5051</a></td>
|
<form th:action="@{/intern/articles/{id}(id = ${article.id})}"><input type="submit" value="Bearbeiten" /></form>
|
||||||
<td><a th:href="@{/intern/listedArticles/45015}">890</a></td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
</tbody>
|
||||||
<td><img th:src="@{/img/product-2.jpg}" class="s"/></td>
|
</table>
|
||||||
<td>Earbuds</td>
|
<p>
|
||||||
<td>63,95 EUR</td>
|
</div>
|
||||||
<td>(53,73 EUR)</td>
|
</main>
|
||||||
<td>Kopfhörer, Elektronik</td>
|
<footer th:replace="fragments/footer :: footer"></footer>
|
||||||
<td>12 <span class="checked"></span></td>
|
</body>
|
||||||
<td><a th:href="@{/intern/articles/#q=%2044048}">840</a></td>
|
</html>
|
||||||
<td><a th:href="@{/intern/listedArticles/45015}">13850</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><img th:src="@{/img/product-3.jpg}" class="s"/></td>
|
|
||||||
<td>USB-Magic Light</td>
|
|
||||||
<td>11,90 EUR</td>
|
|
||||||
<td> (10,00 EUR)</td>
|
|
||||||
<td>Sonstiges, Elektronik</td>
|
|
||||||
<td>3<span class="unchecked"></span></td>
|
|
||||||
<td><a th:href="@{/intern/articles/#q=%2044048}">8401</a></td>
|
|
||||||
<td><a th:href="@{/intern/listedArticles/45015}">5784</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><img th:src="@{/img/product-4.jpg}" class="s"/></td>
|
|
||||||
<td>3D Magic Stativ</td>
|
|
||||||
<td>15,99 EUR</td>
|
|
||||||
<td> (13.44 EUR)</td>
|
|
||||||
<td>Úberwachung, Elektronik</td>
|
|
||||||
<td>4<span class="checked"></span></td>
|
|
||||||
<td><a th:href="@{/intern/articles/#q=%2044048}">2135</a></td>
|
|
||||||
<td><a th:href="@{/intern/listedArticles/45015}">4564</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><img th:src="@{/img/product-5.jpg}" class="s"/></td>
|
|
||||||
<td>Ersatzfernbedinung</td>
|
|
||||||
<td>7,95 EUR</td>
|
|
||||||
<td> (6.68 EUR)</td>
|
|
||||||
<td>Úberwachung, Elektronik</td>
|
|
||||||
<td>0<span class="checked"></span></td>
|
|
||||||
<td><a th:href="@{/intern/articles/#q=%2044048}">4565</a></td>
|
|
||||||
<td><a th:href="@{/intern/listedArticles/45015}">4566</a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<p>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
<footer th:replace="fragments/footer :: footer"></footer>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@ -0,0 +1,69 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de" dir="ltr" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=0.75, user-scalable=no">
|
||||||
|
<title>Händlerangebote</title>
|
||||||
|
<script th:src="@{/js/filterTable.js}"></script>
|
||||||
|
<link rel="stylesheet" th:href="@{/css/ecom.css}"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<nav th:replace="fragments/header :: header">Header</nav>
|
||||||
|
<div class="sidebar-layout content-width">
|
||||||
|
<nav></nav>
|
||||||
|
<div>
|
||||||
|
<h1>Übersicht der Angebote von Lieferanten</h1>
|
||||||
|
<script th:src="@{/js/back.js}"></script>
|
||||||
|
<div class="back" data-group="intern" data-name="Zurück zur Übersicht der von Lieferanten angebotenen Artikel."
|
||||||
|
data-insert="false"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<main class="sidebar-layout content-width">
|
||||||
|
<nav th:replace="fragments/intern :: sidebar"></nav>
|
||||||
|
<div class="content-width">
|
||||||
|
<p>
|
||||||
|
<table id="main-table">
|
||||||
|
<tr>
|
||||||
|
<th colspan="7">
|
||||||
|
<input type="text" placeholder="Filtern" class="smaller jsFilterTable full-width" data-target-id="main-table"></input>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Hersteller</th>
|
||||||
|
<th>Artikelnummer</th>
|
||||||
|
<th>Lieferant</th>
|
||||||
|
<th>Kaufpreis (Netto)</th>
|
||||||
|
<th>Werbungs-<br/>anfrage</th>
|
||||||
|
<th>Status</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr th:each="article : ${OfferedArticles}">
|
||||||
|
<td><span th:text="${article.title}"></span></td>
|
||||||
|
<td><span th:text="${article.manufacturer}"></span></td>
|
||||||
|
<td><span th:text="${article.articlenumber}"></span></td>
|
||||||
|
<td><a th:href="@{/intern/suppliers/{id}(id = ${article.supplierId})}" th:text="${article.supplierName}"></a></td>
|
||||||
|
<td><span th:text="${article.price}"></span> €</td>
|
||||||
|
<td><span th:text="${article.ads}"></span></td>
|
||||||
|
<td>
|
||||||
|
<div th:if="${article.offerIsListed}">
|
||||||
|
<a th:href="@{/intern/articles/{id}(id = ${article.listedArticleId})}">Artikel gelistet</a>
|
||||||
|
</div>
|
||||||
|
<!-- ELSE -->
|
||||||
|
<div th:unless="${article.offerIsListed}">
|
||||||
|
<form class="detailgrid" action="#" th:action="@{/intern/articles/addArticle/{id}(id = ${article.offer_id})}" method="POST">
|
||||||
|
<input type="submit" value="Hinzufügen" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
<footer th:replace="fragments/footer :: footer"></footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -14,7 +14,7 @@
|
|||||||
<nav th:replace="fragments/header :: header">Header</nav>
|
<nav th:replace="fragments/header :: header">Header</nav>
|
||||||
<main class=" content-width">
|
<main class=" content-width">
|
||||||
<div class="sidebar-layout" style="min-height: 75vh;">
|
<div class="sidebar-layout" style="min-height: 75vh;">
|
||||||
<nav th:replace="fragments/shop :: sidebar"></nav>
|
<nav th:replace="fragments/shop :: sidebar(categories=${categories})"></nav>
|
||||||
<div class="content-width">
|
<div class="content-width">
|
||||||
<div class="detailgrid">
|
<div class="detailgrid">
|
||||||
<div class="s">
|
<div class="s">
|
||||||
@ -23,7 +23,9 @@
|
|||||||
<script th:src="@{/js/back.js}"></script>
|
<script th:src="@{/js/back.js}"></script>
|
||||||
<div class="back" data-group="shop" data-insert="true"></div>
|
<div class="back" data-group="shop" data-insert="true"></div>
|
||||||
|
|
||||||
<h2><span th:text="${#numbers.formatDecimal(article.getPriceGross() * 0.01, 1, 'POINT', 2, 'COMMA')}"></span><span> EUR</span></h2>
|
<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>
|
<p th:text="${article.description}"></p>
|
||||||
</div>
|
</div>
|
||||||
<div class="s">
|
<div class="s">
|
||||||
@ -32,7 +34,9 @@
|
|||||||
<div class="s"></div>
|
<div class="s"></div>
|
||||||
<form class="s" method="POST">
|
<form class="s" method="POST">
|
||||||
<div class="detailgrid m">
|
<div class="detailgrid m">
|
||||||
<h2><span th:text="${#numbers.formatDecimal(article.getPriceGross() * 0.01, 1, 'POINT', 2, 'COMMA')}"></span><span> EUR</span></h2>
|
<h2><span
|
||||||
|
th:text="${#numbers.formatDecimal(article.getPriceGross() * 0.01, 1, 'POINT', 2, 'COMMA')}"></span><span> EUR</span>
|
||||||
|
</h2>
|
||||||
<div>
|
<div>
|
||||||
<label class="nolinebreak">Menge:</label>
|
<label class="nolinebreak">Menge:</label>
|
||||||
<select name="quantity" size="1">
|
<select name="quantity" size="1">
|
||||||
@ -55,10 +59,13 @@
|
|||||||
<div>
|
<div>
|
||||||
<h1>Weitere Schnäppchen</h1>
|
<h1>Weitere Schnäppchen</h1>
|
||||||
<div class='grid m base shadow'>
|
<div class='grid m base shadow'>
|
||||||
<section th:each="article: ${commercialArticles}"><a th:href="@{/shop/articles/{id}(id = ${article.id})}" class="section">
|
<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})}"/>
|
<img th:src="@{/shop/articles/{id}/image.jpg(id=${article.id})}"/>
|
||||||
<h2 th:text="${article.title}"></h2>
|
<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 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>
|
<p th:text="${article.description}"></p>
|
||||||
</a>
|
</a>
|
||||||
</section>
|
</section>
|
||||||
|
@ -25,9 +25,11 @@
|
|||||||
<a th:href="@{/shop/articles/{id}(id=${article.id})}" class="section">
|
<a th:href="@{/shop/articles/{id}(id=${article.id})}" class="section">
|
||||||
|
|
||||||
<img th:src="@{/shop/articles/{id}/image.jpg(id=${article.id})}"/>
|
<img th:src="@{/shop/articles/{id}/image.jpg(id=${article.id})}"/>
|
||||||
<h2 th:text="${article.title}" />
|
<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 class='price'><span
|
||||||
<p th:text="${article.description}" />
|
th:text="${#numbers.formatDecimal(article.getPriceGross() * 0.01, 1, 'POINT', 2, 'COMMA')}"></span><span> EUR</span>
|
||||||
|
</p>
|
||||||
|
<p th:text="${article.description}"/>
|
||||||
</a>
|
</a>
|
||||||
</section>
|
</section>
|
||||||
<section class="spacer"></section>
|
<section class="spacer"></section>
|
||||||
@ -57,7 +59,7 @@
|
|||||||
|
|
||||||
<!-- If User is logged in but hasn't ordered anything yet-->
|
<!-- If User is logged in but hasn't ordered anything yet-->
|
||||||
<div th:if="${isLoggedIn == true and hasOrders == false}">
|
<div th:if="${isLoggedIn == true and hasOrders == false}">
|
||||||
<h1>Jetzt Shoppen und Empfehlungen erhalten!</h1>
|
<h2>Jetzt Shoppen und Empfehlungen erhalten!</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- If User is logged in and has ordered something before-->
|
<!-- If User is logged in and has ordered something before-->
|
||||||
@ -67,9 +69,11 @@
|
|||||||
<a th:href="@{/shop/articles/{id}(id=${article.id})}" class="section">
|
<a th:href="@{/shop/articles/{id}(id=${article.id})}" class="section">
|
||||||
|
|
||||||
<img th:src="@{/shop/articles/{id}/image.jpg(id=${article.id})}"/>
|
<img th:src="@{/shop/articles/{id}/image.jpg(id=${article.id})}"/>
|
||||||
<h2 th:text="${article.title}" />
|
<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 class='price'><span
|
||||||
<p th:text="${article.description}" />
|
th:text="${#numbers.formatDecimal(article.getPriceGross() * 0.01, 1, 'POINT', 2, 'COMMA')}"></span><span> EUR</span>
|
||||||
|
</p>
|
||||||
|
<p th:text="${article.description}"/>
|
||||||
</a>
|
</a>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
@ -21,70 +21,29 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<main class="sidebar-layout content-width">
|
<main class="sidebar-layout content-width">
|
||||||
<nav th:replace="fragments/shop :: sidebar"></nav>
|
<nav th:replace="fragments/shop :: sidebar(categories=${categories})"></nav>
|
||||||
<div class="content-width">
|
<div class="content-width">
|
||||||
<div class='grid m condensed'>
|
<div class='grid m condensed' th:if="${articles.size() != 0}">
|
||||||
<section><a th:href="@{/shop/articles/1234}" class="section">
|
<section th:each="article: ${articles}">
|
||||||
<img th:src="@{/img/product-1.jpg}">
|
<a th:href="@{/shop/articles/{id}(id=${article.id})}" class="section">
|
||||||
<h2>Tolle Kamera</h2>
|
|
||||||
<p class='price'> 25.14 EUR</p>
|
|
||||||
<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>
|
|
||||||
</a>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section><a th:href="@{/shop/articles/1234}" class="section">
|
<img th:src="@{/shop/articles/{id}/image.jpg(id=${article.id})}"/>
|
||||||
<img th:src="@{/img/product-2.jpg}">
|
<h2 th:text="${article.title}"/>
|
||||||
<h2>Bluetooth Kopfhörer</h2>
|
<p class='price'><span
|
||||||
<p class='price'> 10.14 EUR</p>
|
th:text="${#numbers.formatDecimal(article.getPriceGross() * 0.01, 1, 'POINT', 2, 'COMMA')}"></span><span> EUR</span>
|
||||||
<p>
|
</p>
|
||||||
Sind halt Kopfhörer ohne Kabel, mehr gibts da nich zu sagen.
|
<p th:text="${article.description}"/>
|
||||||
</p>
|
</a>
|
||||||
</a>
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section><a th:href="@{/shop/articles/1234}" class="section">
|
|
||||||
<img th:src="@{/img/product-3.jpg}">
|
|
||||||
<h2>???</h2>
|
|
||||||
<p class='price'> 25.14 EUR</p>
|
|
||||||
<p>
|
|
||||||
Ich weiß selbst nich was das genau sein soll.<br>
|
|
||||||
Wenn dus willst kannst es gern haben, musst nur das Geld überweisen.
|
|
||||||
</p>
|
|
||||||
</a>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<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>
|
|
||||||
</a>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
|
|
||||||
<section class="spacer"></section>
|
<section class="spacer"></section>
|
||||||
<section class="spacer"></section>
|
<section class="spacer"></section>
|
||||||
<section class="spacer"></section>
|
<section class="spacer"></section>
|
||||||
<section class="spacer"></section>
|
<section class="spacer"></section>
|
||||||
</div>
|
</div>
|
||||||
|
<div th:if="${articles.size() == 0}">
|
||||||
|
<h2>Keine Ergebnisse für diesen Suchterm gefunden!</h2>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
<footer th:replace="fragments/footer :: footer"></footer>
|
<footer th:replace="fragments/footer :: footer"></footer>
|
||||||
|
Reference in New Issue
Block a user