diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml new file mode 100644 index 0000000..68ff19c --- /dev/null +++ b/.idea/dataSources.xml @@ -0,0 +1,12 @@ + + + + + mysql.8 + true + com.mysql.cj.jdbc.Driver + jdbc:mysql://localhost:3306/framework + $ProjectFileDir$ + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/config/database.php b/config/database.php new file mode 100644 index 0000000..9284f01 --- /dev/null +++ b/config/database.php @@ -0,0 +1,9 @@ + 'localhost', + 'database_name' => 'framework', + 'username' => 'student', + 'password' => 'password', + 'charset' => 'utf8' +]; diff --git a/config/routes.php b/config/routes.php index 70142af..5a0a1f6 100644 --- a/config/routes.php +++ b/config/routes.php @@ -5,12 +5,24 @@ 'controller' => 'index', 'action' => 'index' ], - '/hello' => [ - 'controller' => 'helloWorld', - 'action' => 'hello' + '/contracts' => [ + 'controller' => 'contracts', + 'action' => 'showContracts' ], - '/world' => [ - 'controller' => 'helloWorld', - 'action' => 'world' + '/addcontract' => [ + 'controller' => 'contracts', + 'action' => 'showContractsForm' ], + '/addsell' => [ + 'controller' => 'table', + 'action' => 'addSell' + ], + '/table' => [ + 'controller' => 'table', + 'action' => 'showTable' + ], + '/show' => [ + 'controller' => 'index', + 'action' => 'show' + ] ]; diff --git a/controllers/BasicController.php b/controllers/BasicController.php new file mode 100644 index 0000000..1303668 --- /dev/null +++ b/controllers/BasicController.php @@ -0,0 +1,20 @@ +contractsRepository = $contractsRepository; + $this->agentsRepository = $agentsRepository; + } + + + public function showContractsAction(Request $request) + { + return new Response($this->render('contracts', ['contractsRepository' => $this->contractsRepository])); + } + + public function showContractsFormAction(Request $request) + { + if ($request->isPost()) { + $contract = new Contract($request); + + $errors = ContractsErrorHandler::getErrors($contract, $this->contractsRepository); + if ($errors !== null) + return new Response($this->render('add-contract', ['errors' => $errors])); + + $this->contractsRepository->addContract($contract); + return new Response($this->render('contracts', ['contractsRepository' => $this->contractsRepository])); + } + return new Response($this->render('add-contract')); + } +} \ No newline at end of file diff --git a/controllers/HelloWorldController.php b/controllers/HelloWorldController.php deleted file mode 100644 index 7ff0cae..0000000 --- a/controllers/HelloWorldController.php +++ /dev/null @@ -1,54 +0,0 @@ -render('template', [ - 'title' => 'Hello page', - 'text' => 'hello' - ])); - } - - - /** - * World action - * @return Response - * - */ - public function worldAction() { - return new Response($this->render('template', [ - 'title' => 'World page', - 'text' => 'world' - ])); - } - - - protected function render($templateName, $vars = []) - { - ob_start(); - extract($vars); - include sprintf('templates/%s.php', $templateName); - $content = ob_get_contents(); - ob_end_clean(); - return $content; - } - - public function __call($name, $arguments) - { - return new Response('Sorry but this action not found', - '404', 'Not found'); - } - - -} \ No newline at end of file diff --git a/controllers/IndexController.php b/controllers/IndexController.php index f7e8633..ec8e166 100644 --- a/controllers/IndexController.php +++ b/controllers/IndexController.php @@ -1,35 +1,15 @@ render('welcome')); } - public function __call($name, $arguments) + public function errorAction(Request $request) { - return new Response('Sorry but this action not found', - '404', 'Not found'); + return new Response($this->render('404')); } - - } \ No newline at end of file diff --git a/controllers/TableController.php b/controllers/TableController.php new file mode 100644 index 0000000..da1c6de --- /dev/null +++ b/controllers/TableController.php @@ -0,0 +1,50 @@ +contractsRepository = $contractsRepository; + $this->sellsRepository = $sellsRepository; + $this->agentsRepository = $agentsRepository; + } + + + public function showTableAction(Request $request) + { + return new Response($this->render('comission-total', ['sellsRepository' => $this->sellsRepository, 'agentsRepository' => $this->agentsRepository])); + } + + public function addSellAction(Request $request) + { + if ($request->isPost()) { + + $sell = new Sell($request, $this->agentsRepository, $this->contractsRepository); + + $errors = TableErrorHandler::getErrors($sell, $this->sellsRepository); + if ($errors !== null) + return new Response($this->render('add-sell', ['contractsRepository' => $this->contractsRepository, 'errors' => $errors])); + + + $this->sellsRepository->addNewSell($sell); + return new Response($this->render('comission-total', ['sellsRepository' => $this->sellsRepository, 'agentsRepository' => $this->agentsRepository])); + } + return new Response($this->render('add-sell', ['contractsRepository' => $this->contractsRepository])); + } +} \ No newline at end of file diff --git a/controllers/errors_handling/ContractsErrorHandler.php b/controllers/errors_handling/ContractsErrorHandler.php new file mode 100644 index 0000000..0394c1f --- /dev/null +++ b/controllers/errors_handling/ContractsErrorHandler.php @@ -0,0 +1,92 @@ + $value) { + if ($value == '') { + array_push($result, ucfirst(str_replace('_', ' ', $key)) . ' can not be empty'); + } else { + $funcName = 'check_' . $key; + $result = (new ContractsErrorHandler)->$funcName($contract, $contractsRepository, $result); + } + } + + if (count($result) == 0) + return null; + return $result; + } + + private function check_number($contract, ContractsRepository $contractsRepository, $result) + { + $contracts = $contractsRepository->getContractByNumber($contract->number); + if (count($contracts) !== 0) + array_push($result, 'Contract with number #' . $contract->number . ' is already exist'); + return $result; + } + + private function check_agent_name($contract, ContractsRepository $contractsRepository, $result) + { + $contractsOfAgentForThisComplex = $contractsRepository->getContractByAgentNameAndComplexName($contract->agent_name, $contract->living_complex); + if (count($contractsOfAgentForThisComplex) !== 0) + array_push($result, 'Agent already has contract for the complex ' . $contract->living_complex); + return $result; + } + + private function check_living_complex($contract, ContractsRepository $contractsRepository, $result) + { + return $result; + } + + private function check_award_type(Contract $contract, ContractsRepository $contractsRepository, $result) + { + if ($contract->award_type !== 'fix' && $contract->award_type !== 'percent') + array_push($result, 'Award type must be \'fix\' or \'percent\''); + + return $result; + } + + private function check_award_size(Contract $contract, ContractsRepository $contractsRepository, $result) + { + $message = ''; + $is_award_correct = true; + if ($contract->award_type == 'fix') { + $as = (int)$contract->award_size; + if ($as > 1000000 or $as <= 0) { + $is_award_correct = false; + $message = 'Award size of fixed award must be between 0 and 1\'000\'000'; + } + } + + if ($contract->award_type == 'percent') { + $as = (int)$contract->award_size; + if ($as > 10 or $as <= 0) { + $is_award_correct = false; + $message = 'Award size of percent award must be between 0 and 10'; + } + } + + if (!$is_award_correct) + array_push($result, $message); + return $result; + } + + private function check_sign_date(Contract $contract, ContractsRepository $contractsRepository, $result) + { + $isDateCorrect = true; + $expirationDate = new DateTime($contract->expiration_date); + $currentDate = new DateTime("now"); + + if ($expirationDate <= $currentDate) + array_push($result, 'Expiration date must be in future'); + return $result; + } + + private function check_expiration_date(Contract $contract, ContractsRepository $contractsRepository, $result) + { + return $result; + } +} \ No newline at end of file diff --git a/controllers/errors_handling/TableErrorHandler.php b/controllers/errors_handling/TableErrorHandler.php new file mode 100644 index 0000000..1bc0cc2 --- /dev/null +++ b/controllers/errors_handling/TableErrorHandler.php @@ -0,0 +1,71 @@ + $value) { + if ($value == '') { + array_push($result, ucfirst(str_replace('_', ' ', $key)) . ' can not be empty'); + } else { + $funcName = 'check_' . $key; + $result = (new TableErrorHandler)->$funcName($sell, $sellsRepository, $result); + } + } + + if (count($result) == 0) + return null; + return $result; + } + + private function check_contract_number(Sell $sell, SellsRepository $sellsRepository, $result) + { + $sells = $sellsRepository->getByContractNumber($sell->contract_number); + if (count($sells) === 0) + array_push($result, 'Agent with contract number ' . $sell->contract_number . ' doesn\'t exists'); + return $result; + } + + private function check_name(Sell $sell, SellsRepository $sellsRepository, $result) + { + return $result; + } + + private function check_agent_id(Sell $sell, SellsRepository $sellsRepository, $result) + { + return $result; + } + + + private function check_apartment_number(Sell $sell, SellsRepository $sellsRepository, $result) + { + if (count($sellsRepository->getAllByLivingComplexAndApartmentNumber($sell->living_complex, $sell->apartment_number)) !== 0) + array_push($result, 'Contract on apartment #' . $sell->apartment_number . ' is already exists. Please, enter different apartment number'); + return $result; + } + + private function check_living_complex(Sell $sell, SellsRepository $sellsRepository, $result) + { + $sells = $sellsRepository->getByContractNumber($sell->contract_number); + $livingComplex = $sells['living_complex']; + if (count($sells) === 0 || $livingComplex != $sell->living_complex) + array_push($result, "Agent's contract doesn't include living complex '$livingComplex'"); + return $result; + } + + private function check_sum(Sell $sell, SellsRepository $sellsRepository, $result) + { + return $result; + } + + private function check_apartment_price(Sell $sell, SellsRepository $sellsRepository, $result) + { + $sum = $sell->apartment_price; + if ($sum < 500000) + array_push($result, "Sell's sum can't be less than 500'000"); + return $result; + } +} \ No newline at end of file diff --git a/core/Request.php b/core/Request.php index 83932c9..3eea3a5 100644 --- a/core/Request.php +++ b/core/Request.php @@ -95,4 +95,19 @@ public function getPath() { return $this->path; } + /** + * Return get parameter by name + * @param $name + * @return mixed|null + */ + public function getQueryParameter($name) + { + return isset($this->originalGet[$name]) ? $this->originalGet[$name] : null; + } + + public function getPostParameter($name) + { + return isset($this->originalPost[$name]) ? $this->originalPost[$name] : null; + } + } \ No newline at end of file diff --git a/entities/Contract.php b/entities/Contract.php new file mode 100644 index 0000000..ca4fef1 --- /dev/null +++ b/entities/Contract.php @@ -0,0 +1,23 @@ +number = $request->getPostParameter('number'); + $this->agent_name = $request->getPostParameter('agent_name'); + $this->living_complex = $request->getPostParameter('living_complex'); + $this->award_type = $request->getPostParameter('award_type'); + $this->award_size = $request->getPostParameter('award_size'); + $this->sign_date = $request->getPostParameter('sign_date'); + $this->expiration_date = $request->getPostParameter('expiration_date'); + } +} \ No newline at end of file diff --git a/entities/Sell.php b/entities/Sell.php new file mode 100644 index 0000000..f490533 --- /dev/null +++ b/entities/Sell.php @@ -0,0 +1,36 @@ +getPostParameter('contract_info')); + $this->name = $contract_info[1]; + $this->agent_id = $agentsRepository->getIdByAgentsName($this->name)[0]; + $this->contract_number = (int)$contract_info[0]; + $this->apartment_price = (int)$request->getPostParameter('sum'); + $this->sum = $this->getAwardFromApartmentPrice($this->contract_number, $this->apartment_price, $contractsRepository); + $this->apartment_number = $request->getPostParameter('apartment_number'); + $this->living_complex = $contract_info[2]; + } + + protected function getAwardFromApartmentPrice($contract_number, $apartment_price, $contractsRepository) + { + $contract = $contractsRepository->getContractByNumber($contract_number)[0]; + $award_type = $contract['award_type']; + if ($award_type === 'fix') { + return (int)$contract['award_size']; + } else { + return (((int)$contract['award_size']) / 100) * ((int)$apartment_price); + } + } + +} \ No newline at end of file diff --git a/index.php b/index.php index 80cbf01..b16f4e0 100644 --- a/index.php +++ b/index.php @@ -1,31 +1,56 @@ match($request->getPath()); -} catch (\InvalidArgumentException $exception) { - $route = [ - 'controller' => 'index', - 'action' => 'index' - ]; +} catch (InvalidArgumentException $exception) { + if (is_null($request->getPath())) { + $route = [ + 'controller' => 'index', + 'action' => 'index' + ]; + } else { + $route = [ + 'controller' => 'index', + 'action' => 'error' + ]; + } } -$controllerClassName = sprintf('%sController', - ucfirst($route['controller'])); +$controllers = [ + 'table' => new TableController($contractsRepository, $sellsRepository, $agentsRepository), + 'index' => new IndexController(), + 'contracts' => new ContractsController($contractsRepository, $agentsRepository) +]; +$controller = $controllers[$route['controller']]; $actionMethod = $route['action'] . 'Action'; -$controller = new $controllerClassName(); /** @var Response $response */ -$response = $controller->$actionMethod(); +$response = $controller->$actionMethod($request); $response->send(); \ No newline at end of file diff --git a/repositories/AgentsRepository.php b/repositories/AgentsRepository.php new file mode 100644 index 0000000..b8171d6 --- /dev/null +++ b/repositories/AgentsRepository.php @@ -0,0 +1,45 @@ +connection = $connection; + } + + public function getAgentNameById($id) + { + $statement = $this->connection->query("SELECT * FROM agents WHERE id = " . $id); + $statement->execute(); + return $statement->fetch()["full_name"]; + } + + public function getAllAgents(){ + $statement = $this->connection->query("SELECT * FROM agents"); + $statement->execute(); + return $statement->fetch(); + } + + public function getAllAgentsIds(){ + $statement = $this->connection->query("SELECT DISTINCT id FROM agents"); + $statement->execute(); + return $statement->fetchAll(); + } + + public function getIdByAgentsName($name){ + $statement = $this->connection->query("SELECT id FROM agents WHERE full_name = '" . $name . "' LIMIT 1;"); + if(!$statement) { + return [-1, -1]; + } + $statement->execute(); + return $statement->fetch(); + } + + public function addNewAgent($name){ + $statement = $this->connection->query('INSERT INTO agents (full_name) VALUE (\'' . $name . '\');'); +// echo 'added new mfr'; +// $statement->execute(); + } +} \ No newline at end of file diff --git a/repositories/ContractsRepository.php b/repositories/ContractsRepository.php new file mode 100644 index 0000000..b789573 --- /dev/null +++ b/repositories/ContractsRepository.php @@ -0,0 +1,42 @@ +connection = $connection; + } + + public function getAll() + { + $statement = $this->connection->query("SELECT * FROM contracts"); + return $statement->fetchAll(); + } + + public function getContractByNumber($number) + { + $statement = $this->connection->query("SELECT * FROM contracts WHERE number = " . $number . ";"); + return $statement->fetchAll(); + } + + public function getContractByAgentNameAndComplexName($agent_name, $complex_name){ + $statement = $this->connection->query("SELECT * FROM contracts WHERE agent_name = '" . $agent_name . "' AND living_complex = '" . $complex_name . "' ;"); + return $statement->fetchAll(); + } + + public function addContract(Contract $contract) + { + $query = "insert into contracts (number, agent_name, living_complex, award_type, award_size, expiration_date, sign_date) +values (%d, '%s', '%s', '%s', %d, '%s', '%s');"; + $query = sprintf($query, $contract->number, + $contract->agent_name, + $contract->living_complex, + $contract->award_type, + $contract->award_size, + $contract->expiration_date, + $contract->sign_date); + $statement = $this->connection->query($query); + } +} \ No newline at end of file diff --git a/repositories/SellsRepository.php b/repositories/SellsRepository.php new file mode 100644 index 0000000..11cf84d --- /dev/null +++ b/repositories/SellsRepository.php @@ -0,0 +1,66 @@ +connection = $connection; + $this->agentsRepository = new AgentsRepository($connection); + } + + public function getAll() + { + $statement = $this->connection->query("SELECT * FROM apartments_sells"); + return $statement->fetchAll(); + } + + public function getAllByLivingComplexAndApartmentNumber($living_complex, $apartment_number){ + $template_query = "SELECT * FROM apartments_sells WHERE living_complex = '%s' AND apartment_number = %d"; + $query = sprintf($template_query, $living_complex, $apartment_number); + $statement = $this->connection->query($query); + $statement->execute(); + return $statement->fetchAll(); + } + + public function getAllByAgentId($id) + { + $statement = $this->connection->query("SELECT * FROM apartments_sells WHERE agent_id = " . $id); + return $statement->fetchAll(); + } + + public function getByContractNumber($number){ + $statement = $this->connection->query("SELECT * FROM contracts WHERE number = " . $number); + return $statement->fetch(); + } + + public function addNewSell(Sell $sell) + { + $template_query = 'INSERT INTO apartments_sells (agent_id, sum, contract_number, apartment_number, living_complex) +VALUES (%d, %d, %d, %d, \'%s\');'; + + $query = sprintf($template_query, + $sell->agent_id, + $sell->sum, + $sell->contract_number, + $sell->apartment_number, + $sell->living_complex); + $statement = $this->connection->query($query); + + if ($sell->agent_id == 0) { + + $this->agentsRepository->addNewAgent($sell->name); + $sell->agent_id = (int)$this->agentsRepository->getIdByAgentsName($sell->name)[0]; + + $query = sprintf($template_query, + $sell->agent_id, + $sell->sum, + $sell->contract_number, + $sell->apartment_number, + $sell->living_complex); + $statement = $this->connection->query($query); + } + } +} diff --git a/sql/article.sql b/sql/article.sql new file mode 100644 index 0000000..a466c76 --- /dev/null +++ b/sql/article.sql @@ -0,0 +1,28 @@ +CREATE TABLE IF NOT EXISTS agents +( + id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, + full_name varchar(255) not null +) ENGINE = InnoDB; + +CREATE TABLE IF NOT EXISTS apartments_sells +( + agent_id INT(11) NOT NULL, + + sum INT(11) NOT NULL, + contract_number varchar(255) not null, + apartment_number INT(11) NOT NULL, + living_complex varchar(255) not null, + FOREIGN KEY (agent_id) REFERENCES agents (id), + PRIMARY KEY (apartment_number, living_complex) +) ENGINE = InnoDB; + +CREATE TABLE IF NOT EXISTS contracts +( + number varchar(255) primary key, + agent_name varchar(255), + living_complex varchar(255), + award_type varchar(255) check (award_type = 'fix' or award_type = 'percent'), + award_size DECIMAL(11), + expiration_date datetime, + sign_date datetime +) ENGINE = InnoDB; diff --git a/templates/404.php b/templates/404.php new file mode 100644 index 0000000..6116376 --- /dev/null +++ b/templates/404.php @@ -0,0 +1,23 @@ + + + + + +

