<?php
class Report{
private $col1 = 30;
private $col2 = 15;
private function padLeft($string, $length)
{
$countSpace = $length - strlen($string); //количество добавляемых в ячейку пробелов }
private function padRight($string, $length)
{
$countSpace = $length - strlen($string); //количество добавляемых в ячейку пробелов }
public function writeTable(Company $company){// Заголовок таблицы
echo $this->padRight("Departmen", $this->col1) .
$this->padLeft("employe", $this->col2) .
$this->padLeft("money", $this->col2) .
$this->padLeft("coffee", $this->col2) .
$this->padLeft("lists", $this->col2) .
$this->padLeft("money/lists", $this->col2) . "\n\n";
$dataCompany = $company->getData();
// Сама таблица
foreach ($dataCompany as $dataDepartment) {
echo $this->padRight($dataDepartment[0], $this->col1) .
$this->padLeft($dataDepartment[1], $this->col2) .
$this->padLeft($dataDepartment[2], $this->col2) .
$this->padLeft($dataDepartment[3], $this->col2) .
$this->padLeft($dataDepartment[4], $this->col2) .
$this->padLeft($dataDepartment[5], $this->col2) . "\n";
}
}
}
class Company
{
protected $departments = array();//массив депортаментов protected $professions = array();//массив профессий
public function pushDepartmen(Department $department){
$this->departments[] = $department;
}
public function pushProfession(Profession $profession)
{
$this->professions[] = $profession;
}
public function getProfessionList(){
$professionList = array(); foreach ($this->professions as $value) {
$professionList[] = $value;
}
return $professionList;
}
public function getData(){
foreach ($this->departments as $department) {
$departamentData = array(); $departamentData[] = $department->getName();
$departamentData[] = $department->getEmployeCount();
$departamentData[] = $department->getSalary();
$departamentData[] = $department->getCoffeeCount();
$departamentData[] = $department->getListCount();
$departamentData[] = $department->getMoneyPerList();
$companyData[] = $departamentData;
}
return $companyData;
}
}
class Department
{
private $name;
private $company;
private $employees = array();//массив из работников этого департамента private $boss; //указывает на босса депортамента он один из работников (class Employe)
//согласно массиву-шаблону создаём работников департаменты и про
public function __construct
(string
$name, array $d, Company
$company) {
$this->name = $name;
$this->company = $company;
foreach ($d as $listEmploye){
//если в массиве написано "b" значит назначит боссом
if ($listEmploye[0] == 'b'){
$this->boss = $this->createEmloye($listEmploye[1], $listEmploye[2], $this);
//если написано число значит создаст группу работников
}else {
for ($i=0; $i < $listEmploye[0]; $i++) {
$this->employees[] = $this->createEmloye($listEmploye[1], $listEmploye[2], $this);
}
}
}
}
//приходит заявка на создаваемую профессию. Строчка и цифра например - ('en', 2), то функция делает engineera ранга 2
public function createEmloye(string $professionName, int $rangEmploye, Department $department){
$professionList = $this->company->getProfessionList();
foreach ($professionList as $profession) {
//создает работника необходимой профессии.
if ($profession->getName() == $professionName) {
$employe = new Employe($rangEmploye, $profession, $department);
}
}
return $employe;
}
public function getBoss(){
return $this->boss;
}
public function getEmployes(){
return $this->employees;
}
public function getName(){
return $this->name;
}
public function getEmployeCount(){
return count($this->employees); }
public function getSalary(){
$salary = 0;
foreach ($this->employees as $employe) {
$salary = $salary + $employe->getSalary();
}
return $salary;
}
public function getCoffeeCount(){
$coffee = 0;
foreach ($this->employees as $employe) {
$coffee = $coffee + $employe->getCoffee();
}
return $coffee;
}
public function getListCount(){
$listCount = 0;
foreach ($this->employees as $employe) {
$listCount = $listCount + $employe->getListCount();
}
return $listCount;
}
public function getMoneyPerList(){
return round( ($this->getSalary() / $this->getListCount()), 1 ); }
}
class Employe{
private $profession;
private $employeLevel;
private $department; //указывает на принадлежность департаменту (class Department)
public function __construct(int $employeLevel, Profession $profession, Department $department)
{
$this->employeLevel = $employeLevel;
$this->profession = $profession;
$this->department = $department;
}
//определяет является ли сотрудник боссом
public function isBoss(){
$boss = $this->department->getBoss();
if ($this === $boss) {
return true;
} else {
return false;
}
}
public function setDepartament(Department $department){
$this->departament = $department;
}
//расчёт зарплаты сотрудника
public function getSalary()
{
$rateMoneyProfession = $this->profession->getMoneyRate(); //узнаём коэфициент зарплаты для его професси
$rateLevel = $this->employeLevel*0.25 + 0.75; //узнаём коэфициент зарплаты для его ранга
if ($this->isBoss()){ //является ли сотрудник боссом департамента
$bossRate = 1.5; //и устанавливаем соответствующую ставку
} else {
$bossRate = 1;
}
return $rateMoneyProfession*$rateLevel*$bossRate;
}
//расчёт потребления кофе сотрудником
public function getCoffee()
{
$cofeeRate = $this->profession->getCoffeeRate(); //узнаём коэфициент потребления кофе для его професси
if ($this->isBoss()){ //является ли сотрудник боссом департамента
$bossRate = 2; //и устанавливаем соответствующее поглощение кофе для босса
} else {
$bossRate = 1;
}
return $cofeeRate * $bossRate;
}
public function getListCount(){
$listRate = $this->profession->getListRate();
if ($this->isBoss()){ //является ли сотрудник боссом департамента
$bossRate = 0; //босс не занимается бумагами
} else {
$bossRate = 1; //если простой работник то придётся заниматся чертежами отчётами и т.п.
}
return $bossRate * $listRate;
}
}
abstract class Profession{
private $name;
private $moneyRate;
private $coffeeRate;
abstract protected function getListRate();
abstract function getName();
abstract function getCoffeeRate();
abstract function getMoneyRate();
}
Class Manager Extends Profession{
private $name = 'MN';
private $reportListCount = 200; //Манагер делает 200 листов отчёта
private $moneyRate = 500;
private $coffeeRate = 20;
public function getListRate()
{
return $this->reportListCount;
}
public function getName()
{
return $this->name;
}
public function getCoffeeRate()
{
return $this->coffeeRate;
}
public function getMoneyRate()
{
return $this->moneyRate;
}
}
Class Marketer Extends Profession{
private $name = 'MR';
private $reportListCount = 150; //Маркетёр делает 150 листов отчёта
private $moneyRate = 400;
private $coffeeRate = 15;
public function getListRate()
{
return $this->reportListCount;
}
public function getName()
{
return $this->name;
}
public function getCoffeeRate()
{
return $this->coffeeRate;
}
public function getMoneyRate()
{
return $this->moneyRate;
}
}
Class Engineer Extends Profession{
private $name = 'EN';
private $projectListCount = 50; //Инжинер делает 50 листов чертежей и проектов
private $moneyRate = 200;
private $coffeeRate = 5;
public function getListRate()
{
return $this->projectListCount;
}
public function getName()
{
return $this->name;
}
public function getCoffeeRate()
{
return $this->coffeeRate;
}
public function getMoneyRate()
{
return $this->moneyRate;
}
}
Class Analyst Extends Profession{
private $name = 'AN';
private $researchListCount = 5; //Аналист делает 5 листов исследований
private $moneyRate = 800;
private $coffeeRate = 50;
public function getListRate()
{
return $this->researchListCount;
}
public function getName()
{
return $this->name;
}
public function getCoffeeRate()
{
return $this->coffeeRate;
}
public function getMoneyRate()
{
return $this->moneyRate;
}
}
// создаётсяя компания
$company = new Company;
//создаются список профессий востребованных в этой компании b
$manager = new Manager(); // 'MN'
$marketer = new Marketer(); // 'MR'
$engineer = new Engineer(); // 'EN'
$analyst = new Analyst(); // 'AN'
//все профессии заталкиваются в эту саму компанию
$company->pushProfession($manager);
$company->pushProfession($marketer);
$company->pushProfession($engineer);
$company->pushProfession($analyst);
/*массивы для формирования сотрудников отдело и т.п.
первая цифра в ячейке массива - колличество сотрудников. буква b означает босса
(mn-Manager mr-Marketer en-Engineer an-Analyst) - ранг сотрудника
цифра в третьей ячеке - ранг сортудников
*/
$name='Department of Procurement';
$d=[[ 9, 'MN', 1], [3, 'MN', 2], [2, 'MN', 3], [2, 'MR', 1], ['b', 'MN', 2]];
$department = new Department($name, $d, $company);
$company->pushDepartmen($department);
$name='Department of Sales';
$d=[[12, 'MR', 1], [6, 'MR', 2], [3, 'AN', 2], [2, 'AN', 2], ['b', 'MR', 2]];
$department = new Department($name, $d, $company);
$company->pushDepartmen($department);
$name='Department of Advertising';
$d=[[15, 'MR', 1], [10, 'MR', 2], [8, 'MN', 1], [2, 'EN', 1], ['b', 'MR', 3]];
$department = new Department($name, $d, $company);
$company->pushDepartmen($department);
$name='Department of Logistics';
$d=[[13, 'MN', 1], [5, 'MN', 2], [5, 'EN', 1], ['b', 'MN', 1]];
$department = new Department($name, $d, $company);
$company->pushDepartmen($department);
$report= new Report;
$report->writeTable($company);