fork download
  1. <?php
  2.  
  3.  
  4. define("MANAGER", "manager");
  5. define("MARKETER", "marketer");
  6. define("ENGINEER", "engineer");
  7. define("ANALYST", "analyst");
  8.  
  9. class CollectionException extends Exception {}
  10. class DepartmentException extends Exception {}
  11.  
  12. //Класс сотрудник
  13. class Employee
  14. {
  15. protected $profession;
  16. protected $rate;
  17. protected $litresOfCoffee;
  18. protected $pgsOfDocs;
  19. protected $rank;
  20. protected $boss;
  21.  
  22. final public function __construct(string $profession, int $rate, int $litresOfCoffee, int $pgsOfDocs, int $rank, bool $boss = false){
  23. $this->profession = $profession;
  24. $this->rate = $rate;
  25. $this->litresOfCoffee = $litresOfCoffee;
  26. $this->pgsOfDocs = $pgsOfDocs;
  27. $this->rank = $rank;
  28. $this->boss = $boss;
  29. }
  30.  
  31. final public function getProfession():string {
  32. return $this->profession;
  33. }
  34.  
  35. final public function getRate():int {
  36. return $this->rate;
  37. }
  38.  
  39. public function getRateWithRank():float {
  40. switch ($this->rank) {
  41. case 1:
  42. $rateWithRank = $this->rate;
  43. break;
  44. case 2:
  45. $rateWithRank = $this->rate * 1.25;
  46. break;
  47. case 3:
  48. $rateWithRank = $this->rate * 1.50;
  49. break;
  50. }
  51. if ($this->boss)
  52. $rateWithRank *= 1.50;
  53. return $rateWithRank;
  54. }
  55.  
  56. public function getCoffee():int {
  57. if ($this->boss) {
  58. return $this->litresOfCoffee * 2;
  59. } else {
  60. return $this->litresOfCoffee;
  61. }
  62. }
  63.  
  64. public function getPages():int {
  65. if ($this->boss) {
  66. return 0;
  67. } else {
  68. return $this->pgsOfDocs;
  69. }
  70. }
  71.  
  72. final public function getRank():int {
  73. return $this->rank;
  74. }
  75.  
  76. final public function isBoss():bool {
  77. return $this->boss;
  78. }
  79.  
  80. final public function setProfession(string $profession){
  81. $this->profession = $profession;
  82. }
  83.  
  84. final public function setRate(int $rate){
  85. $this->rate = $rate;
  86. }
  87.  
  88. final public function setCoffee(int $litresOfCoffee){
  89. $this->litresOfCoffee = $litresOfCoffee;
  90. }
  91.  
  92. final public function setPages(int $pages){
  93. $this->pgsOfDocs = $pages;
  94. }
  95.  
  96. final public function setRank(int $rank):bool {
  97. if($rank > 0 and $rank < 4){
  98. $this->rank = $rank;
  99. return true;
  100. } else {
  101. return false;
  102. }
  103. }
  104.  
  105. final public function setBossStatus(bool $bossStatus){
  106. $this->boss = $bossStatus;
  107. }
  108. }
  109. //Класс коллекция сотрудников - сортирует, отбирает, исключает, берет процент, берет число сотрудников, извлекает копии класса сотрудников. Возвращает объект коллекцию.
  110. class Collection
  111. {
  112. private $employees;
  113. private $method;
  114. private $sortFlag;
  115.  
  116. const ASC = 1;//сортировка по возрастанию
  117. const DESC = 2;//сортировка по убыванию
  118. const ALL = 3;//все копии
  119. const RATE = 4;
  120. const COFFEE = 5;
  121. const PAGES = 6;
  122. const RANK = 7;
  123. const SALARY = 8;
  124. const PROFESSION = 9;
  125. const BOSS = 10;
  126.  
  127. public function __construct(Employee ...$employees){
  128. $this->employees = $employees;
  129. }
  130. //Сортировка по параметрам
  131. public function sort(int $sortProperty, int $sortFlag = self::ASC):Collection {
  132. if ($sortFlag == self::ASC or $sortFlag == self::DESC) {
  133. $this->sortFlag = $sortFlag;
  134. } else {
  135. throw new CollectionException("Флаг сортировки должен принимать значения: Collection::ASC, Collection::DESC\n");
  136. }
  137.  
  138. if ($this->setMethod($sortProperty) and ($sortProperty < self::PROFESSION)) {
  139. return usort($this->employees, array($this, "sortByProperty")) ? $this :
  140. call_user_func(function(){
  141. throw new CollectionException("Сортировка не произошла!\n");
  142. })
  143. ;
  144. } else {
  145. throw new CollectionException("Сортировка возможна по параметрам: Collection::RATE, Collection::COFFEE, Collection::PAGES, Collection::RANK, Collection::SALARY\n");
  146. }
  147. }
  148. //Выбор по параметрам
  149. public function select(int $property, $value) {
  150. if ($this->setMethod($property)) {
  151. $selectedEmployees = [];
  152. foreach ($this->employees as $employee) {
  153. $method = $this->method;
  154. if($employee->$method() === $value)
  155. $selectedEmployees[] = $employee;
  156. }
  157. if (empty($selectedEmployees)) {
  158. throw new CollectionException("Элементы не найдены!\n");
  159. } else {
  160. $this->employees = $selectedEmployees;
  161. return $this;
  162. }
  163. } else {
  164. throw new CollectionException("Выбор возможен по параметрам: Collection::RATE, Collection::COFFEE, Collection::PAGES, Collection::RANK, Collection::SALARY, Collection::PROFESSION, Collection::BOSS");
  165. }
  166. }
  167. //Исключение по параметрам
  168. public function exclude(int $property, $value):Collection {
  169. if ($this->setMethod($property)) {
  170. $neededEmployees = [];
  171. $method = $this->method;
  172. foreach ($this->employees as $employee) {
  173. if($employee->$method() != $value)
  174. $neededEmployees[] = $employee;
  175. }
  176. if (empty($neededEmployees)) {
  177. throw new CollectionException("Исключены все элементы!\n");
  178. } else {
  179. $this->employees = $neededEmployees;
  180. return $this;
  181. }
  182. } else {
  183. throw new CollectionException("Исключение возможно по параметрам: Collection::RATE, Collection::COFFEE, Collection::PAGES, Collection::RANK, Collection::SALARY, Collection::PROFESSION, Collection::BOSS");
  184. }
  185. }
  186. //Взять процент от числа сотрудников
  187. public function takePercent(int $percent):Collection {
  188. if ($percent > 0) {
  189. $neededEmployees = [];
  190. $percent = $percent / 100;
  191. $numOfEmpl = count($this->employees);
  192. $neededNumOfEmpl = round($numOfEmpl * $percent);
  193. if ($neededNumOfEmpl == 0) {
  194. throw new CoolectionException("Взять данный процент от числа сотрудников не возможно!\n");
  195. }
  196. for($i = 0; $i < $neededNumOfEmpl; $i++){
  197. $neededEmployees[] = $this->employees[$i];
  198. }
  199. $this->employees = $neededEmployees;
  200. return $this;
  201. } else {
  202. return false;
  203. }
  204. }
  205. //Извлечь из коллекции копии объектов класса Сотрудник
  206. public function extractEmployees(int $number = self::ALL) {
  207. $clonedEmployees = [];
  208. $numOfEmpls = count($this->employees);
  209. if ($number == self::ALL) {
  210. foreach ($this->employees as $employee) {
  211. $clonedEmployees[] = clone $employee;
  212. }
  213. return $clonedEmployees;
  214. } else {
  215. if ($number > $numOfEmpls) {
  216. throw new CollectionException("{$number} сотрудников не может быть извлечено, в коллекции {$numOfEmpls} сотрудников!\n");
  217. } elseif($number == 1) {
  218. return $this->extractEmployee();
  219. } else {
  220. for($i = 0; $i < $numOfEmpls; $i++){
  221. $clonedEmployees[] = clone $this->employees[$i];
  222. }
  223. return $clonedEmployees;
  224. }
  225. }
  226. }
  227. //Извлечь одну копию объекта класса Сотрудник
  228. public function extractEmployee():Employee {
  229. return clone $this->employees[0];
  230. }
  231. //Получить коллекцию из $num элементов
  232. public function takeNumItems(int $num):Collection {
  233. $numOfItems = count($this->employees);
  234. if ($num > $numOfItems) {
  235. throw new CollectionException("Коллекция из {$num} элементов не может быть создана, в коллекции {$numOfItems} элементов!\n");
  236. } elseif($num == 1) {
  237. return $this->takeOneItem();
  238. } else {
  239. $collectionOfNumItems = [];
  240. for($i = 0; $i < $num; $i++){
  241. $collectionOfNumItems[] = $this->employees[$i];
  242. }
  243. $this->employees = $collectionOfNumItems;
  244. return $this;
  245. }
  246. }
  247. //Получить коллекцию из одного элемента
  248. public function takeOneItem():Collection {
  249. $oneItemCollection[] = $this->employees[0];
  250. $this->employees = $oneItemCollection;
  251. return $this;
  252. }
  253. //Выбор гет-метода свойства по которому происходит сортировка, выборка и т.п.
  254. private function setMethod(int $property):bool {
  255. switch($property){
  256. case self::RATE:
  257. $this->method = "getRate";
  258. return true;
  259. case self::COFFEE:
  260. $this->method = "getCoffee";
  261. return true;
  262. case self::PAGES:
  263. $this->method = "getPages";
  264. return true;
  265. case self::RANK:
  266. $this->method = "getRank";
  267. return true;
  268. case self::SALARY:
  269. $this->method = "getRateWithRank";
  270. return true;
  271. case self::PROFESSION:
  272. $this->method = "getProfession";
  273. return true;
  274. case self::BOSS:
  275. $this->method = "isBoss";
  276. return true;
  277. default:
  278. return false;
  279. }
  280. }
  281. //Универсальная ф-я сортировки
  282. private function sortByProperty(Employee $employee1, Employee $employee2):int {
  283. $method = $this->method;
  284. if ($this->sortFlag == self::ASC) {
  285. return ($employee1->$method() <=> $employee2->$method());
  286. } else {
  287. return -($employee1->$method() <=> $employee2->$method());
  288. }
  289.  
  290. }
  291.  
  292. }
  293.  
  294. class Department
  295. {
  296. const UPRANK = "up";//повысить ранг
  297. const DOWNRANK = "down";//понизить ранг
  298.  
  299. private $name;
  300. private $employees = [];
  301.  
  302. public function __construct(string $name){
  303. $this->name = $name;
  304. }
  305. //Создать сотрудника
  306. public function createEmployee(int $number, string $employeeClassName, string $profession, int $rate, int $litresOfCoffee, int $pgsOfDocs, int $rank, bool $boss = false){
  307. if (class_exists($employeeClassName) and is_a($employeeClassName, "Employee", true)){
  308. for ($i = 0; $i < $number; $i++) {
  309. $this->employees[] = new $employeeClassName($profession, $rate, $litresOfCoffee, $pgsOfDocs, $rank, $boss);
  310. }
  311. } else {
  312. throw new DepartmentException("Ошибка создания сотрудника!\n");
  313.  
  314. }
  315. }
  316. //Получить коллекцию
  317. public function getCollection(){
  318. if (empty($this->employees)) {
  319. throw new DepartmentException("В департаменте нет сотрудников! Коллекция не может быть создана!\n");
  320. }
  321. return new Collection(...$this->employees);
  322. }
  323. //Удалить сотрудника, принимает на вход коллекцию, удаляет сотрудников идентичных сотрудникам из коллекции(сравнение полей)
  324. public function fireEmployees(Collection $collection){
  325. $samples = $collection->extractEmployees();
  326. foreach ($samples as $sample) {
  327. foreach ($this->employees as $key => $realEmployee) {
  328. if ($realEmployee == $sample) {
  329. unset($this->employees[$key]);
  330. break;
  331. }
  332. }
  333. }
  334. $this->employees = array_values($this->employees);
  335. }
  336. //Добавить сотрудников из коллекции
  337. public function addEmployees(Collection $collection){
  338. foreach ($collection->extractEmployees() as $employee) {
  339. $this->employees[] = $employee;
  340. }
  341. }
  342. //Изменить сотрудников, работает аналогично ф-ии удаления
  343. public function changeEmployees(Collection $collection, int $property, $value){
  344. switch($property){
  345. case Collection::RATE:
  346. $method = "setRate";
  347. break;
  348. case Collection::COFFEE:
  349. $method = "setCoffee";
  350. break;
  351. case Collection::PAGES:
  352. $method = "setPages";
  353. break;
  354. case Collection::RANK:
  355. $method = "setRank";
  356. break;
  357. case Collection::PROFESSION:
  358. $method = "setProfession";
  359. break;
  360. case Collection::BOSS:
  361. $method = "setBossStatus";
  362. break;
  363. default:
  364. throw new DepartmentException("Свойство для изменения должно быть следующим: Collection::RATE, Collection::COFFEE, Collection::PAGES, Collection::RANK, Collection::PROFESSION, Collection::BOSS\n");
  365. }
  366. $samples = $collection->extractEmployees();
  367. if ($method == "setRank") {
  368. foreach ($samples as $sample) {
  369. foreach ($this->employees as $realEmployee) {
  370. if ($realEmployee == $sample) {
  371. if ($value == self::UPRANK) {
  372. $rank = $realEmployee->getRank();
  373. $value = (++$rank > 3) ? --$rank : $rank;
  374. }
  375. if ($value == self::DOWNRANK){
  376. $rank = $realEmployee->getRank();
  377. $value = (--$rank == 0) ? ++$rank : $rank;
  378. }
  379. if($realEmployee->$method($value)){
  380. break;
  381. } else {
  382. throw new DepartmentException("Значения ранга должно быть от 1 до 3!\n");
  383. }
  384. }
  385. }
  386. }
  387. } else {
  388. foreach ($samples as $sample) {
  389. foreach ($this->employees as $realEmployee) {
  390. if ($realEmployee == $sample) {
  391. $realEmployee->$method($value);
  392. break;
  393. }
  394. }
  395. }
  396. }
  397. }
  398.  
  399. public function getName():string {
  400. return $this->name;
  401. }
  402.  
  403. public function getNumOfEmployees():int {
  404. return count($this->employees);
  405. }
  406.  
  407. public function getSalaryOfEmployees():float {
  408. $salary = 0;
  409. foreach ($this->employees as $employee) {
  410. $salary += $employee->getRateWithRank();
  411. }
  412. return $salary;
  413. }
  414.  
  415. public function getCoffee():int {
  416. $coffee = 0;
  417. foreach ($this->employees as $employee) {
  418. $coffee += $employee->getCoffee();
  419. }
  420. return $coffee;
  421. }
  422.  
  423. public function getPages():int {
  424. $pages = 0;
  425. foreach ($this->employees as $employee) {
  426. $pages += $employee->getPages();
  427. }
  428. return $pages;
  429. }
  430.  
  431. public function getTugricsPerPage():float {
  432. if ($this->getPages() == 0) {
  433. return 0;
  434. } else {
  435. return round($this->getSalaryOfEmployees() / $this->getPages(), 1);
  436. }
  437. }
  438.  
  439. }
  440.  
  441. class Company
  442. {
  443. private $name;
  444. private $departments;
  445. private $backupDepartments = [];//клоны департаментов - для восстановления
  446.  
  447. public function __construct(string $name, Department ...$departments){
  448. $this->departments = $departments;
  449. }
  450.  
  451. public function getName():string {
  452. return $this->name;
  453. }
  454.  
  455. public function getDepartments():array {
  456. return $this->departments;
  457. }
  458. //клонирует департаменты(вместе с сотрудниками)
  459. private function cloneDepartments(array $baseDepartments):array {
  460. $copiedDepartments = [];
  461. foreach ($baseDepartments as $department) {
  462. $collection = $department->getCollection();
  463. $backupDepartment = new Department($department->getName());
  464. $backupDepartment->addEmployees($collection);
  465. $copiedDepartments[] = $backupDepartment;
  466. }
  467. return $copiedDepartments;
  468. }
  469. //клонирует исходный массив департаментов
  470. public function backup(){
  471. $this->backupDepartments = $this->cloneDepartments($this->departments);
  472. }
  473. //восстанавливает исходный массив
  474. public function restore(){
  475. $this->departments = $this->cloneDepartments($this->backupDepartments);
  476. }
  477. }
  478.  
  479. function padRight($string, $widthOfCol){
  480. $lengthOfString = mb_strlen($string);
  481. if ($lengthOfString < $widthOfCol) {
  482. $formattedString = $string . str_repeat(" ", $widthOfCol - $lengthOfString);
  483. return $formattedString;
  484. } else {
  485. return false;
  486. }
  487. }
  488.  
  489. function padLeft($string, $widthOfCol){
  490. $lengthOfString = mb_strlen($string);
  491. if ($lengthOfString < $widthOfCol) {
  492. $formattedString = str_repeat(" ", $widthOfCol - $lengthOfString) . $string;
  493. return $formattedString;
  494. } else {
  495. return false;
  496. }
  497. }
  498.  
  499. function displayReport(Company $company){
  500.  
  501. $col1 = 15;
  502. $col2 = 10;
  503. $col3 = 10;
  504. $col4 = 10;
  505. $col5 = 10;
  506. $col6 = 12;
  507.  
  508. echo padRight("Департамент", $col1) .
  509. padLeft("Сотр.", $col2) .
  510. padLeft("Тугр.", $col3) .
  511. padLeft("Кофе", $col4) .
  512. padLeft("Стр.", $col5) .
  513. padLeft("Тугр./стр.", $col6) . "\n\n";
  514.  
  515. $allEmployees = 0;
  516. $allSalary = 0;
  517. $allCoffee = 0;
  518. $allPages = 0;
  519. $allTugPerPgs = 0;
  520.  
  521. foreach ($company->getDepartments() as $department) {
  522.  
  523. echo padRight($department->getName(), $col1) .
  524. padLeft($department->getNumOfEmployees(), $col2) .
  525. padLeft($department->getSalaryOfEmployees(), $col3) .
  526. padLeft($department->getCoffee(), $col4) .
  527. padLeft($department->getPages(), $col5) .
  528. padLeft($department->getTugricsPerPage(), $col6) . "\n";
  529.  
  530. $allEmployees += $department->getNumOfEmployees();
  531. $allSalary += $department->getSalaryOfEmployees();
  532. $allCoffee += $department->getCoffee();
  533. $allPages += $department->getPages();
  534. $allTugPerPgs += $department->getTugricsPerPage();
  535. }
  536.  
  537. $numOfDepartments = count($company->getDepartments());
  538.  
  539. echo padRight("Среднее", $col1) .
  540. padLeft(round(($allEmployees / $numOfDepartments),1), $col2) .
  541. padLeft(round(($allSalary / $numOfDepartments), 1), $col3) .
  542. padLeft(round(($allCoffee / $numOfDepartments), 1), $col4) .
  543. padLeft(round(($allPages / $numOfDepartments), 1), $col5) .
  544. padLeft(round(($allTugPerPgs / $numOfDepartments), 1), $col6) . "\n";
  545.  
  546. echo padRight("Всего", $col1) .
  547. padLeft($allEmployees, $col2) .
  548. padLeft($allSalary, $col3) .
  549. padLeft($allCoffee, $col4) .
  550. padLeft($allPages, $col5) .
  551. padLeft($allTugPerPgs, $col6) . "\n\n";
  552. }
  553.  
  554. //департаменты
  555. $procurementDep = new Department("Закупок");
  556. $salesDep = new Department("Продаж");
  557. $advDep = new Department("Рекламы");
  558. $logstcDep = new Department("Логистики");
  559.  
  560. //добавим сотруников в департаменты
  561.  
  562. $procurementDep->createEmployee(9, "Employee", MANAGER, 500, 20, 200, 1);
  563. $procurementDep->createEmployee(3, "Employee", MANAGER, 500, 20, 200, 2);
  564. $procurementDep->createEmployee(2, "Employee", MANAGER, 500, 20, 200, 3);
  565. $procurementDep->createEmployee(2, "Employee", MARKETER, 400, 15, 150, 1);
  566. $procurementDep->createEmployee(1, "Employee", MANAGER, 500, 20, 200, 2, true);
  567.  
  568. $salesDep->createEmployee(12, "Employee", MANAGER, 500, 20, 200, 1);
  569. $salesDep->createEmployee(6, "Employee", MARKETER, 400, 15, 150, 1);
  570. $salesDep->createEmployee(3, "Employee", ANALYST, 800, 50, 5, 1);
  571. $salesDep->createEmployee(2, "Employee", ANALYST, 800, 50, 5, 2);
  572. $salesDep->createEmployee(1, "Employee", MARKETER, 400, 15, 150, 2, true);
  573.  
  574. $advDep->createEmployee(15, "Employee", MARKETER, 400, 15, 150, 1);
  575. $advDep->createEmployee(10, "Employee", MARKETER, 400, 15, 150, 2);
  576. $advDep->createEmployee(8, "Employee", MANAGER, 500, 20, 200, 1);
  577. $advDep->createEmployee(2, "Employee", ENGINEER, 200, 5, 50, 1);
  578. $advDep->createEmployee(1, "Employee", MARKETER, 400, 15, 150, 3, true);
  579.  
  580. $logstcDep->createEmployee(13, "Employee", MANAGER, 500, 20, 200, 1);
  581. $logstcDep->createEmployee(5, "Employee", MANAGER, 500, 20, 200, 2);
  582. $logstcDep->createEmployee(5, "Employee", ENGINEER, 200, 5, 50, 1);
  583. $logstcDep->createEmployee(1, "Employee", MANAGER, 500, 20, 200, 1, true);
  584.  
  585. $company = new Company("Вектор", $procurementDep, $salesDep, $advDep, $logstcDep);
  586. $company->backup();
  587.  
  588. //Начальные данные
  589. echo "Начальные данные:\n";
  590. displayReport($company);
  591. //План 1
  592. foreach($company->getDepartments() as $department){
  593. try {
  594. $firedLowRankEngineers = $department->getCollection()->select(Collection::PROFESSION, ENGINEER)->sort(Collection::RANK)->exclude(Collection::BOSS, true)->takePercent(40);
  595. $department->fireEmployees($firedLowRankEngineers);
  596. } catch(CollectionException $e){
  597. //echo "В департаменте " . $department->getName() . " " . $e->getMessage();
  598. continue;
  599. } catch(DepartmentException $e){
  600. echo $e->getMessage();
  601. exit();
  602. }
  603. }
  604. echo "План 1:\n";
  605. displayReport($company);
  606. $company->restore();
  607. //План 2
  608. foreach ($company->getDepartments() as $department) {
  609. try {
  610. $analysts = $department->getCollection()->select(Collection::PROFESSION, ANALYST);
  611. $department->changeEmployees($analysts, Collection::RATE, 1100);
  612. $department->changeEmployees($analysts, Collection::COFFEE, 75);
  613. $oldBoss = $department->getCollection()->select(Collection::BOSS, true);
  614. if ($oldBoss->extractEmployee()->getProfession() != ANALYST) {
  615. $department->changeEmployees($oldBoss, Collection::BOSS, false);
  616. $highRankAnalyst = $department->getCollection()->select(Collection::PROFESSION, ANALYST)->sort(Collection::RANK, Collection::DESC)->takeOneItem();
  617. $department->changeEmployees($highRankAnalyst, Collection::BOSS, true);
  618. }
  619. } catch(CollectionException $e){
  620. //echo $e->getMessage();
  621. continue;
  622. } catch(DepartmentException $e){
  623. echo $e->getMessage();
  624. exit();
  625. }
  626. }
  627. echo "План 2:\n";
  628. displayReport($company);
  629. $company->restore();
  630. //План 3
  631. foreach ($company->getDepartments() as $department) {
  632. try {
  633. $oneTwoRankManagers = $department->getCollection()->select(Collection::PROFESSION, MANAGER)->exclude(Collection::RANK, 3)->takePercent(50);
  634. $department->changeEmployees($oneTwoRankManagers, Collection::RANK, Department::UPRANK);
  635. } catch(CollectionException $e){
  636. //echo $e->getMessage();
  637. continue;
  638. } catch(DepartmentException $e){
  639. echo $e->getMessage();
  640. exit();
  641. }
  642. }
  643. echo "План 3:\n";
  644. displayReport($company);
  645. $company->restore();