404

+

We are sorry, but whis page doesn't exists

+ + diff --git a/templates/add-contract.php b/templates/add-contract.php new file mode 100644 index 0000000..6e95617 --- /dev/null +++ b/templates/add-contract.php @@ -0,0 +1,67 @@ + + + + + +

Add new contract to the DB

+
+ + +
+

Contract number

+ +
+

Agent name

+ +
+

Living complex

+ +
+

Award type

+ +
+

Award size

+ +
+

Sign date

+ +
+

Expiration date

+ +
+ +
+
+ + diff --git a/templates/add-sell.php b/templates/add-sell.php new file mode 100644 index 0000000..ab30fed --- /dev/null +++ b/templates/add-sell.php @@ -0,0 +1,62 @@ + + + + + +

Add new sell to the DB

+
+ + +
+

Price of the appartment

+ +
+ +

Contract number, Contractor, Living complex name

+ +
+

Apartment number

+ +
+ getAll()) == 0) { + echo ''; + echo '

Form is unavailable - contracts list is empty. Please, add contract to use this form

'; + } ?> + getAll()) != 0) + echo ''; ?> +
+
+ + diff --git a/templates/comission-total.php b/templates/comission-total.php new file mode 100644 index 0000000..0c63710 --- /dev/null +++ b/templates/comission-total.php @@ -0,0 +1,134 @@ + + + + + + +

See total commission payments

+getAllAgentsIds() as $id): ?> +
+

getAgentNameById($id[0]) ?>

+ + + + + + + + + + + getAllByAgentId($id[0]) as $sell): ?> + + + + + + + + + + + +
IDNameSumContract numberAppartment numberLiving complex name
getAgentNameById($sell['agent_id']) ?>
+

Total:

+
+ +
+

Grand total:

+ + + + + + + + + + + + + + + +getAgentNameById($sell['agent_id'])?> + + + + + + + + + + + \ No newline at end of file diff --git a/templates/contracts.php b/templates/contracts.php new file mode 100644 index 0000000..497da25 --- /dev/null +++ b/templates/contracts.php @@ -0,0 +1,61 @@ + + + + + + +

All contracts

+
+ + + + + + + + + + getAll() as $contract): ?> + + + + + + + + + + +
Contract numberAgent nameLiving complexAward typeAward sizeSign dateExpiration date
+
+ + \ No newline at end of file diff --git a/templates/welcome.php b/templates/welcome.php new file mode 100644 index 0000000..6e51aa1 --- /dev/null +++ b/templates/welcome.php @@ -0,0 +1,70 @@ + + + + + + +

Welcome!

+ + + + \ No newline at end of file