Self-complete
This commit is contained in:
Generated
+8
-1
@@ -3,8 +3,15 @@
|
||||
<component name="MaterialThemeProjectNewConfig">
|
||||
<option name="metadata">
|
||||
<MTProjectMetadataState>
|
||||
<option name="userId" value="-51ab2c09:19e209689d2:-7dc7" />
|
||||
<option name="migrated" value="true" />
|
||||
<option name="pristineConfig" value="false" />
|
||||
<option name="userId" value="51fce684:19c942ae0f3:-7ffd" />
|
||||
</MTProjectMetadataState>
|
||||
</option>
|
||||
<option name="titleBarState">
|
||||
<MTProjectTitleBarConfigState>
|
||||
<option name="overrideColor" value="false" />
|
||||
</MTProjectTitleBarConfigState>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
+37
-17
@@ -3,22 +3,42 @@ project(Lab8)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
include(FetchContent)
|
||||
|
||||
FetchContent_Declare(
|
||||
nlohmann_json
|
||||
GIT_REPOSITORY https://github.com/nlohmann/json.git
|
||||
GIT_TAG v3.11.3
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(nlohmann_json)
|
||||
|
||||
add_executable(Lab8
|
||||
src/TaxRates.h
|
||||
src/Property.h
|
||||
src/Property.cpp
|
||||
src/Apartment.cpp
|
||||
src/Apartment.h
|
||||
src/Car.cpp
|
||||
src/Car.h
|
||||
src/CountryHouse.cpp
|
||||
src/CountryHouse.h
|
||||
src/main.cpp
|
||||
src/Property/Property.cpp
|
||||
src/Property/Property.h
|
||||
src/Apartment/Apartment.cpp
|
||||
src/Apartment/Apartment.h
|
||||
src/Car/Car.cpp
|
||||
src/Car/Car.h
|
||||
src/CountryHouse/CountryHouse.cpp
|
||||
src/CountryHouse/CountryHouse.h
|
||||
src/Owner/Owner.cpp
|
||||
src/Owner/Owner.h
|
||||
src/TaxRates/TaxRates.h
|
||||
src/Human/Human.cpp
|
||||
src/Human/Human.h
|
||||
src/City/City.cpp
|
||||
src/City/City.h
|
||||
src/PropertyFactory/PropertyFactory.cpp
|
||||
src/PropertyFactory/PropertyFactory.h)
|
||||
src/Owner.cpp
|
||||
src/Owner.h
|
||||
src/Ijsonio.cpp
|
||||
src/Ijsonio.h
|
||||
src/PropertySimpleFactory.cpp
|
||||
src/PropertySimpleFactory.h
|
||||
src/TaxService.cpp
|
||||
src/TaxService.h
|
||||
src/tinyxml2.cpp
|
||||
src/tinyxml2.h
|
||||
src/Ixmlio.cpp
|
||||
src/Ixmlio.h
|
||||
src/FileType.h
|
||||
src/FileTypeFactory.h
|
||||
src/FileTypeFactory.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(Lab8 PRIVATE nlohmann_json::nlohmann_json)
|
||||
|
||||
+124
-23
@@ -1,42 +1,143 @@
|
||||
@startuml
|
||||
skinparam classAttributeIconSize 0
|
||||
|
||||
class Property {
|
||||
# double price
|
||||
# string address
|
||||
+ show()
|
||||
+ clone()
|
||||
title Lab8 - Property Tax System
|
||||
|
||||
' =======================
|
||||
' ENUM
|
||||
' =======================
|
||||
enum FileType {
|
||||
JSON
|
||||
XML
|
||||
ANOTHER
|
||||
}
|
||||
|
||||
' =======================
|
||||
' INTERFACES
|
||||
' =======================
|
||||
interface Ijsonio {
|
||||
+fromJson(json)
|
||||
+toJson() : json
|
||||
}
|
||||
|
||||
interface Ixmlio {
|
||||
+fromXml(XMLElement*)
|
||||
+toXml(XMLDocument&) : XMLElement*
|
||||
}
|
||||
|
||||
' =======================
|
||||
' ABSTRACT CLASS
|
||||
' =======================
|
||||
abstract class Property {
|
||||
#worth : double
|
||||
|
||||
+Property(worth)
|
||||
+calculateTax() : double
|
||||
+incomeTax() : double
|
||||
|
||||
+fromJson(json)
|
||||
+toJson() : json
|
||||
+fromXml(XMLElement*)
|
||||
+toXml(XMLDocument&) : XMLElement*
|
||||
|
||||
+~Property()
|
||||
}
|
||||
|
||||
Property ..|> Ijsonio
|
||||
Property ..|> Ixmlio
|
||||
|
||||
' =======================
|
||||
' DERIVED CLASSES
|
||||
' =======================
|
||||
class Apartment {
|
||||
- int rooms
|
||||
+ show()
|
||||
+ clone()
|
||||
#square : double
|
||||
+calculateTax() : double
|
||||
}
|
||||
|
||||
class Car {
|
||||
- string brand
|
||||
- int horsepower
|
||||
+ show()
|
||||
+ clone()
|
||||
#horsepower : double
|
||||
+calculateTax() : double
|
||||
}
|
||||
|
||||
class CountryHouse {
|
||||
- int floors
|
||||
- double landArea
|
||||
+ show()
|
||||
+ clone()
|
||||
}
|
||||
|
||||
class City {
|
||||
- vector<Property>
|
||||
+ addProperty()
|
||||
+ showAll()
|
||||
#distanceFromCity : double
|
||||
+calculateTax() : double
|
||||
}
|
||||
|
||||
Property <|-- Apartment
|
||||
Property <|-- Car
|
||||
Property <|-- CountryHouse
|
||||
|
||||
City o-- Property
|
||||
' =======================
|
||||
' OWNER
|
||||
' =======================
|
||||
class Owner {
|
||||
-fullname : string
|
||||
-inn : string
|
||||
-properties : vector<Property*>
|
||||
|
||||
+addProperty(Property*)
|
||||
+removeProperty(int)
|
||||
+calculateTotalTax() : double
|
||||
+showProperties()
|
||||
|
||||
+fromJson(json)
|
||||
+toJson() : json
|
||||
+fromXml(XMLElement*)
|
||||
+toXml(XMLDocument&) : XMLElement*
|
||||
|
||||
+~Owner()
|
||||
}
|
||||
|
||||
Owner ..|> Ijsonio
|
||||
Owner ..|> Ixmlio
|
||||
|
||||
Owner *-- Property : owns
|
||||
|
||||
' =======================
|
||||
' FACTORY
|
||||
' =======================
|
||||
class PropertySimpleFactory {
|
||||
+static getProperty(key : string) : Property*
|
||||
}
|
||||
|
||||
Owner ..> PropertySimpleFactory
|
||||
|
||||
' =======================
|
||||
' SERVICE LAYER
|
||||
' =======================
|
||||
class TaxService {
|
||||
-owners : vector<Owner*>
|
||||
|
||||
+load(filename)
|
||||
+save(filename)
|
||||
|
||||
+loadFromJson()
|
||||
+saveToJson()
|
||||
|
||||
+loadFromXml()
|
||||
+saveToXml()
|
||||
|
||||
+addOwner()
|
||||
+removeOwner()
|
||||
|
||||
+addProperty()
|
||||
+removeProperty()
|
||||
|
||||
+showOwners()
|
||||
|
||||
+~TaxService()
|
||||
}
|
||||
|
||||
TaxService o-- Owner
|
||||
|
||||
' =======================
|
||||
' FILE TYPE FACTORY
|
||||
' =======================
|
||||
class FileTypeFactory {
|
||||
+static getFileType(filename) : FileType
|
||||
}
|
||||
|
||||
FileTypeFactory ..> FileType
|
||||
|
||||
@enduml
|
||||
@@ -0,0 +1,74 @@
|
||||
#include "Apartment.h"
|
||||
#include "TaxRates.h"
|
||||
|
||||
Apartment::Apartment(double worth, double square)
|
||||
: Property(worth)
|
||||
{
|
||||
this->square = square;
|
||||
}
|
||||
|
||||
double Apartment::calculateTax()
|
||||
{
|
||||
if (square > TAX_RATES::LIMIT_APARTMENT_SQUARE)
|
||||
{
|
||||
return worth * TAX_RATES::APARTMENT_LUXURY_TAX;
|
||||
}
|
||||
|
||||
return worth * TAX_RATES::APARTMENT_TAX;
|
||||
}
|
||||
|
||||
void Apartment::fromJson(json j)
|
||||
{
|
||||
worth = j["worth"];
|
||||
|
||||
square = j["square"];
|
||||
}
|
||||
|
||||
json Apartment::toJson()
|
||||
{
|
||||
json j;
|
||||
|
||||
j["worth"] = worth;
|
||||
|
||||
j["square"] = square;
|
||||
|
||||
j["tax"] = calculateTax();
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
void Apartment::fromXml(
|
||||
XMLElement* element)
|
||||
{
|
||||
element->QueryDoubleAttribute(
|
||||
"worth",
|
||||
&worth
|
||||
);
|
||||
|
||||
element->QueryDoubleAttribute(
|
||||
"square",
|
||||
&square
|
||||
);
|
||||
}
|
||||
|
||||
XMLElement* Apartment::toXml(
|
||||
XMLDocument& doc)
|
||||
{
|
||||
XMLElement* element =
|
||||
doc.NewElement("Apartment");
|
||||
element->SetAttribute(
|
||||
"worth",
|
||||
worth
|
||||
);
|
||||
|
||||
element->SetAttribute(
|
||||
"square",
|
||||
square
|
||||
);
|
||||
|
||||
element->SetAttribute(
|
||||
"tax",
|
||||
calculateTax()
|
||||
);
|
||||
return element;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "Property.h"
|
||||
|
||||
class Apartment : public Property
|
||||
{
|
||||
private:
|
||||
double square;
|
||||
|
||||
public:
|
||||
Apartment(double worth, double square);
|
||||
|
||||
void fromJson(json j) override;
|
||||
|
||||
json toJson() override;
|
||||
|
||||
void fromXml(XMLElement* element) override;
|
||||
|
||||
XMLElement* toXml(XMLDocument& doc) override;
|
||||
|
||||
double calculateTax() override;
|
||||
};
|
||||
@@ -1,45 +0,0 @@
|
||||
#include "Apartment.h"
|
||||
#include <iostream>
|
||||
|
||||
Apartment::Apartment() {
|
||||
rooms = 0;
|
||||
|
||||
std::cout << "Apartment created\n";
|
||||
}
|
||||
|
||||
Apartment::Apartment(double price,
|
||||
std::string address,
|
||||
int rooms)
|
||||
: Property(price, address) {
|
||||
|
||||
this->rooms = rooms;
|
||||
|
||||
std::cout << "Apartment created\n";
|
||||
}
|
||||
|
||||
void Apartment::addResident(Human* resident) {
|
||||
residents.push_back(resident);
|
||||
}
|
||||
|
||||
void Apartment::show() const {
|
||||
|
||||
std::cout
|
||||
<< "\nApartment\n"
|
||||
<< "Address: " << address << std::endl
|
||||
<< "Price: " << price << std::endl
|
||||
<< "Rooms: " << rooms << std::endl;
|
||||
|
||||
std::cout << "Residents:\n";
|
||||
|
||||
for (int i = 0; i < residents.size(); i++) {
|
||||
residents[i]->showInfo();
|
||||
}
|
||||
}
|
||||
|
||||
Apartment::~Apartment() {
|
||||
std::cout << "Apartment deleted\n";
|
||||
}
|
||||
|
||||
std::unique_ptr<Property> Apartment::clone() const {
|
||||
return std::make_unique<Apartment>(*this);
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
#ifndef APARTMENT_H
|
||||
#define APARTMENT_H
|
||||
|
||||
#include "../Property/Property.h"
|
||||
#include "../Human/Human.h"
|
||||
#include <vector>
|
||||
|
||||
class Apartment : public Property {
|
||||
private:
|
||||
int rooms;
|
||||
std::vector<Human*> residents;
|
||||
|
||||
public:
|
||||
Apartment();
|
||||
Apartment(double price,
|
||||
std::string address,
|
||||
int rooms);
|
||||
|
||||
void addResident(Human* resident);
|
||||
|
||||
void show() const override;
|
||||
|
||||
~Apartment();
|
||||
};
|
||||
|
||||
#endif
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
#include "Car.h"
|
||||
#include "TaxRates.h"
|
||||
|
||||
Car::Car(double worth,
|
||||
double horsepower)
|
||||
: Property(worth)
|
||||
{
|
||||
this->horsepower = horsepower;
|
||||
}
|
||||
|
||||
double Car::calculateTax()
|
||||
{
|
||||
if (horsepower <
|
||||
TAX_RATES::LOW_HORSEPOWER)
|
||||
{
|
||||
return worth *
|
||||
TAX_RATES::CAR_TAX;
|
||||
}
|
||||
|
||||
if (horsepower <=
|
||||
TAX_RATES::HIGH_HORSEPOWER)
|
||||
{
|
||||
return worth *
|
||||
TAX_RATES::CAR_TRUCK_TAX;
|
||||
}
|
||||
|
||||
return worth *
|
||||
TAX_RATES::CAR_LUXURY_TAX;
|
||||
}
|
||||
|
||||
void Car::fromJson(json j)
|
||||
{
|
||||
worth = j["worth"];
|
||||
|
||||
horsepower =
|
||||
j["horsepower"];
|
||||
}
|
||||
|
||||
json Car::toJson()
|
||||
{
|
||||
json j;
|
||||
|
||||
j["worth"] = worth;
|
||||
|
||||
j["horsepower"] =
|
||||
horsepower;
|
||||
|
||||
j["tax"] =
|
||||
calculateTax();
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
void Car::fromXml(
|
||||
XMLElement* element)
|
||||
{
|
||||
element->QueryDoubleAttribute(
|
||||
"worth",
|
||||
&worth
|
||||
);
|
||||
|
||||
element->QueryDoubleAttribute(
|
||||
"horsepower",
|
||||
&horsepower
|
||||
);
|
||||
}
|
||||
|
||||
XMLElement* Car::toXml(
|
||||
XMLDocument& doc)
|
||||
{
|
||||
XMLElement* element =
|
||||
doc.NewElement("Car");
|
||||
|
||||
element->SetAttribute(
|
||||
"worth",
|
||||
worth
|
||||
);
|
||||
|
||||
element->SetAttribute(
|
||||
"horsepower",
|
||||
horsepower
|
||||
);
|
||||
|
||||
element->SetAttribute(
|
||||
"tax",
|
||||
calculateTax()
|
||||
);
|
||||
|
||||
return element;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include "Property.h"
|
||||
#include "Ijsonio.h"
|
||||
|
||||
class Car : public Property
|
||||
{
|
||||
private:
|
||||
double horsepower;
|
||||
|
||||
public:
|
||||
Car(double worth,
|
||||
double horsepower);
|
||||
|
||||
double calculateTax() override;
|
||||
|
||||
void fromJson(json j) override;
|
||||
|
||||
json toJson() override;
|
||||
|
||||
void fromXml(XMLElement* element) override;
|
||||
|
||||
XMLElement* toXml(XMLDocument& doc) override;
|
||||
};
|
||||
@@ -1,38 +0,0 @@
|
||||
#include "Car.h"
|
||||
#include <iostream>
|
||||
|
||||
Car::Car() {
|
||||
brand = "Unknown";
|
||||
horsepower = 0;
|
||||
|
||||
std::cout << "Car created\n";
|
||||
}
|
||||
|
||||
Car::Car(double price,
|
||||
std::string address,
|
||||
std::string brand,
|
||||
int horsepower)
|
||||
: Property(price, address) {
|
||||
|
||||
this->brand = brand;
|
||||
this->horsepower = horsepower;
|
||||
|
||||
std::cout << "Car created\n";
|
||||
}
|
||||
|
||||
void Car::show() const {
|
||||
|
||||
std::cout
|
||||
<< "\nCar\n"
|
||||
<< "Brand: " << brand << std::endl
|
||||
<< "Horsepower: " << horsepower << std::endl
|
||||
<< "Price: " << price << std::endl;
|
||||
}
|
||||
|
||||
Car::~Car() {
|
||||
std::cout << "Car deleted\n";
|
||||
}
|
||||
|
||||
std::unique_ptr<Property> Car::clone() const {
|
||||
return std::make_unique<Car>(*this);
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
#ifndef CAR_H
|
||||
#define CAR_H
|
||||
|
||||
#include "../Property/Property.h"
|
||||
|
||||
class Car : public Property {
|
||||
private:
|
||||
std::string brand;
|
||||
int horsepower;
|
||||
|
||||
public:
|
||||
Car();
|
||||
|
||||
Car(double price,
|
||||
std::string address,
|
||||
std::string brand,
|
||||
int horsepower);
|
||||
|
||||
void show() const override;
|
||||
|
||||
~Car();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,49 +0,0 @@
|
||||
#include "City.h"
|
||||
#include <iostream>
|
||||
|
||||
City::City() {
|
||||
std::cout << "City created\n";
|
||||
}
|
||||
|
||||
City::City(const City& other) {
|
||||
std::cout << "City COPY\n";
|
||||
|
||||
for (const auto& p : other.properties) {
|
||||
properties.push_back(p->clone());
|
||||
}
|
||||
}
|
||||
|
||||
City& City::operator=(const City& other) {
|
||||
|
||||
std::cout << "City ASSIGN\n";
|
||||
|
||||
if (this == &other)
|
||||
return *this;
|
||||
|
||||
properties.clear();
|
||||
|
||||
for (const auto& p : other.properties) {
|
||||
properties.push_back(p->clone());
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
void City::addProperty(const Property& property) {
|
||||
properties.push_back(property.clone());
|
||||
}
|
||||
|
||||
void City::showAll() const {
|
||||
|
||||
std::cout << "\nCITY PROPERTY LIST\n";
|
||||
|
||||
for (const auto& p : properties) {
|
||||
p->show();
|
||||
}
|
||||
}
|
||||
|
||||
City::~City() {
|
||||
std::cout << "City destroyed\n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
#ifndef CITY_H
|
||||
#define CITY_H
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include "../Property/Property.h"
|
||||
|
||||
class City {
|
||||
private:
|
||||
std::vector<std::unique_ptr<Property>> properties;
|
||||
|
||||
public:
|
||||
City();
|
||||
|
||||
void addProperty(const Property& property);
|
||||
|
||||
void showAll() const;
|
||||
|
||||
City(const City& other);
|
||||
City& operator=(const City& other);
|
||||
|
||||
~City();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,74 @@
|
||||
#include "CountryHouse.h"
|
||||
#include "TaxRates.h"
|
||||
|
||||
CountryHouse::CountryHouse(double worth,
|
||||
double distanceFromCity)
|
||||
: Property(worth)
|
||||
{
|
||||
this->distanceFromCity = distanceFromCity;
|
||||
}
|
||||
|
||||
double CountryHouse::calculateTax()
|
||||
{
|
||||
return worth * TAX_RATES::COUNTRY_HOUSE_TAX;
|
||||
}
|
||||
|
||||
void CountryHouse::fromJson(json j)
|
||||
{
|
||||
worth = j["worth"];
|
||||
|
||||
distanceFromCity =
|
||||
j["distanceFromCity"];
|
||||
}
|
||||
|
||||
json CountryHouse::toJson()
|
||||
{
|
||||
json j;
|
||||
|
||||
j["worth"] = worth;
|
||||
|
||||
j["distanceFromCity"] =
|
||||
distanceFromCity;
|
||||
|
||||
j["tax"] = calculateTax();
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
void CountryHouse::fromXml(
|
||||
XMLElement* element)
|
||||
{
|
||||
element->QueryDoubleAttribute(
|
||||
"worth",
|
||||
&worth
|
||||
);
|
||||
|
||||
element->QueryDoubleAttribute(
|
||||
"distanceFromCity",
|
||||
&distanceFromCity
|
||||
);
|
||||
}
|
||||
|
||||
XMLElement* CountryHouse::toXml(
|
||||
XMLDocument& doc)
|
||||
{
|
||||
XMLElement* element =
|
||||
doc.NewElement("CountryHouse");
|
||||
|
||||
element->SetAttribute(
|
||||
"worth",
|
||||
worth
|
||||
);
|
||||
|
||||
element->SetAttribute(
|
||||
"distanceFromCity",
|
||||
distanceFromCity
|
||||
);
|
||||
|
||||
element->SetAttribute(
|
||||
"tax",
|
||||
calculateTax()
|
||||
);
|
||||
|
||||
return element;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "Property.h"
|
||||
#include "Ijsonio.h"
|
||||
|
||||
class CountryHouse : public Property
|
||||
{
|
||||
private:
|
||||
double distanceFromCity;
|
||||
|
||||
public:
|
||||
CountryHouse(double worth, double distanceFromCity);
|
||||
|
||||
void fromJson(json j) override;
|
||||
|
||||
json toJson() override;
|
||||
|
||||
double calculateTax() override;
|
||||
|
||||
void fromXml(XMLElement* element) override;
|
||||
|
||||
XMLElement* toXml(XMLDocument& doc) override;
|
||||
};
|
||||
@@ -1,39 +0,0 @@
|
||||
#include "CountryHouse.h"
|
||||
#include <iostream>
|
||||
|
||||
CountryHouse::CountryHouse() {
|
||||
floors = 0;
|
||||
landArea = 0;
|
||||
|
||||
std::cout << "CountryHouse created\n";
|
||||
}
|
||||
|
||||
CountryHouse::CountryHouse(double price,
|
||||
std::string address,
|
||||
int floors,
|
||||
double landArea)
|
||||
: Property(price, address) {
|
||||
|
||||
this->floors = floors;
|
||||
this->landArea = landArea;
|
||||
|
||||
std::cout << "CountryHouse created\n";
|
||||
}
|
||||
|
||||
void CountryHouse::show() const {
|
||||
|
||||
std::cout
|
||||
<< "\nCountry House\n"
|
||||
<< "Address: " << address << std::endl
|
||||
<< "Floors: " << floors << std::endl
|
||||
<< "Land area: " << landArea << std::endl
|
||||
<< "Price: " << price << std::endl;
|
||||
}
|
||||
|
||||
CountryHouse::~CountryHouse() {
|
||||
std::cout << "CountryHouse deleted\n";
|
||||
}
|
||||
|
||||
std::unique_ptr<Property> CountryHouse::clone() const {
|
||||
return std::make_unique<CountryHouse>(*this);
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
#ifndef COUNTRYHOUSE_H
|
||||
#define COUNTRYHOUSE_H
|
||||
|
||||
#include "../Property/Property.h"
|
||||
|
||||
class CountryHouse : public Property {
|
||||
private:
|
||||
int floors;
|
||||
double landArea;
|
||||
|
||||
public:
|
||||
CountryHouse();
|
||||
|
||||
CountryHouse(double price,
|
||||
std::string address,
|
||||
int floors,
|
||||
double landArea);
|
||||
|
||||
void show() const override;
|
||||
|
||||
~CountryHouse();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
enum class FileType
|
||||
{
|
||||
JSON,
|
||||
XML,
|
||||
ANOTHER
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
#include "FileTypeFactory.h"
|
||||
|
||||
FileType FileTypeFactory::getFileType(
|
||||
std::string filename)
|
||||
{
|
||||
if (filename.size() >= 5 &&
|
||||
filename.substr(
|
||||
filename.size() - 5
|
||||
) == ".json")
|
||||
{
|
||||
return FileType::JSON;
|
||||
}
|
||||
if (filename.size() >= 4 &&
|
||||
filename.substr(
|
||||
filename.size() - 4
|
||||
) == ".xml")
|
||||
{
|
||||
return FileType::XML;
|
||||
}
|
||||
return FileType::ANOTHER;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "FileType.h"
|
||||
|
||||
class FileTypeFactory
|
||||
{
|
||||
public:
|
||||
static FileType getFileType(
|
||||
std::string filename
|
||||
);
|
||||
};
|
||||
@@ -1,45 +0,0 @@
|
||||
#include "Human.h"
|
||||
#include <iostream>
|
||||
|
||||
Human::Human() {
|
||||
name = "Unknown";
|
||||
surname = "Unknown";
|
||||
age = 0;
|
||||
|
||||
std::cout << "Human created\n";
|
||||
}
|
||||
|
||||
Human::Human(std::string name, std::string surname, int age) {
|
||||
this->name = name;
|
||||
this->surname = surname;
|
||||
this->age = age;
|
||||
|
||||
std::cout << "Human created: "
|
||||
<< name << " "
|
||||
<< surname << std::endl;
|
||||
}
|
||||
|
||||
std::string Human::getName() const {
|
||||
return name;
|
||||
}
|
||||
|
||||
std::string Human::getSurname() const {
|
||||
return surname;
|
||||
}
|
||||
|
||||
int Human::getAge() const {
|
||||
return age;
|
||||
}
|
||||
|
||||
void Human::showInfo() const {
|
||||
std::cout
|
||||
<< name << " "
|
||||
<< surname << ", age: "
|
||||
<< age << std::endl;
|
||||
}
|
||||
|
||||
Human::~Human() {
|
||||
std::cout << "Human deleted: "
|
||||
<< name << " "
|
||||
<< surname << std::endl;
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
#ifndef HUMAN_H
|
||||
#define HUMAN_H
|
||||
|
||||
#include <string>
|
||||
|
||||
class Human {
|
||||
private:
|
||||
std::string name;
|
||||
std::string surname;
|
||||
int age;
|
||||
|
||||
public:
|
||||
Human();
|
||||
Human(std::string name, std::string surname, int age);
|
||||
|
||||
std::string getName() const;
|
||||
std::string getSurname() const;
|
||||
int getAge() const;
|
||||
|
||||
void showInfo() const;
|
||||
|
||||
~Human();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by Михаил on 22.05.2026.
|
||||
//
|
||||
|
||||
#include "Ijsonio.h"
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "nlohmann/json.hpp"
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
class Ijsonio
|
||||
{
|
||||
public:
|
||||
virtual void fromJson(json j) = 0;
|
||||
|
||||
virtual json toJson() = 0;
|
||||
|
||||
virtual ~Ijsonio() {}
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by Михаил on 22.05.2026.
|
||||
//
|
||||
|
||||
#include "Ixmlio.h"
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "tinyxml2.h"
|
||||
|
||||
using namespace tinyxml2;
|
||||
|
||||
class Ixmlio
|
||||
{
|
||||
public:
|
||||
virtual void fromXml(
|
||||
XMLElement* element
|
||||
) = 0;
|
||||
|
||||
virtual XMLElement* toXml(
|
||||
XMLDocument& doc
|
||||
) = 0;
|
||||
|
||||
virtual ~Ixmlio() {}
|
||||
};
|
||||
+239
@@ -0,0 +1,239 @@
|
||||
#include "Owner.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <cctype>
|
||||
|
||||
bool isValidINN(const std::string& inn)
|
||||
{
|
||||
if (inn.size() != 12)
|
||||
return false;
|
||||
|
||||
for (char c : inn)
|
||||
{
|
||||
if (!std::isdigit(c))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Owner::Owner(std::string fullname,
|
||||
std::string inn)
|
||||
{
|
||||
this->fullname = fullname;
|
||||
this->inn = inn;
|
||||
}
|
||||
|
||||
Owner::~Owner()
|
||||
{
|
||||
for (Property* property : properties)
|
||||
{
|
||||
delete property;
|
||||
}
|
||||
}
|
||||
|
||||
void Owner::addProperty(Property* property)
|
||||
{
|
||||
properties.push_back(property);
|
||||
}
|
||||
|
||||
void Owner::removeProperty(int index)
|
||||
{
|
||||
if (index < 0 || index >= properties.size())
|
||||
{
|
||||
std::cout << "Invalid index" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
delete properties[index];
|
||||
|
||||
properties.erase(properties.begin() + index);
|
||||
}
|
||||
|
||||
double Owner::calculateTotalTax()
|
||||
{
|
||||
double total = 0;
|
||||
|
||||
for (Property* property : properties)
|
||||
{
|
||||
total += property->calculateTax();
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
void Owner::showProperties()
|
||||
{
|
||||
std::cout << "Owner: "
|
||||
<< fullname
|
||||
<< std::endl;
|
||||
|
||||
std::cout << "INN: "
|
||||
<< inn
|
||||
<< std::endl;
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
for (int i = 0; i < properties.size(); i++)
|
||||
{
|
||||
std::cout << i + 1
|
||||
<< ". Tax: "
|
||||
<< properties[i]->calculateTax()
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "Total tax: "
|
||||
<< calculateTotalTax()
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
std::string Owner::getFullname() const
|
||||
{
|
||||
return fullname;
|
||||
}
|
||||
|
||||
int Owner::getPropertiesCount() const
|
||||
{
|
||||
return properties.size();
|
||||
}
|
||||
|
||||
void Owner::fromJson(json j)
|
||||
{
|
||||
fullname = j["fullname"];
|
||||
|
||||
inn = j["inn"];
|
||||
|
||||
json propertiesJson =
|
||||
j["properties"];
|
||||
|
||||
for (auto elem : propertiesJson)
|
||||
{
|
||||
std::string key =
|
||||
elem.items().begin().key();
|
||||
|
||||
Property* property =
|
||||
PropertySimpleFactory::
|
||||
getProperty(key);
|
||||
|
||||
property->fromJson(elem[key]);
|
||||
|
||||
properties.push_back(property);
|
||||
}
|
||||
}
|
||||
|
||||
json Owner::toJson()
|
||||
{
|
||||
json j;
|
||||
|
||||
j["fullname"] = fullname;
|
||||
|
||||
j["inn"] = inn;
|
||||
|
||||
j["totalTax"] =
|
||||
calculateTotalTax();
|
||||
|
||||
json propertiesJson =
|
||||
json::array();
|
||||
|
||||
for (Property* property : properties)
|
||||
{
|
||||
Apartment* apartment =
|
||||
dynamic_cast<Apartment*>(property);
|
||||
|
||||
if (apartment)
|
||||
{
|
||||
propertiesJson.push_back(
|
||||
{
|
||||
{
|
||||
"Apartment",
|
||||
apartment->toJson()
|
||||
}
|
||||
});
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
Car* car =
|
||||
dynamic_cast<Car*>(property);
|
||||
|
||||
if (car)
|
||||
{
|
||||
propertiesJson.push_back(
|
||||
{
|
||||
{
|
||||
"Car",
|
||||
car->toJson()
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
CountryHouse* house =
|
||||
dynamic_cast<CountryHouse*>(property);
|
||||
|
||||
if (house)
|
||||
{
|
||||
propertiesJson.push_back(
|
||||
{
|
||||
{
|
||||
"CountryHouse",
|
||||
house->toJson()
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
j["properties"] = propertiesJson;
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
void Owner::fromXml(
|
||||
XMLElement* element)
|
||||
{
|
||||
fullname =
|
||||
element->Attribute("fullname");
|
||||
|
||||
inn =
|
||||
element->Attribute("inn");
|
||||
XMLElement* child =
|
||||
element->FirstChildElement();
|
||||
while (child)
|
||||
{
|
||||
std::string key =
|
||||
child->Name();
|
||||
Property* property =
|
||||
PropertySimpleFactory::
|
||||
getProperty(key);
|
||||
property->fromXml(child);
|
||||
|
||||
properties.push_back(property);
|
||||
child =
|
||||
child->NextSiblingElement();
|
||||
}
|
||||
}
|
||||
XMLElement* Owner::toXml(
|
||||
XMLDocument& doc)
|
||||
{
|
||||
XMLElement* ownerElement =
|
||||
doc.NewElement("Owner");
|
||||
ownerElement->SetAttribute(
|
||||
"fullname",
|
||||
fullname.c_str()
|
||||
);
|
||||
|
||||
ownerElement->SetAttribute(
|
||||
"inn",
|
||||
inn.c_str()
|
||||
);
|
||||
for (Property* property : properties)
|
||||
{
|
||||
ownerElement->InsertEndChild(
|
||||
property->toXml(doc)
|
||||
);
|
||||
}
|
||||
return ownerElement;
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "Property.h"
|
||||
#include "Apartment.h"
|
||||
#include "Car.h"
|
||||
#include "CountryHouse.h"
|
||||
#include "Ixmlio.h"
|
||||
|
||||
#include "PropertySimpleFactory.h"
|
||||
|
||||
class Owner : public Ijsonio, public Ixmlio{
|
||||
private:
|
||||
std::string fullname;
|
||||
|
||||
std::string inn;
|
||||
|
||||
std::vector<Property*> properties;
|
||||
|
||||
public:
|
||||
Owner(std::string fullname,
|
||||
std::string inn);
|
||||
|
||||
~Owner();
|
||||
|
||||
void addProperty(Property* property);
|
||||
|
||||
void removeProperty(int index);
|
||||
|
||||
double calculateTotalTax();
|
||||
|
||||
void showProperties();
|
||||
|
||||
void fromJson(json j) override;
|
||||
|
||||
json toJson() override;
|
||||
|
||||
std::string getFullname() const;
|
||||
|
||||
int getPropertiesCount() const;
|
||||
|
||||
void fromXml(XMLElement* element) override;
|
||||
|
||||
XMLElement* toXml(XMLDocument& doc) override;
|
||||
|
||||
const std::vector<Property*>& getProperties() const;
|
||||
|
||||
};
|
||||
|
||||
bool isValidINN(const std::string& inn);
|
||||
@@ -1,31 +0,0 @@
|
||||
#include "Owner.h"
|
||||
#include <iostream>
|
||||
|
||||
Owner::Owner() : Human() {
|
||||
std::cout << "Owner created\n";
|
||||
}
|
||||
|
||||
Owner::Owner(std::string name,
|
||||
std::string surname,
|
||||
int age)
|
||||
: Human(name, surname, age) {
|
||||
|
||||
std::cout << "Owner created\n";
|
||||
}
|
||||
|
||||
void Owner::addProperty(Property* property) {
|
||||
properties.push_back(property);
|
||||
}
|
||||
|
||||
void Owner::showProperties() const {
|
||||
|
||||
std::cout << "\nOWNER PROPERTY LIST\n";
|
||||
|
||||
for (int i = 0; i < properties.size(); i++) {
|
||||
properties[i]->show();
|
||||
}
|
||||
}
|
||||
|
||||
Owner::~Owner() {
|
||||
std::cout << "Owner deleted\n";
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
#ifndef OWNER_H
|
||||
#define OWNER_H
|
||||
|
||||
#include "../Human/Human.h"
|
||||
#include "../Property/Property.h"
|
||||
#include <vector>
|
||||
|
||||
class Owner : public Human {
|
||||
private:
|
||||
std::vector<Property*> properties;
|
||||
|
||||
public:
|
||||
Owner();
|
||||
|
||||
Owner(std::string name,
|
||||
std::string surname,
|
||||
int age);
|
||||
|
||||
void addProperty(Property* property);
|
||||
|
||||
void showProperties() const;
|
||||
|
||||
~Owner();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,14 @@
|
||||
#include "Property.h"
|
||||
|
||||
Property::Property(double worth)
|
||||
{
|
||||
this->worth = worth;
|
||||
}
|
||||
|
||||
Property::~Property()
|
||||
{ }
|
||||
|
||||
double Property::calculateIncomeTax() const
|
||||
{
|
||||
return worth * 0.13;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "Ijsonio.h"
|
||||
#include "Ixmlio.h"
|
||||
|
||||
class Property :
|
||||
public Ijsonio,
|
||||
public Ixmlio
|
||||
{
|
||||
protected:
|
||||
double worth;
|
||||
|
||||
public:
|
||||
Property(double worth);
|
||||
|
||||
virtual ~Property();
|
||||
|
||||
virtual double calculateTax() = 0;
|
||||
|
||||
double calculateIncomeTax() const;
|
||||
};
|
||||
@@ -1,16 +0,0 @@
|
||||
#include "Property.h"
|
||||
#include <iostream>
|
||||
|
||||
Property::Property() {
|
||||
price = 0;
|
||||
address = "Unknown";
|
||||
}
|
||||
|
||||
Property::Property(double price, std::string address) {
|
||||
this->price = price;
|
||||
this->address = address;
|
||||
}
|
||||
|
||||
Property::~Property() {
|
||||
std::cout << "Property deleted\n";
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
#ifndef PROPERTY_H
|
||||
#define PROPERTY_H
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
class Property {
|
||||
protected:
|
||||
double price;
|
||||
std::string address;
|
||||
|
||||
public:
|
||||
Property();
|
||||
Property(double price, std::string address);
|
||||
|
||||
virtual void show() const = 0;
|
||||
|
||||
virtual std::unique_ptr<Property> clone() const = 0;
|
||||
|
||||
virtual ~Property();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,21 +0,0 @@
|
||||
#include "PropertyFactory.h"
|
||||
#include "../Apartment/Apartment.h"
|
||||
#include "../Car/Car.h"
|
||||
#include "../CountryHouse/CountryHouse.h"
|
||||
|
||||
std::unique_ptr<Property> PropertyFactory::create(Type type) {
|
||||
|
||||
switch (type) {
|
||||
|
||||
case APARTMENT:
|
||||
return std::make_unique<Apartment>(120000, "Moscow", 3);
|
||||
|
||||
case CAR:
|
||||
return std::make_unique<Car>(30000, "Garage", "BMW", 250);
|
||||
|
||||
case COUNTRY_HOUSE:
|
||||
return std::make_unique<CountryHouse>(500000, "Village", 2, 15.5);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
#ifndef PROPERTYFACTORY_H
|
||||
#define PROPERTYFACTORY_H
|
||||
|
||||
#include <memory>
|
||||
#include "../Property/Property.h"
|
||||
|
||||
class PropertyFactory {
|
||||
public:
|
||||
enum Type {
|
||||
APARTMENT,
|
||||
CAR,
|
||||
COUNTRY_HOUSE
|
||||
};
|
||||
|
||||
static std::unique_ptr<Property> create(Type type);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,26 @@
|
||||
#include "PropertySimpleFactory.h"
|
||||
|
||||
#include "Apartment.h"
|
||||
#include "Car.h"
|
||||
#include "CountryHouse.h"
|
||||
|
||||
Property* PropertySimpleFactory::
|
||||
getProperty(std::string key)
|
||||
{
|
||||
if (key == "Apartment")
|
||||
{
|
||||
return new Apartment(0, 0);
|
||||
}
|
||||
|
||||
if (key == "Car")
|
||||
{
|
||||
return new Car(0, 0);
|
||||
}
|
||||
|
||||
if (key == "CountryHouse")
|
||||
{
|
||||
return new CountryHouse(0, 0);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "Property.h"
|
||||
|
||||
class PropertySimpleFactory
|
||||
{
|
||||
public:
|
||||
static Property* getProperty(
|
||||
std::string key
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
namespace TAX_RATES
|
||||
{
|
||||
const double CAR_TAX = 0.0007;
|
||||
const double CAR_TRUCK_TAX = 0.007;
|
||||
const double CAR_LUXURY_TAX = 0.027;
|
||||
|
||||
const double APARTMENT_TAX = 0.001;
|
||||
const double APARTMENT_LUXURY_TAX = 0.004;
|
||||
|
||||
const double COUNTRY_HOUSE_TAX = 0.01;
|
||||
|
||||
const double LOW_HORSEPOWER = 100;
|
||||
const double HIGH_HORSEPOWER = 200;
|
||||
|
||||
const unsigned int LIMIT_DISTANCE_FROM_CITY = 30;
|
||||
|
||||
const int LIMIT_APARTMENT_SQUARE = 100;
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
#ifndef TAXRATES_H
|
||||
#define TAXRATES_H
|
||||
|
||||
namespace TAX_RATES {
|
||||
|
||||
// ==========================
|
||||
// НАЛОГИ ДЛЯ АВТОМОБИЛЕЙ
|
||||
// ==========================
|
||||
|
||||
const double CAR_TAX = 0.0007;
|
||||
|
||||
const double CAR_TRUCK_TAX = 0.007;
|
||||
|
||||
const double CAR_LUXURY_TAX = 0.027;
|
||||
|
||||
// ==========================
|
||||
// НАЛОГИ ДЛЯ КВАРТИР
|
||||
// ==========================
|
||||
|
||||
const double APARTMENT_TAX = 0.001;
|
||||
|
||||
const double APARTMENT_LUXURY_TAX = 0.004;
|
||||
|
||||
// ==========================
|
||||
// НАЛОГ ДЛЯ ДОМА
|
||||
// ==========================
|
||||
|
||||
const double COUNTRY_HOUSE_TAX = 0.01;
|
||||
|
||||
// ==========================
|
||||
// ГРАНИЦЫ
|
||||
// ==========================
|
||||
|
||||
const double LOW_HORSEPOWER = 100;
|
||||
|
||||
const double HIGH_HORSEPOWER = 200;
|
||||
|
||||
const unsigned int LIMIT_DISTANCE_FROM_CITY = 30;
|
||||
|
||||
const int LIMIT_APARTMENT_SQUARE = 100;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,413 @@
|
||||
#include "TaxService.h"
|
||||
#include "FileTypeFactory.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
TaxService::~TaxService()
|
||||
{
|
||||
for (Owner* owner : owners)
|
||||
{
|
||||
delete owner;
|
||||
}
|
||||
}
|
||||
void TaxService::loadFromJson(
|
||||
std::string filename)
|
||||
{
|
||||
std::ifstream in(filename);
|
||||
|
||||
if (!in.is_open())
|
||||
{
|
||||
throw std::runtime_error(
|
||||
"Cannot open input file"
|
||||
);
|
||||
}
|
||||
json j;
|
||||
|
||||
in >> j;
|
||||
|
||||
in.close();
|
||||
for (auto elem : j)
|
||||
{
|
||||
Owner* owner =
|
||||
new Owner("", "");
|
||||
|
||||
owner->fromJson(elem);
|
||||
|
||||
owners.push_back(owner);
|
||||
}
|
||||
}
|
||||
void TaxService::saveToJson(
|
||||
std::string filename)
|
||||
{
|
||||
json result =
|
||||
json::array();
|
||||
for (Owner* owner : owners)
|
||||
{
|
||||
result.push_back(
|
||||
owner->toJson()
|
||||
);
|
||||
}
|
||||
std::ofstream out(filename);
|
||||
|
||||
if (!out.is_open())
|
||||
{
|
||||
throw std::runtime_error(
|
||||
"Cannot open output file"
|
||||
);
|
||||
}
|
||||
|
||||
out << result.dump(4);
|
||||
|
||||
out.close();
|
||||
}
|
||||
void TaxService::showOwners()
|
||||
{
|
||||
for (Owner* owner : owners)
|
||||
{
|
||||
owner->showProperties();
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void TaxService::load(
|
||||
std::string filename)
|
||||
{
|
||||
FileType type =
|
||||
FileTypeFactory::
|
||||
getFileType(filename);
|
||||
switch (type)
|
||||
{
|
||||
case FileType::JSON:
|
||||
{
|
||||
loadFromJson(filename);
|
||||
break;
|
||||
}
|
||||
|
||||
case FileType::XML:
|
||||
{
|
||||
loadFromXml(filename);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
throw std::runtime_error(
|
||||
"Unknown file type"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
void TaxService::save(
|
||||
std::string filename)
|
||||
{
|
||||
FileType type =
|
||||
FileTypeFactory::
|
||||
getFileType(filename);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case FileType::JSON:
|
||||
{
|
||||
saveToJson(filename);
|
||||
break;
|
||||
}
|
||||
|
||||
case FileType::XML:
|
||||
{
|
||||
saveToXml(filename);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
throw std::runtime_error(
|
||||
"Unknown file type"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TaxService::loadFromXml(
|
||||
std::string filename)
|
||||
{
|
||||
XMLDocument doc;
|
||||
if (doc.LoadFile(
|
||||
filename.c_str())
|
||||
!= XML_SUCCESS)
|
||||
{
|
||||
throw std::runtime_error(
|
||||
"Cannot load XML"
|
||||
);
|
||||
}
|
||||
XMLElement* root =
|
||||
doc.FirstChildElement(
|
||||
"Owners"
|
||||
);
|
||||
XMLElement* elem =
|
||||
root->FirstChildElement(
|
||||
"Owner"
|
||||
);
|
||||
while (elem)
|
||||
{
|
||||
Owner* owner =
|
||||
new Owner("", "");
|
||||
|
||||
owner->fromXml(elem);
|
||||
|
||||
owners.push_back(owner);
|
||||
|
||||
elem =
|
||||
elem->NextSiblingElement(
|
||||
"Owner"
|
||||
);
|
||||
}
|
||||
}
|
||||
void TaxService::saveToXml(
|
||||
std::string filename)
|
||||
{
|
||||
XMLDocument doc;
|
||||
XMLElement* root =
|
||||
doc.NewElement("Owners");
|
||||
|
||||
doc.InsertFirstChild(root);
|
||||
for (Owner* owner : owners)
|
||||
{
|
||||
root->InsertEndChild(
|
||||
owner->toXml(doc)
|
||||
);
|
||||
}
|
||||
doc.SaveFile(
|
||||
filename.c_str()
|
||||
);
|
||||
}
|
||||
|
||||
void TaxService::addOwner()
|
||||
{
|
||||
std::string fullname;
|
||||
std::string inn;
|
||||
|
||||
std::cin.ignore();
|
||||
|
||||
std::cout << "Fullname: ";
|
||||
std::getline(std::cin, fullname);
|
||||
|
||||
std::cout << "INN (12 digits): ";
|
||||
std::getline(std::cin, inn);
|
||||
|
||||
if (!isValidINN(inn))
|
||||
{
|
||||
std::clog << "ERROR: Invalid INN\n";
|
||||
return;
|
||||
}
|
||||
|
||||
Owner* owner = new Owner(fullname, inn);
|
||||
owners.push_back(owner);
|
||||
|
||||
std::cout << "Owner added!\n";
|
||||
}
|
||||
void TaxService::removeOwner()
|
||||
{
|
||||
showOwners();
|
||||
int index;
|
||||
|
||||
std::cout
|
||||
<< "Owner index: ";
|
||||
|
||||
std::cin
|
||||
>> index;
|
||||
if (index < 0 ||
|
||||
index >= owners.size())
|
||||
{
|
||||
std::cout
|
||||
<< "Invalid index\n";
|
||||
|
||||
return;
|
||||
}
|
||||
delete owners[index];
|
||||
|
||||
owners.erase(
|
||||
owners.begin() + index
|
||||
);
|
||||
|
||||
std::cout
|
||||
<< "Owner removed!\n";
|
||||
}
|
||||
|
||||
void TaxService::addProperty() {
|
||||
showOwners();
|
||||
int ownerIndex;
|
||||
|
||||
std::cout
|
||||
<< "Choose owner: ";
|
||||
|
||||
std::cin
|
||||
>> ownerIndex;
|
||||
if (ownerIndex < 0 ||
|
||||
ownerIndex >= owners.size()) {
|
||||
std::cout
|
||||
<< "Invalid index\n";
|
||||
|
||||
return;
|
||||
}
|
||||
int type;
|
||||
|
||||
std::cout
|
||||
<< "\n1. Apartment\n";
|
||||
|
||||
std::cout
|
||||
<< "2. Car\n";
|
||||
|
||||
std::cout
|
||||
<< "3. CountryHouse\n";
|
||||
|
||||
std::cout
|
||||
<< "Choose type: ";
|
||||
|
||||
std::cin
|
||||
>> type;
|
||||
|
||||
if (type == 1) {
|
||||
double worth;
|
||||
double square;
|
||||
std::cout
|
||||
<< "Worth: ";
|
||||
|
||||
std::cin
|
||||
>> worth;
|
||||
|
||||
std::cout
|
||||
<< "Square: ";
|
||||
|
||||
std::cin
|
||||
>> square;
|
||||
owners[ownerIndex]
|
||||
->addProperty(
|
||||
new Apartment(
|
||||
worth,
|
||||
square
|
||||
)
|
||||
);
|
||||
} else if (type == 2) {
|
||||
double worth;
|
||||
double horsepower;
|
||||
|
||||
std::cout
|
||||
<< "Worth: ";
|
||||
|
||||
std::cin
|
||||
>> worth;
|
||||
|
||||
std::cout
|
||||
<< "Horsepower: ";
|
||||
|
||||
std::cin
|
||||
>> horsepower;
|
||||
|
||||
owners[ownerIndex]
|
||||
->addProperty(
|
||||
new Car(
|
||||
worth,
|
||||
horsepower
|
||||
)
|
||||
);
|
||||
} else if (type == 3) {
|
||||
double worth;
|
||||
double distance;
|
||||
|
||||
std::cout
|
||||
<< "Worth: ";
|
||||
|
||||
std::cin
|
||||
>> worth;
|
||||
|
||||
std::cout
|
||||
<< "Distance: ";
|
||||
|
||||
std::cin
|
||||
>> distance;
|
||||
|
||||
owners[ownerIndex]
|
||||
->addProperty(
|
||||
new CountryHouse(
|
||||
worth,
|
||||
distance
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void TaxService::removeProperty()
|
||||
{
|
||||
if (owners.empty())
|
||||
{
|
||||
std::cout << "No owners available\n";
|
||||
return;
|
||||
}
|
||||
|
||||
showOwners();
|
||||
|
||||
int ownerIndex;
|
||||
|
||||
std::cout << "Choose owner: ";
|
||||
std::cin >> ownerIndex;
|
||||
|
||||
if (std::cin.fail())
|
||||
{
|
||||
std::cin.clear();
|
||||
std::cin.ignore(
|
||||
std::numeric_limits<std::streamsize>::max(),
|
||||
'\n'
|
||||
);
|
||||
|
||||
std::cout << "Invalid input\n";
|
||||
return;
|
||||
}
|
||||
|
||||
if (ownerIndex < 0 || ownerIndex >= owners.size())
|
||||
{
|
||||
std::cout << "Invalid owner index\n";
|
||||
return;
|
||||
}
|
||||
|
||||
Owner* owner = owners[ownerIndex];
|
||||
|
||||
if (owner->getProperties().empty())
|
||||
{
|
||||
std::cout << "This owner has no properties\n";
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "\nProperties:\n";
|
||||
|
||||
owner->showProperties();
|
||||
|
||||
int propertyIndex;
|
||||
|
||||
std::cout << "Property index: ";
|
||||
std::cin >> propertyIndex;
|
||||
|
||||
if (std::cin.fail())
|
||||
{
|
||||
std::cin.clear();
|
||||
std::cin.ignore(
|
||||
std::numeric_limits<std::streamsize>::max(),
|
||||
'\n'
|
||||
);
|
||||
|
||||
std::cout << "Invalid input\n";
|
||||
return;
|
||||
}
|
||||
|
||||
if (propertyIndex < 0 ||
|
||||
propertyIndex >= owner->getProperties().size())
|
||||
{
|
||||
std::cout << "Invalid property index\n";
|
||||
return;
|
||||
}
|
||||
|
||||
owner->removeProperty(propertyIndex);
|
||||
|
||||
std::cout << "Property removed successfully\n";
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "Owner.h"
|
||||
|
||||
class TaxService
|
||||
{
|
||||
private:
|
||||
std::vector<Owner*> owners;
|
||||
|
||||
public:
|
||||
~TaxService();
|
||||
|
||||
void loadFromJson(
|
||||
std::string filename
|
||||
);
|
||||
|
||||
void saveToJson(
|
||||
std::string filename
|
||||
);
|
||||
|
||||
void showOwners();
|
||||
|
||||
void loadFromXml(
|
||||
std::string filename
|
||||
);
|
||||
|
||||
void saveToXml(
|
||||
std::string filename
|
||||
);
|
||||
|
||||
void load(std::string filename);
|
||||
|
||||
void save(std::string filename);
|
||||
|
||||
void addOwner();
|
||||
|
||||
void removeOwner();
|
||||
|
||||
void addProperty();
|
||||
|
||||
void removeProperty();
|
||||
};
|
||||
+163
-10
@@ -1,18 +1,171 @@
|
||||
#include "City/City.h"
|
||||
#include "Apartment/Apartment.h"
|
||||
#include "Car/Car.h"
|
||||
#include "CountryHouse/CountryHouse.h"
|
||||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
#include "TaxService.h"
|
||||
|
||||
City city;
|
||||
|
||||
city.addProperty(*PropertyFactory::create(PropertyFactory::CAR));
|
||||
city.addProperty(*PropertyFactory::create(PropertyFactory::APARTMENT));
|
||||
city.addProperty(*PropertyFactory::create(PropertyFactory::COUNTRY_HOUSE));
|
||||
int safeIntInput()
|
||||
{
|
||||
int x;
|
||||
|
||||
city.showAll();
|
||||
std::cin >> x;
|
||||
|
||||
while (std::cin.fail())
|
||||
{
|
||||
std::cin.clear();
|
||||
std::cin.ignore(
|
||||
std::numeric_limits<std::streamsize>::max(),
|
||||
'\n'
|
||||
);
|
||||
|
||||
std::cout << "Try again: ";
|
||||
std::cin >> x;
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
void showMenu()
|
||||
{
|
||||
std::cout
|
||||
<< "\n========================\n";
|
||||
|
||||
std::cout
|
||||
<< " TAX PROPERTY SERVICE\n";
|
||||
|
||||
std::cout
|
||||
<< "========================\n";
|
||||
|
||||
std::cout
|
||||
<< "1. Load file\n";
|
||||
|
||||
std::cout
|
||||
<< "2. Show owners\n";
|
||||
|
||||
std::cout
|
||||
<< "3. Add owner\n";
|
||||
|
||||
std::cout
|
||||
<< "4. Remove owner\n";
|
||||
|
||||
std::cout
|
||||
<< "5. Add property\n";
|
||||
|
||||
std::cout
|
||||
<< "6. Remove property\n";
|
||||
|
||||
std::cout
|
||||
<< "7. Save file\n";
|
||||
|
||||
std::cout
|
||||
<< "8. Exit\n";
|
||||
|
||||
std::cout
|
||||
<< "Choose: ";
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
TaxService service;
|
||||
|
||||
int choice;
|
||||
while (true)
|
||||
{
|
||||
showMenu();
|
||||
|
||||
int choice = safeIntInput();
|
||||
switch (choice)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
std::string filename;
|
||||
|
||||
std::cout
|
||||
<< "Input file: ";
|
||||
|
||||
std::cin
|
||||
>> filename;
|
||||
try
|
||||
{
|
||||
service.load(filename);
|
||||
|
||||
std::cout
|
||||
<< "Loaded!\n";
|
||||
}
|
||||
catch (std::exception& ex)
|
||||
{
|
||||
std::clog
|
||||
<< "ERROR: "
|
||||
<< ex.what()
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
service.showOwners();
|
||||
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
service.addOwner();
|
||||
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
service.removeOwner();
|
||||
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
service.addProperty();
|
||||
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
service.removeProperty();
|
||||
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
std::string filename;
|
||||
|
||||
std::cout
|
||||
<< "Output file: ";
|
||||
|
||||
std::cin
|
||||
>> filename;
|
||||
try
|
||||
{
|
||||
service.save(filename);
|
||||
|
||||
std::cout
|
||||
<< "Saved!\n";
|
||||
}
|
||||
catch (std::exception& ex)
|
||||
{
|
||||
std::clog
|
||||
<< "ERROR: "
|
||||
<< ex.what()
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 8:
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
{
|
||||
std::cout
|
||||
<< "Invalid choice\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+3047
File diff suppressed because it is too large
Load Diff
+2387
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user