Success #stdin #stdout 0.02s 24912KB
stdin
Standard input is empty
stdout
Начальные данные:
Департамент         Сотр.     Тугр.      Кофе      Стр.  Тугр./стр.

Закупок                17    9612.5       350      3100         3.1
Продаж                 24     13550       610      3325         4.1
Рекламы                36     16300       575      5450           3
Логистики              24     11375       425      3850           3
Среднее              25.3   12709.4       490    3931.3         3.3
Всего                 101   50837.5      1960     15725        13.2

План 1:
Департамент         Сотр.     Тугр.      Кофе      Стр.  Тугр./стр.

Закупок                17    9612.5       350      3100         3.1
Продаж                 24     13550       610      3325         4.1
Рекламы                35     16100       570      5400           3
Логистики              22     10975       415      3750         2.9
Среднее              24.5   12559.4     486.3    3893.8         3.3
Всего                  98   50237.5      1945     15575        13.1

План 2:
Департамент         Сотр.     Тугр.      Кофе      Стр.  Тугр./стр.

Закупок                17    9612.5       350      3100         3.1
Продаж                 24   15637.5       795      3470         4.5
Рекламы                36     16300       575      5450           3
Логистики              24     11375       425      3850           3
Среднее              25.3   13231.3     536.3    3967.5         3.4
Всего                 101     52925      2145     15870        13.6

План 3:
Департамент         Сотр.     Тугр.      Кофе      Стр.  Тугр./стр.

Закупок                17   10487.5       350      3100         3.4
Продаж                 24     14300       610      3325         4.3
Рекламы                36     16800       575      5450         3.1
Логистики              24     12625       425      3850         3.3
Среднее              25.3   13553.1       490    3931.3         3.5
Всего                 101   54212.5      1960     15725        14.1