master merged into feature/customer_orders
This commit is contained in:
		@ -0,0 +1,36 @@
 | 
			
		||||
package org.hso.ecommerce.components;
 | 
			
		||||
 | 
			
		||||
import org.hso.ecommerce.entities.booking.PaymentMethod;
 | 
			
		||||
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.Component;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.PostConstruct;
 | 
			
		||||
import java.sql.Timestamp;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
 | 
			
		||||
@Component
 | 
			
		||||
public class AdminInitializer {
 | 
			
		||||
 | 
			
		||||
	@Autowired
 | 
			
		||||
	private final UserRepository userRepository = null;
 | 
			
		||||
 | 
			
		||||
	@PostConstruct
 | 
			
		||||
	public void init() {
 | 
			
		||||
		Optional<Integer> numberOfEmployees = userRepository.numberOfEmployees();
 | 
			
		||||
		if (numberOfEmployees.orElse(0) == 0) {
 | 
			
		||||
			// create first admin user
 | 
			
		||||
			User firstAdmin = new User();
 | 
			
		||||
			firstAdmin.created = new Timestamp(System.currentTimeMillis());
 | 
			
		||||
			firstAdmin.name = "admin";
 | 
			
		||||
			firstAdmin.defaultPayment = new PaymentMethod();
 | 
			
		||||
			firstAdmin.defaultPayment.creditCardNumber = ""; //set empty number
 | 
			
		||||
			firstAdmin.email = "admin";
 | 
			
		||||
			firstAdmin.isActive = true;
 | 
			
		||||
			firstAdmin.isEmployee = true;
 | 
			
		||||
			firstAdmin.setPassword("admin");
 | 
			
		||||
			userRepository.save(firstAdmin); //save to DB
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -10,23 +10,21 @@ import javax.annotation.PostConstruct;
 | 
			
		||||
@Component
 | 
			
		||||
public class SlotInitializer {
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private final SlotRepository slotRepository = null;
 | 
			
		||||
	@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");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
	// 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");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -26,8 +26,6 @@ public class RegisterController {
 | 
			
		||||
			@RequestParam("username") String username, @RequestParam("password") String password,
 | 
			
		||||
			@RequestParam("password2") String password2, @RequestParam("salutation") String salutation,
 | 
			
		||||
			@RequestParam("name") String name, @RequestParam("address") String address,
 | 
			
		||||
			@RequestParam("type") String type, // TODO store
 | 
			
		||||
			@RequestParam("ad") String ad, // TODO store
 | 
			
		||||
			HttpSession session) {
 | 
			
		||||
		Optional<User> user = userRepository.findByEmail(username);
 | 
			
		||||
		if (user.isPresent()) {
 | 
			
		||||
 | 
			
		||||
@ -3,6 +3,7 @@ package org.hso.ecommerce.controller;
 | 
			
		||||
import org.hso.ecommerce.action.user.CreateDeliveryData;
 | 
			
		||||
import org.hso.ecommerce.action.user.UpdateUserSettingsAction;
 | 
			
		||||
import org.hso.ecommerce.api.RestServiceForDelivery;
 | 
			
		||||
import org.hso.ecommerce.entities.shop.Address;
 | 
			
		||||
import org.hso.ecommerce.entities.shop.CustomerOrder;
 | 
			
		||||
import org.hso.ecommerce.entities.user.User;
 | 
			
		||||
import org.hso.ecommerce.repos.shop.CustomerOrderRepository;
 | 
			
		||||
@ -47,6 +48,9 @@ public class UserController {
 | 
			
		||||
    ) {
 | 
			
		||||
        long userId = (long) session.getAttribute("userId");
 | 
			
		||||
        User user = userRepository.findById(userId).get();
 | 
			
		||||
        if(user.defaultDeliveryAddress == null){
 | 
			
		||||
            user.defaultDeliveryAddress = new Address();
 | 
			
		||||
        }
 | 
			
		||||
        model.addAttribute("user", user);
 | 
			
		||||
 | 
			
		||||
        return "user/settings";
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
package org.hso.ecommerce.controller.cronjob;
 | 
			
		||||
 | 
			
		||||
import java.sql.Timestamp;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Calendar;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.GregorianCalendar;
 | 
			
		||||
@ -37,6 +38,11 @@ import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
import org.springframework.stereotype.Component;
 | 
			
		||||
import org.springframework.ui.Model;
 | 
			
		||||
import org.springframework.web.bind.annotation.GetMapping;
 | 
			
		||||
import org.springframework.web.bind.annotation.PathVariable;
 | 
			
		||||
import org.springframework.web.bind.annotation.PostMapping;
 | 
			
		||||
import org.springframework.web.bind.annotation.RequestMapping;
 | 
			
		||||
 | 
			
		||||
interface ICronjob {
 | 
			
		||||
    /**
 | 
			
		||||
@ -63,10 +69,22 @@ interface ICronjob {
 | 
			
		||||
     * @param controller Back-reference that allows to use repositories.
 | 
			
		||||
     */
 | 
			
		||||
    void executeAt(Calendar time, CronjobController controller);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a name for this cronjob, that can be presented to the user in the frontend.
 | 
			
		||||
     *
 | 
			
		||||
     * @return A german name of this cronjob.
 | 
			
		||||
     */
 | 
			
		||||
    String getDisplayName();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@Component
 | 
			
		||||
class Reorder implements ICronjob {
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getDisplayName() {
 | 
			
		||||
        return "Nachbestellung";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Calendar nextExecution(Calendar reference) {
 | 
			
		||||
        if (reference.get(Calendar.HOUR_OF_DAY) >= 8) {
 | 
			
		||||
@ -215,6 +233,7 @@ class ScheduledCronjob {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@Component
 | 
			
		||||
@RequestMapping("intern/cronjobs")
 | 
			
		||||
class CronjobController {
 | 
			
		||||
    private static final Logger log = LoggerFactory.getLogger(CronjobController.class);
 | 
			
		||||
 | 
			
		||||
@ -328,4 +347,42 @@ class CronjobController {
 | 
			
		||||
    public void onPostConstruct() {
 | 
			
		||||
        new Thread(this::runCronjobExecutionLoop).start();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class ManualCronjob {
 | 
			
		||||
        public final String identifier;
 | 
			
		||||
        public final String visibleName;
 | 
			
		||||
 | 
			
		||||
        public ManualCronjob(String identifier, String visibleName) {
 | 
			
		||||
            this.identifier = identifier;
 | 
			
		||||
            this.visibleName = visibleName;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private List<ManualCronjob> listAllCronjobs() {
 | 
			
		||||
        ArrayList<ManualCronjob> entries = new ArrayList<>();
 | 
			
		||||
        for (Entry<String, ICronjob> job : cronjobs.entrySet()) {
 | 
			
		||||
            entries.add(new ManualCronjob(job.getKey(), job.getValue().getDisplayName()));
 | 
			
		||||
        }
 | 
			
		||||
        return entries;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @GetMapping("/")
 | 
			
		||||
    public String cronjobOverview(Model model) {
 | 
			
		||||
        model.addAttribute("jobs", listAllCronjobs());
 | 
			
		||||
        return "intern/cronjobs/index";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @PostMapping("/run/{identifier}")
 | 
			
		||||
    public String runCronjob(Model model, @PathVariable("identifier") String identifier) {
 | 
			
		||||
        ICronjob jobToExecute = cronjobs.get(identifier);
 | 
			
		||||
        if (jobToExecute != null) {
 | 
			
		||||
            jobToExecute.executeAt(new GregorianCalendar(), this);
 | 
			
		||||
            model.addAttribute("info",
 | 
			
		||||
                    String.format("Der Cronjob \"%s\" wurde ausgeführt.", jobToExecute.getDisplayName()));
 | 
			
		||||
        } else {
 | 
			
		||||
            model.addAttribute("error", "Der Cronjob konnte nicht gefunden werden.");
 | 
			
		||||
        }
 | 
			
		||||
        model.addAttribute("jobs", listAllCronjobs());
 | 
			
		||||
        return "intern/cronjobs/index";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -22,6 +22,7 @@ import java.awt.image.BufferedImage;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.nio.file.Files;
 | 
			
		||||
import java.nio.file.Path;
 | 
			
		||||
import java.nio.file.Paths;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
@ -171,15 +172,22 @@ public class InternArticleController {
 | 
			
		||||
				if (imageID.isPresent()) {
 | 
			
		||||
					article.image = imageRepository.findImageById(imageID.get()); // add existing img to article
 | 
			
		||||
				} else {
 | 
			
		||||
 | 
			
		||||
					Path targetPath = Paths.get("./data/img/");
 | 
			
		||||
					if (Files.notExists(targetPath)) {
 | 
			
		||||
						Files.createDirectories(targetPath);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					// write new img file to disk
 | 
			
		||||
					Files.newOutputStream(Paths.get("./data/img/", fileName)).write(imgFile.getBytes());
 | 
			
		||||
					Files.newOutputStream(Paths.get(targetPath.toString(), 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) {
 | 
			
		||||
			} catch (IOException e) {
 | 
			
		||||
				e.printStackTrace();
 | 
			
		||||
				setDefaultImage(article); // if upload failed, reset to default img
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,5 @@
 | 
			
		||||
package org.hso.ecommerce.controller.intern.customers;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
 | 
			
		||||
import org.hso.ecommerce.controller.intern.accounting.AccountingController;
 | 
			
		||||
import org.hso.ecommerce.controller.intern.accounting.AccountingController.ShortTemplateBookingResult;
 | 
			
		||||
import org.hso.ecommerce.entities.booking.Booking;
 | 
			
		||||
@ -13,12 +9,13 @@ import org.hso.ecommerce.repos.booking.BookingRepository;
 | 
			
		||||
import org.hso.ecommerce.repos.shop.CustomerOrderRepository;
 | 
			
		||||
import org.hso.ecommerce.repos.user.UserRepository;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
 | 
			
		||||
import org.springframework.stereotype.Controller;
 | 
			
		||||
import org.springframework.ui.Model;
 | 
			
		||||
import org.springframework.web.bind.annotation.*;
 | 
			
		||||
 | 
			
		||||
import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
import javax.servlet.http.HttpServletResponse;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
 | 
			
		||||
@Controller
 | 
			
		||||
@ -104,18 +101,18 @@ public class CustomersIndexController {
 | 
			
		||||
    ) {
 | 
			
		||||
        if (!password.equals(password2)) {
 | 
			
		||||
            request.setAttribute("error", "Passwörter stimmen nicht überein!");
 | 
			
		||||
            return "/intern/customers/id";
 | 
			
		||||
            return "intern/customers/id";
 | 
			
		||||
        }
 | 
			
		||||
        User user = userRepository.findById(id).get();
 | 
			
		||||
        if (!user.validatePassword(password)) {
 | 
			
		||||
            request.setAttribute("error", "Die Passwörter stimmen nicht mit dem Original überein!");
 | 
			
		||||
            return "/intern/customers/id";
 | 
			
		||||
            return "intern/customers/id";
 | 
			
		||||
        }
 | 
			
		||||
        user.setPassword("12345");
 | 
			
		||||
        userRepository.save(user);
 | 
			
		||||
        request.setAttribute("info", "Passwort wurde auf 12345 geändert!");
 | 
			
		||||
 | 
			
		||||
        return "/intern/customers/id";
 | 
			
		||||
        return "intern/customers/id";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,7 @@ import org.springframework.web.bind.annotation.*;
 | 
			
		||||
import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
import javax.servlet.http.HttpServletResponse;
 | 
			
		||||
import javax.servlet.http.HttpSession;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileInputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
@ -100,11 +101,18 @@ public class ShopArticleController {
 | 
			
		||||
                                    @PathVariable("id") Long id
 | 
			
		||||
    ) throws IOException {
 | 
			
		||||
        Article article = articleRepository.findArticleById(id);
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        if(article.image != null) {
 | 
			
		||||
        	InputStream in = new FileInputStream(article.image.path);
 | 
			
		||||
            response.setContentType(MediaType.IMAGE_JPEG_VALUE);
 | 
			
		||||
            IOUtils.copy(in, response.getOutputStream());
 | 
			
		||||
            File file = new File(article.image.path);
 | 
			
		||||
            File allowedPath = new File("./data/img/");
 | 
			
		||||
 | 
			
		||||
            if (file.getCanonicalPath().startsWith(allowedPath.getCanonicalPath())) {
 | 
			
		||||
                InputStream in = new FileInputStream(file);
 | 
			
		||||
                response.setContentType(MediaType.IMAGE_JPEG_VALUE);
 | 
			
		||||
                IOUtils.copy(in, response.getOutputStream());
 | 
			
		||||
            } else {
 | 
			
		||||
                throw new RuntimeException("Got illegal file path. DB was modified.");
 | 
			
		||||
            }
 | 
			
		||||
        }        
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -109,7 +109,7 @@ public class ShopCheckoutController {
 | 
			
		||||
    ) {
 | 
			
		||||
 | 
			
		||||
        if (shoppingCart.getRevision() != cartRevision) {
 | 
			
		||||
            request.setAttribute("error", "Der Warenkorb wurde zwischenzeitlich bearbeitet. Daher die Kaufvorgang nicht abgeschlossen werden. Bitte versuchen Sie es erneut.");
 | 
			
		||||
            request.setAttribute("error", "Der Warenkorb wurde zwischenzeitlich bearbeitet. Daher konnte der Kaufvorgang nicht abgeschlossen werden. Bitte versuchen Sie es erneut.");
 | 
			
		||||
            response.setStatus(HttpServletResponse.SC_CONFLICT);
 | 
			
		||||
            return "shop/checkout";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,9 @@ import org.hso.ecommerce.repos.shop.CategoryRepository;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
import org.springframework.stereotype.Controller;
 | 
			
		||||
import org.springframework.ui.Model;
 | 
			
		||||
import org.springframework.web.bind.annotation.*;
 | 
			
		||||
import org.springframework.web.bind.annotation.GetMapping;
 | 
			
		||||
import org.springframework.web.bind.annotation.RequestMapping;
 | 
			
		||||
import org.springframework.web.bind.annotation.RequestParam;
 | 
			
		||||
 | 
			
		||||
import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
import javax.servlet.http.HttpServletResponse;
 | 
			
		||||
@ -45,6 +47,9 @@ public class ShopSearchController {
 | 
			
		||||
            return "error/404";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return "/shop/search";
 | 
			
		||||
        // Show term in search box
 | 
			
		||||
        model.addAttribute("searchterm", term != null ? term : "");
 | 
			
		||||
 | 
			
		||||
        return "shop/search";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -10,8 +10,9 @@ import java.util.Optional;
 | 
			
		||||
@Repository
 | 
			
		||||
public interface UserRepository extends JpaRepository<User, Long> {
 | 
			
		||||
 | 
			
		||||
    @Query("SELECT c FROM User c WHERE c.email = :email")
 | 
			
		||||
    Optional<User> findByEmail(String email);
 | 
			
		||||
	@Query("SELECT c FROM User c WHERE c.email = :email")
 | 
			
		||||
	Optional<User> findByEmail(String email);
 | 
			
		||||
 | 
			
		||||
	@Query("SELECT count(*) FROM User WHERE isEmployee = true")
 | 
			
		||||
	Optional<Integer> numberOfEmployees();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										35
									
								
								prototype/src/main/resources/static/css/manual-cronjobs.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								prototype/src/main/resources/static/css/manual-cronjobs.css
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,35 @@
 | 
			
		||||
.alert {
 | 
			
		||||
  display: block;
 | 
			
		||||
  text-transform: uppercase;
 | 
			
		||||
  background: #c0392b;
 | 
			
		||||
  color: white;
 | 
			
		||||
  animation: blinking 1s linear infinite;
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.alert > span {
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  padding-left: 100%;
 | 
			
		||||
  animation: marquee 10s linear infinite;
 | 
			
		||||
  white-space: nowrap;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@keyframes marquee {
 | 
			
		||||
  0%   { transform: translateX(0); }
 | 
			
		||||
  100% { transform: translateX(-100%); }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@keyframes blinking {
 | 
			
		||||
  60% {
 | 
			
		||||
    color: white;
 | 
			
		||||
  }
 | 
			
		||||
  75% {
 | 
			
		||||
    color: #c0392b;
 | 
			
		||||
  }
 | 
			
		||||
  85% {
 | 
			
		||||
    color: #c0392b;
 | 
			
		||||
  }
 | 
			
		||||
  100% {
 | 
			
		||||
    color: white;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								prototype/src/main/resources/static/favicon.ico
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								prototype/src/main/resources/static/favicon.ico
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 3.4 KiB  | 
@ -11,7 +11,8 @@
 | 
			
		||||
    <div class='content-width bar-flex'>
 | 
			
		||||
        <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">
 | 
			
		||||
            <input type="text" name="term" placeholder="Nach Produkten suchen..."/>
 | 
			
		||||
            <input type="text" name="term" placeholder="Nach Produkten suchen..."
 | 
			
		||||
                   th:value="${searchterm != null ? searchterm : ''}"/>
 | 
			
		||||
            <button>Finden</button>
 | 
			
		||||
        </form>
 | 
			
		||||
        <a th:unless="${user}" class="button" th:href="@{/login}">Login</a>
 | 
			
		||||
@ -25,7 +26,10 @@
 | 
			
		||||
                </form>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <a class="button" th:href="@{/shop/checkout}">Warenkorb (<span th:text="${shoppingCart.itemCount}"></span>)</a>
 | 
			
		||||
        <a class="button" th:href="@{/shop/checkout}">Warenkorb
 | 
			
		||||
            <th:block th:if="${shoppingCart.itemCount > 0}"> (<span th:text="${shoppingCart.itemCount}"></span>)
 | 
			
		||||
            </th:block>
 | 
			
		||||
        </a>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div th:if="${error}" class="error" id="error-msg">
 | 
			
		||||
        <div class="content-width bar-flex">
 | 
			
		||||
 | 
			
		||||
@ -47,6 +47,8 @@
 | 
			
		||||
                </ul>
 | 
			
		||||
            </li>
 | 
			
		||||
 | 
			
		||||
            <li><a th:href="@{/intern/cronjobs/}">Cronjobs</a></li>
 | 
			
		||||
 | 
			
		||||
        </ul>
 | 
			
		||||
    </ul>
 | 
			
		||||
</nav>
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,60 @@
 | 
			
		||||
<!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>Cronjobs</title>
 | 
			
		||||
    <script th:src="@{/js/filterTable.js}"></script>
 | 
			
		||||
    <link rel="stylesheet" th:href="@{/css/ecom.css}"/>
 | 
			
		||||
    <link rel="stylesheet" th:href="@{/css/manual-cronjobs.css}"/>
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body>
 | 
			
		||||
<nav th:replace="fragments/header :: header">Header</nav>
 | 
			
		||||
<div class="sidebar-layout content-width">
 | 
			
		||||
    <nav></nav>
 | 
			
		||||
    <div>
 | 
			
		||||
        <h1>Cronjobs</h1>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
<main class="sidebar-layout content-width">
 | 
			
		||||
    <nav th:replace="fragments/intern :: sidebar"></nav>
 | 
			
		||||
    <div class="content-width">
 | 
			
		||||
        <h3>Manuelle Ausführung von Cronjobs</h3>
 | 
			
		||||
        <div class="alert"><span>
 | 
			
		||||
            WARNUNG<br>
 | 
			
		||||
            Manuelles Triggern von Cronjobs kann zu unerwartetem Verhalten führen!<br>
 | 
			
		||||
            Diese Seite ist nur für Debugging-Zwecke gedacht.
 | 
			
		||||
        </span></div>
 | 
			
		||||
 | 
			
		||||
        <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>Cronjob</th>
 | 
			
		||||
                <th></th>
 | 
			
		||||
            </tr>
 | 
			
		||||
            <tr th:each="job: ${jobs}">
 | 
			
		||||
                <td th:text="${job.visibleName}"></td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <form th:action="@{/intern/cronjobs/run/{identifier}(identifier = ${job.identifier})}" method="post">
 | 
			
		||||
                        <input class="button smaller" type="submit" value="Ausführen" />
 | 
			
		||||
                    </form>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
        </table>
 | 
			
		||||
        </p>
 | 
			
		||||
 | 
			
		||||
    </div>
 | 
			
		||||
</main>
 | 
			
		||||
<footer th:replace="fragments/footer :: footer"></footer>
 | 
			
		||||
</body>
 | 
			
		||||
 | 
			
		||||
</html>
 | 
			
		||||
@ -23,7 +23,7 @@
 | 
			
		||||
<div class="sidebar-layout content-width">
 | 
			
		||||
    <nav></nav>
 | 
			
		||||
    <div>
 | 
			
		||||
        <h1 th:text="|Kunde ${user.id}"></h1>
 | 
			
		||||
        <h1 th:text="|Kunde ${user.id}|"></h1>
 | 
			
		||||
 | 
			
		||||
        <script th:src="@{/js/back.js}"></script>
 | 
			
		||||
        <div class="back" data-group="intern" data-insert="true"></div>
 | 
			
		||||
 | 
			
		||||
@ -28,7 +28,7 @@
 | 
			
		||||
                  <input class=" full-width" type="text" id="title" name="title" required="required" pattern=".+" th:value="${ArticleID.title}"/>
 | 
			
		||||
               </p>
 | 
			
		||||
               <p class="s">
 | 
			
		||||
                  <label for="ref_disabled">Refernzierter Artikel</label>
 | 
			
		||||
                  <label for="ref_disabled">Referenzierter Artikel</label>
 | 
			
		||||
                  <input class="" type="text" id="ref_disabled" th:value="${ArticleID.offerID}" disabled/>
 | 
			
		||||
                  
 | 
			
		||||
                  <input type="hidden" id="ref_hidden" th:value="${ArticleID.offerID}" name="ref-article" />
 | 
			
		||||
@ -38,7 +38,7 @@
 | 
			
		||||
               <div class="spacer"></div>
 | 
			
		||||
               <div class="m">
 | 
			
		||||
                  <p>
 | 
			
		||||
                     <label for="img">Bild Hochladen</label>
 | 
			
		||||
                     <label for="img">Bild hochladen</label>
 | 
			
		||||
                     <input class="full-width" type="file" id="img" name="img"/>
 | 
			
		||||
                  </p>
 | 
			
		||||
                  <p>
 | 
			
		||||
@ -88,7 +88,7 @@
 | 
			
		||||
                  </p>
 | 
			
		||||
                  <p>
 | 
			
		||||
                     Der Wert wird nur für zukünftige Lagerbuchungen verwendet.
 | 
			
		||||
                     Bei Problemen kann können Einheiten aus- und wieder eingebucht werden.
 | 
			
		||||
                     Bei Problemen können Einheiten aus- und wieder eingebucht werden.
 | 
			
		||||
                     <!-- TODO: set link g-->
 | 
			
		||||
                  </p>
 | 
			
		||||
                  <p>
 | 
			
		||||
 | 
			
		||||
@ -54,25 +54,8 @@
 | 
			
		||||
            <textarea rows="5" class="full-width" type="text" name="address" id="address"
 | 
			
		||||
               placeholder="Optional: Zusatz
Optional: Unternehmen
Straße Hausnummer
Postleitzeit Ort
Land"></textarea>
 | 
			
		||||
            </div>
 | 
			
		||||
            <fieldset>
 | 
			
		||||
            <input type="radio" id="type-priv" name="type" value="priv">
 | 
			
		||||
            <label for="type-priv">Ich bin Privatkunde</label><br>
 | 
			
		||||
            <input type="radio" id="type-bus" name="type" value="bus">
 | 
			
		||||
            <label for="type-bus">Ich bin Geschäftskunde</label><br>
 | 
			
		||||
            </fieldset>
 | 
			
		||||
            <div>
 | 
			
		||||
            <h2> Werbung </h2>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div>
 | 
			
		||||
            <fieldset>
 | 
			
		||||
            <input type="radio" id="ad-y" name="ad" value="y">
 | 
			
		||||
            <label for="ad-y">Ich möchte Werbung erhalten.</label><br>
 | 
			
		||||
            <input type="radio" id="ad-n" name="ad" value="n">
 | 
			
		||||
            <label for="ad-n">Ich möchte keine Werbung erhalten.</label><br>  
 | 
			
		||||
            </fieldset>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div>
 | 
			
		||||
            <button class="full-width" type="submit" name="action" value="login">Registeren</button>
 | 
			
		||||
            <button class="full-width" type="submit" name="action" value="login">Registrieren</button>
 | 
			
		||||
            <a th:href="@{/terms}">
 | 
			
		||||
            Unsere AGBs finden sie hier.
 | 
			
		||||
            </a>
 | 
			
		||||
 | 
			
		||||
@ -52,7 +52,7 @@
 | 
			
		||||
                    <p> Jetzt Kunde werden und viele Vorteile sichern,
 | 
			
		||||
                        wie z.B. personalisierte Empfehlungen. </p>
 | 
			
		||||
                    <p>
 | 
			
		||||
                        <a class="button" th:href="@{/register}">Registieren</a>
 | 
			
		||||
                        <a class="button" th:href="@{/register}">Registrieren</a>
 | 
			
		||||
                    </p>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
@ -21,8 +21,10 @@
 | 
			
		||||
<main class="sidebar-layout content-width">
 | 
			
		||||
    <nav th:replace="fragments/customer :: sidebar"></nav>
 | 
			
		||||
    <div class="content-width detailflex">
 | 
			
		||||
        <div th:each="order: ${orderDeliveryDataMap}">
 | 
			
		||||
            <h2 id="20202701" th:text="|Bestellung vom ${order.getKey().formatCreated()}|" />
 | 
			
		||||
        <div th:if="${orderDeliveryDataMap.isEmpty()}">
 | 
			
		||||
            <h2>Mit diesem Account wurden noch keine Bestellungen getätigt.</h2>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div th:if="${!orderDeliveryDataMap.isEmpty()}" th:each="order: ${orderDeliveryDataMap}">
 | 
			
		||||
            <div>
 | 
			
		||||
                <table class="key-value">
 | 
			
		||||
                    <tr>
 | 
			
		||||
 | 
			
		||||
@ -91,7 +91,11 @@
 | 
			
		||||
            </div>
 | 
			
		||||
            <div>
 | 
			
		||||
                <div class="input-icon">
 | 
			
		||||
                    <input class="full-width" type="text" name="creditCardNumber" th:value="${user.defaultPayment.creditCardNumber}"/>
 | 
			
		||||
                    <input class="full-width"
 | 
			
		||||
                           type="text"
 | 
			
		||||
                           name="creditCardNumber"
 | 
			
		||||
                           th:value="${user.defaultPayment != null && user.defaultPayment.creditCardNumber != null ? user.defaultPayment.creditCardNumber : ''}"
 | 
			
		||||
                           placeholder="Jetzt Kreditkartennummer hinterlegen."/>
 | 
			
		||||
                    <button> Kreditkartennummer ändern</button>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user