School Commit Init
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
.vscode
|
||||
@@ -0,0 +1,35 @@
|
||||
# Assignment 07
|
||||
|
||||
Observation:
|
||||
* Requirements **3** and **4** must be implemented using inheritance and polymorphism.
|
||||
|
||||
## Bonus possibility (0.2p, deadline week 9)
|
||||
In addition to the file-based implementation for the repository, implement a true database-backed repository. For this, use inheritance and polymorphism. You are free to choose any type of database management system (e.g. `MySQL`, `SQLite`, `PostgreSQL`, `Couchbase` etc.).
|
||||
|
||||
## Problem Statement
|
||||
For your solution to the previous assignments (Assignments 04-05, 06), add the following features:
|
||||
|
||||
1. Store data in a text file. When the program starts, entities are read from the file. Modifications made during program execution are stored in the file. Implement this using the `iostream` library. Create insertion and extraction operators for your entities and use these when reading/writing to files or the console.
|
||||
|
||||
2. Use exceptions to signal errors:
|
||||
- from the repository;
|
||||
- validation errors – validate your entities using Validator classes;
|
||||
- create your own exception classes.
|
||||
- validate program input.
|
||||
|
||||
3. Depending on your assignment, store your (adoption list, movie watch list, shopping basket or tutorial watch list) in a file. When the application starts, the user should choose the type of file between `CSV` or `HTML`. Depending on the type, the application will save the list in the correct format.
|
||||
|
||||
**Indications**\
|
||||
The CSV file will contain each entity on one line and the attributes will be separated by comma \
|
||||
The HTML file will contain a table, in which each row holds the data of one entity. The columns of the table will contain the names of the data attributes.\
|
||||
These are exemplified in the [example.csv](example.csv) and [example.html](example.html) files.
|
||||
`CSV` and `HTML` files are used to save and display data to the user; they act as program outputs, so data should not be read from them!
|
||||
|
||||
4. Add a new command, allowing the user to see the:
|
||||
* adoption list
|
||||
* movie watch list
|
||||
* shopping basket
|
||||
* tutorial watch list\
|
||||
Displaying the list means opening the saved file (`CSV` or `HTML`) with the correct application (`CSV` files using Notepad, Notepad++, Microsoft Excel etc. and `HTML` files using a browser)
|
||||
|
||||
5. Create a UML class diagram for your entire application. For this, you can use any tool that you like ([StarUML](https://staruml.io/) or [LucidChart](https://www.lucidchart.com/) are only some examples. Many other options exist.
|
||||
@@ -0,0 +1,10 @@
|
||||
38,Bej,55,30,https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/71zZoa1e-xL._AC_UX466_.jpg
|
||||
40,Bej,55,25,https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/71zZoa1e-xL._AC_UX466_.jpg
|
||||
36,Blac",60,5,https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/41RBzLubByL._AC_UY550_.jpg
|
||||
40,Black,60,50,https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/41RBzLubByL._AC_UY550_.jpg
|
||||
38,Army Green,60,40,https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/61Qptn0CKQL._AC_UX342_.jpg
|
||||
42,Army Green,60,40,https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/61Qptn0CKQL._AC_UX342_.jpg
|
||||
40,Black,100,3,https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/71YLqJCurtL._AC_UY550_.jpg
|
||||
38,Red,33,20,https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/816lGcU-fWL._AC_UX425_.jpg
|
||||
40,Red,33,33,https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/816lGcU-fWL._AC_UX425_.jpg
|
||||
38,Blue,51,15,https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/51zHT88C6zL._AC_UY550_.jpg
|
||||
|
Can't render this file because it contains an unexpected character in line 3 and column 8.
|
@@ -0,0 +1,2 @@
|
||||
Queen,Bohemian Rhapsody,5:59,https://www.youtube.com/watch?v=fJ9rUzIMcZQ
|
||||
Louis Armstrong,What A Wonderful World,2:29,https://www.youtube.com/watch?v=VqhCQZaH4Vs
|
||||
|
@@ -0,0 +1,29 @@
|
||||
<!DOCTYPE html> <!-- write this exactly as it is here -->
|
||||
<html> <!-- write this exactly as it is here -->
|
||||
<head> <!-- write this exactly as it is here -->
|
||||
<title>Playlist</title> <!-- replace “Playlist” with the title for your HTML -->
|
||||
</head> <!-- write this exactly as it is here (close head tag) -->
|
||||
<body> <!-- write this exactly as it is here -->
|
||||
<table border="1"> <!-- write this exactly as it is here -->
|
||||
<tr> <!-- tr = table row; 1 row for each entity -->
|
||||
<td>Artist</td> <!-- td = table data; 1 td for each attribute of the entity -->
|
||||
<td>Title</td>
|
||||
<td>Duration</td>
|
||||
<td>Youtube link</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Queen</td>
|
||||
<td>Bohemian Rhapsody</td>
|
||||
<td>5:59</td>
|
||||
<td><a href="https://www.youtube.com/watch?v=fJ9rUzIMcZQ">Link</a></td>
|
||||
<!-- a href makes the text “Link” clickable and directs us towards the link written after “=” -->
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Louis Armstrong</td>
|
||||
<td>What A Wonderful World</td>
|
||||
<td>2:29</td>
|
||||
<td><a href="https://www.youtube.com/watch?v=VqhCQZaH4Vs">Link</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,10 @@
|
||||
38,Bej,55,2,https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/71zZoa1e-xL._AC_UX466_.jpg
|
||||
40,Bej,55,16,https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/71zZoa1e-xL._AC_UX466_.jpg
|
||||
36,Black,60,2,https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/41RBzLubByL._AC_UY550_.jpg
|
||||
40,Black,60,47,https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/41RBzLubByL._AC_UY550_.jpg
|
||||
38,Army Green,60,38,https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/61Qptn0CKQL._AC_UX342_.jpg
|
||||
42,Army Green,60,39,https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/61Qptn0CKQL._AC_UX342_.jpg
|
||||
40,Black,100,3,https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/71YLqJCurtL._AC_UY550_.jpg
|
||||
38,Red,33,20,https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/816lGcU-fWL._AC_UX425_.jpg
|
||||
40,Red,33,33,https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/816lGcU-fWL._AC_UX425_.jpg
|
||||
38,Blue,51,15,https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/51zHT88C6zL._AC_UY550_.jpg
|
||||
|
@@ -0,0 +1 @@
|
||||
38,Bej,55,1,https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/71zZoa1e-xL._AC_UX466_.jpg
|
||||
|
@@ -0,0 +1 @@
|
||||
<!DOCTYPE html><html><head><title>Shopping list</title></head><body><table border="1"><tr><td>Size</td><td>Colour</td><td>Price</td><td>Quantity</td><td>Photograph Link</td><td>Photo</td></tr></table></body></html>
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
#include "admin_controller.h"
|
||||
#include "../../exceptions/exceptions.h"
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
AdminController::AdminController(std::shared_ptr<FileRepository> repo){
|
||||
this->_repo = repo;
|
||||
}
|
||||
|
||||
AdminController::~AdminController(){
|
||||
|
||||
}
|
||||
void AdminController::add(int size,std::string colour,int price,int quantity,std::string photograph){
|
||||
Trench trench(size,colour,price,quantity,photograph);
|
||||
this->_repo->add(trench);
|
||||
}
|
||||
void AdminController::remove(int size,std::string colour,std::string photograph){
|
||||
Trench trench(size,colour,0,0,photograph);
|
||||
this->_repo->remove(trench);
|
||||
}
|
||||
void AdminController::remove(int index){
|
||||
this->_repo->remove(index);
|
||||
}
|
||||
void AdminController::update(int size,std::string colour,int price,int quantity,std::string photograph){
|
||||
Trench trench(size,colour,price,quantity,photograph);
|
||||
int index = this->_repo->get(trench);
|
||||
if(index==-1){
|
||||
throw AdminControllerException("Trench does not exist");
|
||||
}
|
||||
this->_repo->update(index,price,quantity);
|
||||
|
||||
}
|
||||
int AdminController::get(int size,std::string colour,std::string photograph){
|
||||
if(size<=0){
|
||||
throw AdminControllerException("Size must be greater than 0");
|
||||
}
|
||||
if(colour.length()==0){
|
||||
throw AdminControllerException("Colour must not be empty");
|
||||
}
|
||||
if(photograph.length()==0){
|
||||
throw AdminControllerException("Photograph must not be empty");
|
||||
}
|
||||
Trench trench(size,colour,0,0,photograph);
|
||||
int index = this->_repo->get(trench);
|
||||
return index;
|
||||
|
||||
}
|
||||
int AdminController::size(){
|
||||
return this->_repo->size();
|
||||
}
|
||||
Trench& AdminController::operator[](int index){
|
||||
return (*this->_repo)[index];
|
||||
}
|
||||
std::shared_ptr<FileRepository> AdminController::getAll(){
|
||||
return this->_repo;
|
||||
}
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
#pragma once
|
||||
#include "../../repository/FileRepository.h"
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
class AdminController {
|
||||
private:
|
||||
std::shared_ptr<FileRepository> _repo;
|
||||
public:
|
||||
|
||||
|
||||
/*
|
||||
* Constructor for the AdminController class
|
||||
* Input: repo - Repository object
|
||||
* Output: adminController object
|
||||
*/
|
||||
AdminController(std::shared_ptr<FileRepository> repo);
|
||||
|
||||
/*
|
||||
* Destructor for the AdminController class
|
||||
* Input: -
|
||||
* Output: -
|
||||
*/
|
||||
~AdminController();
|
||||
|
||||
/*
|
||||
* Adds a trench coat to the repository
|
||||
* Input: size - integer
|
||||
* colour - string
|
||||
* price - integer
|
||||
* quantity - integer
|
||||
* photograph - string
|
||||
* Output: -
|
||||
* Throws: AdminControllerException if: size<=0
|
||||
* colour is empty
|
||||
* price<=0
|
||||
* quantity<0
|
||||
* photograph is empty
|
||||
* trench coat already exists
|
||||
*/
|
||||
void add(int size,std::string colour,int price,int quantity,std::string photograph);
|
||||
|
||||
/*
|
||||
* Removes a trench coat from the repository
|
||||
* Input: size - integer
|
||||
* colour - string
|
||||
* photograph - string
|
||||
* Output: -
|
||||
* Throws: AdminControllerException if: size<=0
|
||||
* colour is empty
|
||||
* photograph is empty
|
||||
* trench coat does not exist
|
||||
*/
|
||||
void remove(int size,std::string colour,std::string photograph);
|
||||
|
||||
/*
|
||||
* Removes a trench coat from the repository
|
||||
* Input: index - integer
|
||||
* Output: -
|
||||
* Throws: RepoException if: index is out of bounds
|
||||
*/
|
||||
void remove(int index);
|
||||
|
||||
/*
|
||||
* Updates a trench coat from the repository. If the price or quantity is -1, it will not be updated
|
||||
* Input: size - integer
|
||||
* colour - string
|
||||
* price - integer
|
||||
* quantity - integer
|
||||
* photograph - string
|
||||
* Output: -
|
||||
* Throws: AdminControllerException if: size<=0
|
||||
* colour is empty
|
||||
* price!=-1 and price<=0
|
||||
* quantity!=-1 and quantity<0
|
||||
* photograph is empty
|
||||
* trench coat does not exist
|
||||
*/
|
||||
void update(int size,std::string colour,int price,int quantity,std::string photograph);
|
||||
|
||||
/*
|
||||
* Returns the index of a trench coat in the repository. If it does not exist, it returns -1
|
||||
* Input: size - integer
|
||||
* colour - string
|
||||
* photograph - string
|
||||
* Output: index - integer
|
||||
*/
|
||||
int get(int size,std::string colour,std::string photograph);
|
||||
|
||||
/*
|
||||
* Returns the number of trench coats in the repository
|
||||
* Input: -
|
||||
* Output: size - integer
|
||||
*/
|
||||
int size();
|
||||
|
||||
/*
|
||||
* Returns the trench coat at the given index
|
||||
* Input: index - integer
|
||||
* Output: trench coat - Trench object
|
||||
* Throws: RepoException if: index is out of bounds
|
||||
*/
|
||||
Trench& operator[](int index);
|
||||
|
||||
/*
|
||||
* Returns an iterator for all the trench coats in the repository
|
||||
* Input: -
|
||||
* Output: iterator
|
||||
*/
|
||||
std::shared_ptr<FileRepository> getAll();
|
||||
|
||||
};
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
#include "../../repository/FileRepository.h"
|
||||
#include "../../domain/trench.h"
|
||||
#include "user_controller.h"
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
|
||||
UserController::UserController(std::shared_ptr<FileRepository> repo,std::shared_ptr<FileRepository> shoppingRepo) {
|
||||
this->_repo = repo;
|
||||
this->_shoppingRepository = shoppingRepo;
|
||||
}
|
||||
|
||||
UserController::~UserController() {
|
||||
|
||||
}
|
||||
|
||||
void UserController::addProductToShoppingList(Trench trench) {
|
||||
int index = this->_shoppingRepository->get(trench);
|
||||
int repo_index = this->_repo->get(trench);
|
||||
if(index==-1) {
|
||||
Trench trenchCopy = trench;
|
||||
trenchCopy.quantity(1);
|
||||
this->_shoppingRepository->add(trenchCopy);
|
||||
trench.quantity(trench.quantity()-1);
|
||||
(*this->_repo)[repo_index].quantity((*this->_repo)[repo_index].quantity()-1);
|
||||
return;
|
||||
}
|
||||
trench.quantity(trench.quantity()-1);
|
||||
this->_shoppingRepository->update(index,trench.price(),(*this->_shoppingRepository)[index].quantity()+1);
|
||||
(*this->_repo)[repo_index].quantity((*this->_repo)[repo_index].quantity()-1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
int UserController::shoppingListTotal() {
|
||||
int total = 0;
|
||||
for(Trench i : *this->_shoppingRepository) {
|
||||
total+=i.quantity()*i.price();
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
|
||||
std::vector<Trench> UserController::getTrenchCarousel(int size) {
|
||||
std::vector<Trench> trenchCarousel;
|
||||
for(Trench i : *this->_repo){
|
||||
if((size == -1||i.size()==size) && i.quantity()>0){
|
||||
Trench copy = i;
|
||||
trenchCarousel.push_back(copy);
|
||||
}
|
||||
}
|
||||
return trenchCarousel;
|
||||
}
|
||||
|
||||
void UserController::openShoppingList() {
|
||||
this->_shoppingRepository->open();
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
#include "../../repository/FileRepository.h"
|
||||
#include "../../domain/trench.h"
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
class UserController {
|
||||
private:
|
||||
std::shared_ptr<FileRepository> _repo;
|
||||
std::shared_ptr<FileRepository> _shoppingRepository;
|
||||
public:
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Constructor for the UserController class
|
||||
* Input: repo - Repository object
|
||||
* Output: userController object
|
||||
*/
|
||||
UserController(std::shared_ptr<FileRepository> repo,std::shared_ptr<FileRepository> shoppingRepo);
|
||||
|
||||
/*
|
||||
* Destructor for the UserController class
|
||||
* Input: -
|
||||
* Output: -
|
||||
*/
|
||||
~UserController();
|
||||
|
||||
/*
|
||||
* Adds a trench coat to the shopping list
|
||||
* Input: trench - Trench object
|
||||
* Output: -
|
||||
*/
|
||||
void addProductToShoppingList(Trench trench);
|
||||
|
||||
/*
|
||||
* Returns the total price of the shopping list
|
||||
* Input: -
|
||||
* Output: total - integer
|
||||
*/
|
||||
int shoppingListTotal();
|
||||
|
||||
|
||||
/*
|
||||
* Returns a vector of trench coats that are in the shopping list
|
||||
* Input: size - integer
|
||||
* Output: trenchCarousel - vector<Trench*> object
|
||||
*/
|
||||
std::vector<Trench> getTrenchCarousel(int size);
|
||||
|
||||
void openShoppingList();
|
||||
|
||||
};
|
||||
@@ -0,0 +1,128 @@
|
||||
#include "trench.h"
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <exception>
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
Trench::Trench(int size, std::string colour, int price, int quantity, std::string photograph){
|
||||
this->_size = size;
|
||||
this->_colour = colour;
|
||||
this->_price = price;
|
||||
this->_quantity = quantity;
|
||||
this->_photograph=photograph;
|
||||
}
|
||||
|
||||
Trench::~Trench(){
|
||||
|
||||
}
|
||||
|
||||
Trench::Trench(const Trench &trench){
|
||||
_size = trench.size();
|
||||
_colour = trench.colour();
|
||||
_price = trench.price();
|
||||
_quantity = trench.quantity();
|
||||
_photograph = trench.photograph();
|
||||
}
|
||||
|
||||
Trench& Trench::operator=(const Trench &trench){
|
||||
this->_size = trench.size();
|
||||
this->_colour=trench.colour();
|
||||
this->_price = trench.price();
|
||||
this->_quantity = trench.quantity();
|
||||
this->_photograph = trench.photograph();
|
||||
return *this;
|
||||
}
|
||||
|
||||
int Trench::size() const {
|
||||
return this->_size;
|
||||
}
|
||||
|
||||
void Trench::size(int newSize){
|
||||
this->_size = newSize;
|
||||
}
|
||||
|
||||
std::string Trench::colour() const {
|
||||
return this->_colour;
|
||||
}
|
||||
|
||||
void Trench::colour(std::string newColour){
|
||||
this->_colour = newColour;
|
||||
}
|
||||
|
||||
int Trench::price() const {
|
||||
return this->_price;
|
||||
}
|
||||
|
||||
void Trench::price(int newPrice){
|
||||
this->_price = newPrice;
|
||||
}
|
||||
|
||||
int Trench::quantity() const{
|
||||
return this->_quantity;
|
||||
}
|
||||
|
||||
void Trench::quantity(int newQuantity){
|
||||
this->_quantity = newQuantity;
|
||||
}
|
||||
|
||||
std::string Trench::photograph() const {
|
||||
return this->_photograph;
|
||||
}
|
||||
|
||||
void Trench::photograph(std::string newPhotograph){
|
||||
this->_photograph = newPhotograph;
|
||||
}
|
||||
|
||||
bool Trench::operator==(const Trench& t){
|
||||
if(this->_size==t.size() && this->_colour == t.colour() && this->_photograph == t.photograph()){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Trench& trench){
|
||||
os << "Size: " << trench.size() << " | Colour: " << trench.colour() << " | Price: " << trench.price() << " | Quantity: " << trench.quantity() << " | Photograph Link: " << trench.photograph() << std::endl;
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ofstream& operator<<(std::ofstream& os, const Trench& trench){
|
||||
os << trench.size() << "," << trench.colour() << "," << trench.price() << "," << trench.quantity() << "," << trench.photograph() << std::endl;
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ifstream& operator>>(std::ifstream& is, Trench& trench){
|
||||
std::string line;
|
||||
std::getline(is, line);
|
||||
if(line == ""){
|
||||
return is;
|
||||
}
|
||||
std::string delimiter = ",";
|
||||
size_t pos = 0;
|
||||
std::string token;
|
||||
int i = 0;
|
||||
while ((pos = line.find(delimiter)) != std::string::npos) {
|
||||
token = line.substr(0, pos);
|
||||
switch(i){
|
||||
case 0:
|
||||
trench.size(std::stoi(token));
|
||||
break;
|
||||
case 1:
|
||||
trench.colour(token);
|
||||
break;
|
||||
case 2:
|
||||
trench.price(std::stoi(token));
|
||||
break;
|
||||
case 3:
|
||||
trench.quantity(std::stoi(token));
|
||||
break;
|
||||
}
|
||||
line.erase(0, pos + delimiter.length());
|
||||
i++;
|
||||
}
|
||||
trench.photograph(line);
|
||||
return is;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
class Trench {
|
||||
|
||||
private:
|
||||
|
||||
int _size;
|
||||
std::string _colour;
|
||||
int _price;
|
||||
int _quantity;
|
||||
std::string _photograph;
|
||||
|
||||
public:
|
||||
Trench()=default;
|
||||
|
||||
/*
|
||||
* Constructor for the Trench class
|
||||
* Input: size - integer
|
||||
* colour - string
|
||||
* price - integer
|
||||
* quantity - integer
|
||||
* photograph - string
|
||||
* Output: trench object
|
||||
*/
|
||||
Trench(int size, std::string colour, int price, int quantity, std::string photograph);
|
||||
|
||||
|
||||
/*
|
||||
* Destructor for the Trench class
|
||||
* Input: -
|
||||
* Output: -
|
||||
*/
|
||||
~Trench();
|
||||
|
||||
/*
|
||||
* Copy constructor for the Trench class
|
||||
* Input: trench - trench object
|
||||
* Output: trench object
|
||||
*/
|
||||
Trench(const Trench &trench);
|
||||
|
||||
/*
|
||||
* Overload of the = operator
|
||||
* Input: trench - trench object
|
||||
* Output: trench object
|
||||
*/
|
||||
Trench& operator=(const Trench &trench);
|
||||
|
||||
/*
|
||||
* Getter for the size attribute
|
||||
* Input: -
|
||||
* Output: size - integer
|
||||
*/
|
||||
int size() const;
|
||||
|
||||
/*
|
||||
* Setter for the size attribute
|
||||
* Input: newSize - integer
|
||||
* Output: -
|
||||
*/
|
||||
void size(int newSize);
|
||||
|
||||
/*
|
||||
* Getter for the colour attribute
|
||||
* Input: -
|
||||
* Output: colour - string
|
||||
*/
|
||||
std::string colour() const;
|
||||
|
||||
/*
|
||||
* Setter for the colour attribute
|
||||
* Input: newColour - string
|
||||
* Output: -
|
||||
*/
|
||||
void colour(std::string newColour);
|
||||
|
||||
/*
|
||||
* Getter for the price attribute
|
||||
* Input: -
|
||||
* Output: price - integer
|
||||
*/
|
||||
int price() const;
|
||||
|
||||
/*
|
||||
* Setter for the price attribute
|
||||
* Input: newPrice - integer
|
||||
* Output: -
|
||||
*/
|
||||
void price(int newPrice);
|
||||
|
||||
/*
|
||||
* Getter for the quantity attribute
|
||||
* Input: -
|
||||
* Output: quantity - integer
|
||||
*/
|
||||
int quantity() const;
|
||||
|
||||
/*
|
||||
* Setter for the quantity attribute
|
||||
* Input: newQuantity - integer
|
||||
* Output: -
|
||||
*/
|
||||
void quantity(int newQuantity);
|
||||
|
||||
/*
|
||||
* Getter for the photograph attribute
|
||||
* Input: -
|
||||
* Output: photograph - string
|
||||
*/
|
||||
std::string photograph() const;
|
||||
|
||||
/*
|
||||
* Setter for the photograph attribute
|
||||
* Input: newPhotograph - string
|
||||
* Output: -
|
||||
*/
|
||||
void photograph(std::string newPhotograph);
|
||||
|
||||
/*
|
||||
* Overload of the == operator
|
||||
* Input: trench - trench object
|
||||
* Output: true - if the trench objects are the same
|
||||
* false - otherwise
|
||||
*/
|
||||
bool operator==(const Trench& t);
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, const Trench& trench);
|
||||
|
||||
friend std::ofstream& operator<<(std::ofstream& os, const Trench& trench);
|
||||
|
||||
friend std::ifstream& operator>>(std::ifstream& is, Trench& trench);
|
||||
|
||||
};
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#include "exceptions.h"
|
||||
|
||||
RepoException::RepoException(const char* message){
|
||||
this->_message = message;
|
||||
}
|
||||
|
||||
const char* RepoException::what() const noexcept {
|
||||
return this->_message;
|
||||
}
|
||||
|
||||
AdminControllerException::AdminControllerException(const char* message){
|
||||
this->_message = message;
|
||||
}
|
||||
|
||||
const char* AdminControllerException::what() const noexcept {
|
||||
return this->_message;
|
||||
}
|
||||
|
||||
ValidatorException::ValidatorException(const char* message){
|
||||
this->_message = message;
|
||||
}
|
||||
|
||||
const char* ValidatorException::what() const noexcept {
|
||||
return this->_message;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#include <exception>
|
||||
|
||||
class RepoException : public std::exception {
|
||||
public:
|
||||
RepoException(const char* message);
|
||||
const char* what() const noexcept override;
|
||||
private:
|
||||
const char* _message;
|
||||
};
|
||||
|
||||
class AdminControllerException : public std::exception {
|
||||
public:
|
||||
AdminControllerException(const char* message);
|
||||
const char* what() const noexcept override;
|
||||
private:
|
||||
const char* _message;
|
||||
};
|
||||
|
||||
class ValidatorException : public std::exception{
|
||||
public:
|
||||
ValidatorException(const char* message);
|
||||
const char* what() const noexcept override;
|
||||
private:
|
||||
const char* _message;
|
||||
};
|
||||
@@ -0,0 +1,12 @@
|
||||
#include "repository/MemoryRepository.h"
|
||||
#include "repository/CSVRepository.h"
|
||||
#include "repository/HTMLRepository.h"
|
||||
#include "controllers/admin_controller/admin_controller.h"
|
||||
#include "ui/ui.h"
|
||||
|
||||
|
||||
int main(){
|
||||
UI ui;
|
||||
ui.run();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
#include "CSVRepository.h"
|
||||
|
||||
CSVRepository::CSVRepository(std::string fileName){
|
||||
this->_fileName = fileName;
|
||||
}
|
||||
|
||||
CSVRepository::~CSVRepository(){
|
||||
this->saveToFile();
|
||||
}
|
||||
|
||||
void CSVRepository::loadFromFile(){
|
||||
std::ifstream file(this->_fileName);
|
||||
if(!file.is_open()){
|
||||
return;
|
||||
}
|
||||
|
||||
while(true){
|
||||
Trench trench;
|
||||
file >> trench;
|
||||
if(file.eof()){
|
||||
break;
|
||||
}
|
||||
this->_data.push_back(trench);
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
|
||||
void CSVRepository::saveToFile(){
|
||||
std::ofstream file(this->_fileName);
|
||||
if(!file.is_open()){
|
||||
return;
|
||||
}
|
||||
for(auto trench : this->_data){
|
||||
file << trench;
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
|
||||
void CSVRepository::open(){
|
||||
std::string command = "notepad-plus-plus " + this->_fileName + " > /dev/null 2>&1";
|
||||
system(command.c_str());
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include "FileRepository.h"
|
||||
#include "../exceptions/exceptions.h"
|
||||
#include "../domain/trench.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
class CSVRepository : public FileRepository {
|
||||
private:
|
||||
std::string _fileName;
|
||||
void saveToFile() override;
|
||||
public:
|
||||
void loadFromFile();
|
||||
CSVRepository(std::string fileName);
|
||||
~CSVRepository();
|
||||
void open() override;
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
#include "FileRepository.h"
|
||||
|
||||
void FileRepository::add(Trench trench){
|
||||
MemoryRepository::add(trench);
|
||||
this->saveToFile();
|
||||
}
|
||||
|
||||
void FileRepository::remove(int index){
|
||||
MemoryRepository::remove(index);
|
||||
this->saveToFile();
|
||||
}
|
||||
|
||||
void FileRepository::remove(Trench trench){
|
||||
MemoryRepository::remove(trench);
|
||||
this->saveToFile();
|
||||
}
|
||||
|
||||
void FileRepository::update(int index, int price, int quantity){
|
||||
MemoryRepository::update(index, price, quantity);
|
||||
this->saveToFile();
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
#include "MemoryRepository.h"
|
||||
#include "../domain/trench.h"
|
||||
#include <string>
|
||||
|
||||
class FileRepository : public MemoryRepository {
|
||||
protected:
|
||||
std::string _fileName;
|
||||
virtual void saveToFile()=0;
|
||||
|
||||
public:
|
||||
FileRepository()=default;
|
||||
virtual ~FileRepository()=default;
|
||||
virtual void add(Trench trench) override;
|
||||
virtual void remove(Trench trench) override;
|
||||
virtual void remove(int index) override;
|
||||
virtual void update(int index, int price, int quantity) override;
|
||||
virtual void open()=0;
|
||||
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
#include "HTMLRepository.h"
|
||||
|
||||
|
||||
HTMLRepository::HTMLRepository(std::string fileName){
|
||||
this->_fileName = fileName;
|
||||
}
|
||||
|
||||
HTMLRepository::~HTMLRepository(){
|
||||
this->saveToFile();
|
||||
}
|
||||
|
||||
void HTMLRepository::saveToFile(){
|
||||
std::ofstream file(this->_fileName);
|
||||
if(!file.is_open()){
|
||||
return;
|
||||
}
|
||||
file << "<!DOCTYPE html><html><head><title>Shopping list</title></head><body><table border=\"1\"><tr><td>Size</td><td>Colour</td><td>Price</td><td>Quantity</td><td>Photograph Link</td><td>Photo</td></tr>";
|
||||
for(auto trench : this->_data){
|
||||
file << "<tr><td>" << trench.size() << "</td><td>" << trench.colour() << "</td><td>" << trench.price() << "</td><td>" << trench.quantity() << "</td><td>" << "<a href=\"" << trench.photograph() << "\">Link</a> " << "</td><td>" << "<img src=\"" << trench.photograph() << "\" width=100 height=100>" << "</td></tr>";
|
||||
}
|
||||
file << "</table></body></html>";
|
||||
file.close();
|
||||
}
|
||||
|
||||
void HTMLRepository::open(){
|
||||
std::string command = "xdg-open " + this->_fileName + " > /dev/null 2>&1";
|
||||
system(command.c_str());
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
#include "FileRepository.h"
|
||||
#include "../exceptions/exceptions.h"
|
||||
#include "../domain/trench.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
class HTMLRepository : public FileRepository {
|
||||
private:
|
||||
std::string _fileName;
|
||||
void saveToFile() override;
|
||||
public:
|
||||
HTMLRepository(std::string fileName);
|
||||
~HTMLRepository();
|
||||
void open() override;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
#include "MemoryRepository.h"
|
||||
#include "../exceptions/exceptions.h"
|
||||
|
||||
MemoryRepository::MemoryRepository(){
|
||||
|
||||
}
|
||||
MemoryRepository::~MemoryRepository(){
|
||||
|
||||
}
|
||||
void MemoryRepository::add(Trench trench){
|
||||
if(this->get(trench)!=-1)
|
||||
throw RepoException("Trench already exists");
|
||||
this->_data.push_back(trench);
|
||||
|
||||
}
|
||||
void MemoryRepository::remove(Trench trench){
|
||||
int index = this->get(trench);
|
||||
if(index==-1)
|
||||
throw RepoException("Trench does not exists");
|
||||
this->remove(index);
|
||||
}
|
||||
void MemoryRepository::remove(int index){
|
||||
if(index<0 || index > (int)(this->_data.size())-1)
|
||||
throw RepoException("Index out of bounds");
|
||||
this->_data.erase(this->_data.begin()+index);
|
||||
}
|
||||
|
||||
int MemoryRepository::get(Trench trench){
|
||||
for(int i=0;i<(int)(this->_data.size());i++){
|
||||
if(trench == this->_data[i])
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Trench& MemoryRepository::operator[](int index){
|
||||
if(index<0 || index > (int)(this->_data.size())-1)
|
||||
throw RepoException("Index out of bounds");
|
||||
return this->_data[index];
|
||||
}
|
||||
void MemoryRepository::update(int index, int price, int quantity){
|
||||
if(index<0 || index > (int)(this->_data.size())-1)
|
||||
throw RepoException("Index out of bounds");
|
||||
Trench& trench = this->_data[index];
|
||||
if(price!=-1 && price<=0)
|
||||
throw RepoException("Invalid price");
|
||||
if(quantity!=-1 && quantity<0)
|
||||
throw RepoException("Invalid quantity");
|
||||
if(price>0)
|
||||
trench.price(price);
|
||||
if(quantity>=0)
|
||||
trench.quantity(quantity);
|
||||
}
|
||||
|
||||
int MemoryRepository::size(){
|
||||
return this->_data.size();
|
||||
}
|
||||
|
||||
std::vector<Trench>::iterator MemoryRepository::begin(){
|
||||
return this->_data.begin();
|
||||
}
|
||||
std::vector<Trench>::iterator MemoryRepository::end(){
|
||||
return this->_data.end();
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
#pragma once
|
||||
#include "../domain/trench.h"
|
||||
#include <vector>
|
||||
#include "Repository.h"
|
||||
|
||||
class MemoryRepository : public Repository {
|
||||
|
||||
public:
|
||||
|
||||
/*
|
||||
* Constructor for the Repository class
|
||||
* Input: -
|
||||
* Output: repository object
|
||||
*/
|
||||
MemoryRepository();
|
||||
|
||||
/*
|
||||
* Destructor for the Repository class
|
||||
* Input: -
|
||||
* Output: -
|
||||
*/
|
||||
~MemoryRepository();
|
||||
|
||||
/*
|
||||
* Adds a trench to the repository
|
||||
* Input: trench - trench object
|
||||
* Output: -
|
||||
* Throws: RepoException if trench already exists
|
||||
*/
|
||||
void add(Trench trench) override;
|
||||
|
||||
/*
|
||||
* Removes a trench from the repository
|
||||
* Input: trench - trench object
|
||||
* Output: -
|
||||
* Throws: RepoException if trench does not exist
|
||||
*/
|
||||
void remove(Trench trench) override;
|
||||
|
||||
/*
|
||||
* Removes a trench from the repository
|
||||
* Input: index - index of the trench
|
||||
* Output: -
|
||||
* Throws: RepoException if index is out of bounds
|
||||
*/
|
||||
void remove(int index) override;
|
||||
|
||||
/*
|
||||
* Returns the index of a trench in the repository
|
||||
* Input: trench - trench object
|
||||
* Output: index of the trench. -1 if trench does not exist
|
||||
*/
|
||||
int get(Trench trench) override;
|
||||
|
||||
/*
|
||||
* Returns a trench from the repository
|
||||
* Input: index - index of the trench
|
||||
* Output: trench object
|
||||
* Throws: RepoException if index is out of bounds
|
||||
*/
|
||||
Trench& operator[](int index) override;
|
||||
|
||||
/*
|
||||
* Updates a trench from the repository
|
||||
* Input: index - index of the trench
|
||||
* price - new price
|
||||
* quantity - new quantity
|
||||
* Output: -
|
||||
* Throws: RepoException if index is out of bounds
|
||||
*/
|
||||
void update(int index, int price, int quantity) override;
|
||||
|
||||
/*
|
||||
* Returns the size of the repository
|
||||
* Input: -
|
||||
* Output: size of the repository
|
||||
*/
|
||||
int size() override;
|
||||
|
||||
/*
|
||||
* Returns an iterator to the beginning of the repository
|
||||
* Input: -
|
||||
* Output: iterator to the beginning of the repository
|
||||
*/
|
||||
std::vector<Trench>::iterator begin() override;
|
||||
|
||||
/*
|
||||
* Returns an iterator to the end of the repository
|
||||
* Input: -
|
||||
* Output: iterator to the end of the repository
|
||||
*/
|
||||
std::vector<Trench>::iterator end() override;
|
||||
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#include "../domain/trench.h"
|
||||
#include <vector>
|
||||
|
||||
class Repository {
|
||||
protected:
|
||||
std::vector<Trench> _data;
|
||||
public:
|
||||
Repository() = default;
|
||||
~Repository() = default;
|
||||
virtual void add(Trench trench) = 0;
|
||||
virtual void remove(Trench trench) = 0;
|
||||
virtual void remove(int index) = 0;
|
||||
virtual int get(Trench trench) = 0;
|
||||
virtual Trench& operator[](int index) = 0;
|
||||
virtual void update(int index, int price, int quantity) = 0;
|
||||
virtual int size() = 0;
|
||||
virtual std::vector<Trench>::iterator begin() = 0;
|
||||
virtual std::vector<Trench>::iterator end() = 0;
|
||||
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
#include<iostream>
|
||||
#include "tests/domain_tests/domain_tests.h"
|
||||
#include "tests/repo_tests/repo_tests.h"
|
||||
#include "tests/admin_controller_tests/admin_controller_tests.h"
|
||||
#include "tests/user_controller_tests/user_controller_tests.h"
|
||||
|
||||
|
||||
int main(){
|
||||
|
||||
test_domain();
|
||||
test_repo();
|
||||
test_admin_controller();
|
||||
test_user_controller();
|
||||
std::cout<<"All tests passed"<<std::endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,333 @@
|
||||
#include "ui.h"
|
||||
#include "../exceptions/exceptions.h"
|
||||
#include "../domain/trench.h"
|
||||
#include "../validator/validator.h"
|
||||
#include "../repository/Repository.h"
|
||||
#include "../repository/MemoryRepository.h"
|
||||
#include "../repository/CSVRepository.h"
|
||||
#include "../repository/HTMLRepository.h"
|
||||
#include "../controllers/admin_controller/admin_controller.h"
|
||||
#include "../controllers/user_controller/user_controller.h"
|
||||
#include <stdlib.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
|
||||
UI::UI(){
|
||||
std::shared_ptr<CSVRepository> repo = std::make_shared<CSVRepository>("repo.csv");
|
||||
repo->loadFromFile();
|
||||
std::shared_ptr<FileRepository> shoppingRepo;
|
||||
while(true){
|
||||
std::cout<<"1. CSV Repository"<<std::endl;
|
||||
std::cout<<"2. HTML Repository"<<std::endl;
|
||||
std::cout<<"Option: ";
|
||||
std::string buffer;
|
||||
getline(std::cin,buffer);
|
||||
if(buffer.length()!=1){
|
||||
std::cout<<"Invalid option!"<<std::endl;
|
||||
continue;
|
||||
}
|
||||
char option = buffer[0];
|
||||
switch(option){
|
||||
case '1':
|
||||
shoppingRepo = std::make_shared<CSVRepository>("shoppingRepo.csv");
|
||||
break;
|
||||
case '2':
|
||||
shoppingRepo = std::make_shared<HTMLRepository>("shoppingRepo.html");
|
||||
break;
|
||||
default:
|
||||
std::cout<<"Invalid option!"<<std::endl;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
this->_adminController = std::make_unique<AdminController>(repo);
|
||||
this->_userController = std::make_unique<UserController>(repo,shoppingRepo);
|
||||
}
|
||||
|
||||
|
||||
UI::~UI(){
|
||||
|
||||
}
|
||||
|
||||
void UI::run(){
|
||||
char option = 0;
|
||||
std::string buffer;
|
||||
while(1){
|
||||
std::cout<<"1. Run as admin"<<std::endl;
|
||||
std::cout<<"2. Run as user"<<std::endl;
|
||||
std::cout<<"3. Exit"<<std::endl;
|
||||
std::cout<<"Option: ";
|
||||
std::getline(std::cin,buffer);
|
||||
if(buffer.length()!=1){
|
||||
std::cout<<"Invalid option!"<<std::endl;
|
||||
continue;
|
||||
}
|
||||
option = buffer[0];
|
||||
switch(option){
|
||||
case '1':
|
||||
this->runAsAdmin();
|
||||
break;
|
||||
case '2':
|
||||
this->runAsUser();
|
||||
break;
|
||||
case '3':
|
||||
return;
|
||||
default:
|
||||
std::cout<<"Invalid option!"<<std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UI::runAsAdmin(){
|
||||
char option = 0;
|
||||
std::string buffer;
|
||||
while(1){
|
||||
std::cout<<"1. Add trench"<<std::endl;
|
||||
std::cout<<"2. Remove trench"<<std::endl;
|
||||
std::cout<<"3. Update trench"<<std::endl;
|
||||
std::cout<<"4. List all trenches"<<std::endl;
|
||||
std::cout<<"5. Exit"<<std::endl;
|
||||
std::cout<<"Option: ";
|
||||
std::getline(std::cin,buffer);
|
||||
if(buffer.length()!=1){
|
||||
std::cout<<"Invalid option!"<<std::endl;
|
||||
continue;
|
||||
}
|
||||
option = buffer[0];
|
||||
switch(option){
|
||||
case '1':
|
||||
{
|
||||
try{
|
||||
std::string buffer;
|
||||
int size;
|
||||
std::string colour;
|
||||
int price;
|
||||
int quantity;
|
||||
std::string photograph;
|
||||
std::cout<<"Size: ";
|
||||
getline(std::cin,buffer);
|
||||
Validator::validate_size(buffer);
|
||||
size = std::stoi(buffer);
|
||||
std::cout<<"Colour: ";
|
||||
getline(std::cin,colour);
|
||||
Validator::validate_colour(colour);
|
||||
std::cout<<"Price: ";
|
||||
getline(std::cin,buffer);
|
||||
Validator::validate_price(buffer);
|
||||
price = std::stoi(buffer);
|
||||
std::cout<<"Quantity: ";
|
||||
getline(std::cin,buffer);
|
||||
Validator::validate_quantity(buffer);
|
||||
quantity = std::stoi(buffer);
|
||||
std::cout<<"Photograph: ";
|
||||
getline(std::cin,photograph);
|
||||
Validator::validate_photograph(photograph);
|
||||
this->_adminController->add(size,colour,price,quantity,photograph);
|
||||
std::cout<<"Trench added!"<<std::endl;
|
||||
}
|
||||
catch(ValidatorException& e){
|
||||
std::cout<<e.what()<<std::endl;
|
||||
}
|
||||
catch(RepoException& e){
|
||||
std::cout<<e.what()<<std::endl;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '2':
|
||||
{
|
||||
try{
|
||||
std::string buffer;
|
||||
int size;
|
||||
std::string colour;
|
||||
std::string photograph;
|
||||
std::cout<<"Size: ";
|
||||
getline(std::cin,buffer);
|
||||
Validator::validate_size(buffer);
|
||||
size = std::stoi(buffer);
|
||||
std::cout<<"Colour: ";
|
||||
getline(std::cin,colour);
|
||||
Validator::validate_colour(colour);
|
||||
std::cout<<"Photograph: ";
|
||||
getline(std::cin,photograph);
|
||||
Validator::validate_photograph(photograph);
|
||||
this->_adminController->remove(size,colour,photograph);
|
||||
std::cout<<"Trench removed!"<<std::endl;
|
||||
}
|
||||
catch(ValidatorException& e){
|
||||
std::cout<<e.what()<<std::endl;
|
||||
}
|
||||
catch(RepoException& e){
|
||||
std::cout<<e.what()<<std::endl;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '3':
|
||||
{
|
||||
try{
|
||||
std::string buffer;
|
||||
int size;
|
||||
std::string colour;
|
||||
int price;
|
||||
int quantity;
|
||||
std::string photograph;
|
||||
std::cout<<"Size: ";
|
||||
getline(std::cin,buffer);
|
||||
Validator::validate_size(buffer);
|
||||
size = std::stoi(buffer);
|
||||
std::cout<<"Colour: ";
|
||||
getline(std::cin,colour);
|
||||
Validator::validate_colour(colour);
|
||||
std::cout<<"Price: (type enter to not change it) ";
|
||||
getline(std::cin,buffer);
|
||||
if (buffer.length()!=0){
|
||||
Validator::validate_price(buffer);
|
||||
price = std::stoi(buffer);
|
||||
}
|
||||
else
|
||||
price = -1;
|
||||
std::cout<<"Quantity: (type enter to not change it) ";
|
||||
getline(std::cin,buffer);
|
||||
if (buffer.length()!=0){
|
||||
Validator::validate_quantity(buffer);
|
||||
quantity = std::stoi(buffer);
|
||||
}
|
||||
else
|
||||
quantity = -1;
|
||||
std::cout<<"Photograph: ";
|
||||
getline(std::cin,photograph);
|
||||
Validator::validate_photograph(photograph);
|
||||
this->_adminController->update(size,colour,price,quantity,photograph);
|
||||
std::cout<<"Trench updated!"<<std::endl;
|
||||
}
|
||||
catch(ValidatorException& e){
|
||||
std::cout<<e.what()<<std::endl;
|
||||
}
|
||||
catch(RepoException& e){
|
||||
std::cout<<e.what()<<std::endl;
|
||||
}
|
||||
catch(AdminControllerException& e){
|
||||
std::cout<<e.what()<<std::endl;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '4':
|
||||
for(Trench i:*this->_adminController->getAll()){
|
||||
std::cout<<i;
|
||||
}
|
||||
break;
|
||||
case '5':
|
||||
return;
|
||||
default:
|
||||
std::cout<<"Invalid option!"<<std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UI::runAsUser(){
|
||||
char option;
|
||||
std::string buffer;
|
||||
while(1){
|
||||
std::cout<<"1. Show all trench coats in a given size"<<std::endl;
|
||||
std::cout<<"2. Show shopping cart"<<std::endl;
|
||||
std::cout<<"3. Exit"<<std::endl;
|
||||
std::cout<<"Option: ";
|
||||
std::getline(std::cin,buffer);
|
||||
if(buffer.length()!=1){
|
||||
std::cout<<"Invalid option!"<<std::endl;
|
||||
continue;
|
||||
}
|
||||
option = buffer[0];
|
||||
switch(option){
|
||||
case '1':
|
||||
{
|
||||
std::string buffer;
|
||||
int size;
|
||||
std::cout<<"Size: ";
|
||||
getline(std::cin,buffer);
|
||||
if (buffer.length()!=0){
|
||||
try{
|
||||
Validator::validate_size(buffer);
|
||||
}
|
||||
catch(ValidatorException& e){
|
||||
std::cout<<e.what()<<std::endl;
|
||||
continue;
|
||||
}
|
||||
size = std::stoi(buffer);
|
||||
}
|
||||
else
|
||||
size = -1;
|
||||
std::vector<Trench> iterator = this->_userController->getTrenchCarousel(size);
|
||||
if(iterator.size()==0){
|
||||
std::cout<<"No trench coats found!"<<std::endl;
|
||||
continue;
|
||||
}
|
||||
int exit = 1;
|
||||
int index = 0;
|
||||
while(exit && iterator.size()){
|
||||
Trench s = iterator[index];
|
||||
std::cout<< s << std::endl;
|
||||
std::cout<<"Total price: "<<this->_userController->shoppingListTotal()<<std::endl;
|
||||
char option;
|
||||
std::string buffer;
|
||||
std::cout<<"1. Add to shopping cart"<<std::endl;
|
||||
std::cout<<"2. Next trench coat"<<std::endl;
|
||||
std::cout<<"3. Exit"<<std::endl;
|
||||
std::cout<<"Option: ";
|
||||
std::getline(std::cin,buffer);
|
||||
if(buffer.length()!=1){
|
||||
std::cout<<"Invalid option!"<<std::endl;
|
||||
continue;
|
||||
}
|
||||
option = buffer[0];
|
||||
switch(option){
|
||||
case '1':
|
||||
{
|
||||
this->_userController->addProductToShoppingList(iterator[index]);
|
||||
iterator[index].quantity(iterator[index].quantity()-1);
|
||||
if (iterator[index].quantity() == 0){
|
||||
iterator.erase(iterator.begin()+index);
|
||||
if(index==(int)(iterator.size()))
|
||||
index=0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '2':
|
||||
{
|
||||
index++;
|
||||
if(index==(int)(iterator.size()))
|
||||
index=0;
|
||||
break;
|
||||
}
|
||||
case '3':
|
||||
{
|
||||
exit=0;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
std::cout<<"Invalid option!"<<std::endl;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '2':
|
||||
{
|
||||
this->_userController->openShoppingList();
|
||||
}
|
||||
|
||||
case '3':
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
#include "../controllers/admin_controller/admin_controller.h"
|
||||
#include "../controllers/user_controller/user_controller.h"
|
||||
#include <memory>
|
||||
|
||||
|
||||
class UI {
|
||||
private:
|
||||
std::unique_ptr<AdminController> _adminController;
|
||||
std::unique_ptr<UserController> _userController;
|
||||
public:
|
||||
UI();
|
||||
~UI();
|
||||
void run();
|
||||
void runAsAdmin();
|
||||
void runAsUser();
|
||||
};
|
||||
@@ -0,0 +1,59 @@
|
||||
#include "validator.h"
|
||||
#include "../exceptions/exceptions.h"
|
||||
|
||||
void Validator::validate_size(const std::string& size) {
|
||||
if (size.length() == 0) {
|
||||
throw ValidatorException("Invalid size!");
|
||||
}
|
||||
for(size_t i=0;i<size.length();i++){
|
||||
if(size[i]<'0' || size[i]>'9'){
|
||||
throw ValidatorException("Invalid size!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (std::stoi(size) <= 0) {
|
||||
throw ValidatorException("Invalid size!");
|
||||
}
|
||||
}
|
||||
|
||||
void Validator::validate_colour(const std::string& colour) {
|
||||
if (colour.length() == 0) {
|
||||
throw ValidatorException("Invalid colour!");
|
||||
}
|
||||
}
|
||||
|
||||
void Validator::validate_price(const std::string& price) {
|
||||
if (price.length() == 0) {
|
||||
throw ValidatorException("Invalid price!");
|
||||
}
|
||||
for(size_t i=0;i<price.length();i++){
|
||||
if(price[i]<'0' || price[i]>'9'){
|
||||
throw ValidatorException("Invalid price!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (std::stoi(price) <= 0) {
|
||||
throw ValidatorException("Invalid price!");
|
||||
}
|
||||
}
|
||||
|
||||
void Validator::validate_quantity(const std::string& quantity) {
|
||||
if (quantity.length() == 0) {
|
||||
throw ValidatorException("Invalid quantity!");
|
||||
}
|
||||
for(size_t i=0;i<quantity.length();i++){
|
||||
if(quantity[i]<'0' || quantity[i]>'9'){
|
||||
throw ValidatorException("Invalid quantity!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (std::stoi(quantity) < 0) {
|
||||
throw ValidatorException("Invalid quantity!");
|
||||
}
|
||||
}
|
||||
|
||||
void Validator::validate_photograph(const std::string& photograph) {
|
||||
if (photograph.length() == 0) {
|
||||
throw ValidatorException("Invalid photograph!");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
class Validator {
|
||||
private:
|
||||
Validator()=default;
|
||||
public:
|
||||
static void validate_size(const std::string& size);
|
||||
static void validate_colour(const std::string& colour);
|
||||
static void validate_price(const std::string& price);
|
||||
static void validate_quantity(const std::string& quantity);
|
||||
static void validate_photograph(const std::string& photograph);
|
||||
};
|
||||
Reference in New Issue
Block a user