src/Entity/Gauge/GaugePurpose.php line 20

Open in your IDE?
  1. <?php
  2. namespace App\Entity\Gauge;
  3. use App\Entity\Extension\GaugeUnitInterface;
  4. use App\Entity\Extension\ItemsWithHistoryTrait;
  5. use App\Utils\GaugeType;
  6. use App\Utils\Period;
  7. use App\Utils\Segment;
  8. use App\Utils\Units;
  9. use Doctrine\Common\Collections\ArrayCollection;
  10. use Doctrine\Common\Collections\Collection;
  11. use Doctrine\ORM\Mapping as ORM;
  12. use Symfony\Component\Validator\Constraints as Assert;
  13. /**
  14. * @ORM\Entity()
  15. * @ORM\Table(name="gauge_purpose")
  16. */
  17. class GaugePurpose
  18. {
  19. public const PURPOSE_CONSUMPTION = 1; // spotřeba
  20. public const PURPOSE_PRODUCTION = 2; // výroba
  21. public const PURPOSE_DELIVERY = 3; // dodávka (přetoky)
  22. public const PURPOSE_RAINFALL = 4; // srážky
  23. public const PURPOSE_TEMPERATURE = 5; // teplota
  24. public const PURPOSE_HUMIDITY = 6; // vlhkost
  25. public const PURPOSE_CO2 = 7; // koncentrace CO2
  26. public static array $all = [
  27. self::PURPOSE_CONSUMPTION,
  28. self::PURPOSE_PRODUCTION,
  29. self::PURPOSE_DELIVERY,
  30. self::PURPOSE_TEMPERATURE,
  31. self::PURPOSE_HUMIDITY,
  32. self::PURPOSE_CO2,
  33. ];
  34. /**
  35. * @var int|null
  36. * @ORM\Id()
  37. * @ORM\GeneratedValue()
  38. * @ORM\Column(type="integer")
  39. */
  40. private ?int $id = null;
  41. /**
  42. * @var Gauge $gauge
  43. * @ORM\ManyToOne(targetEntity="App\Entity\Gauge\Gauge", inversedBy="purposes")
  44. * @ORM\JoinColumn(name="gauge_id", referencedColumnName="id", nullable=false)
  45. */
  46. private Gauge $gauge;
  47. /**
  48. * values defined above GaugePurpose::PURPOSE_...
  49. * @var int
  50. * @ORM\Column(type="smallint")
  51. */
  52. private int $purpose;
  53. /**
  54. * TODO can be deleted after sql/EM-442.sql on production
  55. * @var int|null
  56. * @ORM\Column(type="smallint", nullable=true)
  57. */
  58. private ?int $primaryMode = GaugeType::MODE_MANUAL;
  59. /**
  60. * TODO can be deleted after sql/EM-442.sql on production
  61. * @var int|null
  62. * @ORM\Column(type="smallint", nullable=true)
  63. */
  64. private ?int $secondaryMode = GaugeType::MODE_NONE;
  65. /**
  66. * @var Collection|GaugeVolumeRatio[]
  67. * @ORM\OneToMany(targetEntity="App\Entity\Gauge\GaugeVolumeRatio", mappedBy="gaugePurpose", cascade={"all"})
  68. */
  69. private $volumeRatio;
  70. /**
  71. * @var Collection|GaugeRemoteVolumeRatio[]
  72. * @ORM\OneToMany(targetEntity="App\Entity\Gauge\GaugeRemoteVolumeRatio", mappedBy="gaugePurpose", cascade={"all"})
  73. */
  74. private $remoteVolumeRatio;
  75. /**
  76. * @var Collection|GaugeConsumptionUsage[]
  77. * @ORM\OneToMany(targetEntity="App\Entity\Gauge\GaugeConsumptionUsage", mappedBy="gaugePurpose", cascade={"all"})
  78. */
  79. private $consumptionUsage;
  80. /**
  81. * @var int|null
  82. * @ORM\Column(type="smallint", nullable=true)
  83. */
  84. private ?int $readingsPeriod = Period::MONTH;
  85. /**
  86. * @var bool
  87. * @ORM\Column(type="boolean")
  88. */
  89. private bool $readingsPeriodControl = true;
  90. /**
  91. * values are defined in App\Utils\Period
  92. * @var int|null
  93. * @ORM\Column(type="smallint", nullable=true)
  94. */
  95. private ?int $secondaryReadingsPeriod = null;
  96. /**
  97. * @var bool
  98. * @ORM\Column(type="boolean")
  99. */
  100. private bool $secondaryReadingsPeriodControl = true;
  101. /**
  102. * values are defined in App\Utils\Period
  103. * @var int|null
  104. * @ORM\Column(type="smallint", nullable=true)
  105. */
  106. private ?int $remoteReadingsPeriod = null;
  107. /**
  108. * @var int|null
  109. * @ORM\Column(type="integer", nullable=true)
  110. */
  111. private ?int $remoteReadingsMinuteFrequency = null;
  112. /**
  113. * @var Collection|GaugeUnit[]
  114. * @ORM\OneToMany(targetEntity="App\Entity\Gauge\GaugeUnit", mappedBy="gaugePurpose", cascade={"all"})
  115. */
  116. private $units;
  117. /**
  118. * @var Collection|GaugeRemoteUnit[]
  119. * @ORM\OneToMany(targetEntity="App\Entity\Gauge\GaugeRemoteUnit", mappedBy="gaugePurpose", cascade={"all"})
  120. */
  121. private $remoteUnits;
  122. use ItemsWithHistoryTrait;
  123. public function __construct()
  124. {
  125. $this->consumptionUsage = new ArrayCollection();
  126. $this->volumeRatio = new ArrayCollection();
  127. $this->remoteVolumeRatio = new ArrayCollection();
  128. $this->units = new ArrayCollection();
  129. $this->remoteUnits = new ArrayCollection();
  130. }
  131. /**
  132. * @return int|null
  133. */
  134. public function getId(): ?int
  135. {
  136. return $this->id;
  137. }
  138. /**
  139. * @param int|null $id
  140. * @return GaugePurpose
  141. */
  142. public function setId(?int $id): GaugePurpose
  143. {
  144. $this->id = $id;
  145. return $this;
  146. }
  147. /**
  148. * @return Gauge
  149. */
  150. public function getGauge(): Gauge
  151. {
  152. return $this->gauge;
  153. }
  154. /**
  155. * @param Gauge $gauge
  156. * @return GaugePurpose
  157. */
  158. public function setGauge(Gauge $gauge): GaugePurpose
  159. {
  160. $this->gauge = $gauge;
  161. return $this;
  162. }
  163. /**
  164. * @return GaugeVolumeRatio[]|Collection
  165. */
  166. public function getVolumeRatio()
  167. {
  168. return $this->volumeRatio;
  169. }
  170. /**
  171. * @param GaugeVolumeRatio[]|Collection $volumeRatio
  172. * @return GaugePurpose
  173. */
  174. public function setVolumeRatio($volumeRatio)
  175. {
  176. $this->volumeRatio = $volumeRatio;
  177. return $this;
  178. }
  179. /**
  180. * @return GaugeRemoteVolumeRatio[]|Collection
  181. */
  182. public function getRemoteVolumeRatio()
  183. {
  184. return $this->remoteVolumeRatio;
  185. }
  186. /**
  187. * @param GaugeRemoteVolumeRatio[]|Collection $remoteVolumeRatio
  188. * @return GaugePurpose
  189. */
  190. public function setRemoteVolumeRatio($remoteVolumeRatio)
  191. {
  192. $this->remoteVolumeRatio = $remoteVolumeRatio;
  193. return $this;
  194. }
  195. /**
  196. * @return GaugeConsumptionUsage[]|Collection
  197. */
  198. public function getConsumptionUsage()
  199. {
  200. return $this->consumptionUsage;
  201. }
  202. /**
  203. * @param GaugeConsumptionUsage[]|Collection $consumptionUsage
  204. * @return GaugePurpose
  205. */
  206. public function setConsumptionUsage($consumptionUsage)
  207. {
  208. $this->consumptionUsage = $consumptionUsage;
  209. return $this;
  210. }
  211. /**
  212. * @param float $volumeRatio
  213. * @return $this
  214. */
  215. public function addVolumeRatio(float $volumeRatio): self
  216. {
  217. $volumeRatioObj = (new GaugeVolumeRatio())
  218. ->setRatio($volumeRatio)
  219. ->setValidFrom(new \DateTime());
  220. $volumeRatioObj->setGaugePurpose($this);
  221. $this->volumeRatio->add($volumeRatioObj);
  222. return $this;
  223. }
  224. /**
  225. * @param GaugeConsumptionUsage $consumptionUsage
  226. * @return self
  227. */
  228. public function addConsumptionUsage(GaugeConsumptionUsage $consumptionUsage): self
  229. {
  230. $consumptionUsage->setGaugePurpose($this);
  231. $this->consumptionUsage->add($consumptionUsage);
  232. return $this;
  233. }
  234. /**
  235. * @param float $volumeRatio
  236. * @return $this
  237. */
  238. public function addRemoteVolumeRatio(float $volumeRatio): self
  239. {
  240. $remoteVolumeRatioObj = (new GaugeRemoteVolumeRatio())
  241. ->setRatio($volumeRatio)
  242. ->setValidFrom(new \DateTime());
  243. $remoteVolumeRatioObj->setGaugePurpose($this);
  244. $this->remoteVolumeRatio->add($remoteVolumeRatioObj);
  245. return $this;
  246. }
  247. /**
  248. * @return int
  249. */
  250. public function getPurpose(): int
  251. {
  252. return $this->purpose;
  253. }
  254. /**
  255. * @param int $purpose
  256. * @return GaugePurpose
  257. */
  258. public function setPurpose(int $purpose): GaugePurpose
  259. {
  260. $this->purpose = $purpose;
  261. return $this;
  262. }
  263. /**
  264. * @return int|null
  265. */
  266. public function getReadingsPeriod(): ?int
  267. {
  268. return $this->readingsPeriod;
  269. }
  270. /**
  271. * @param int|null $readingsPeriod
  272. * @return GaugePurpose
  273. */
  274. public function setReadingsPeriod(?int $readingsPeriod): GaugePurpose
  275. {
  276. $this->readingsPeriod = $readingsPeriod;
  277. return $this;
  278. }
  279. /**
  280. * @return bool
  281. */
  282. public function isReadingsPeriodControl(): bool
  283. {
  284. return $this->readingsPeriodControl;
  285. }
  286. /**
  287. * @param bool $readingsPeriodControl
  288. * @return GaugePurpose
  289. */
  290. public function setReadingsPeriodControl(bool $readingsPeriodControl): GaugePurpose
  291. {
  292. $this->readingsPeriodControl = $readingsPeriodControl;
  293. return $this;
  294. }
  295. /**
  296. * @return int|null
  297. */
  298. public function getSecondaryReadingsPeriod(): ?int
  299. {
  300. return $this->secondaryReadingsPeriod;
  301. }
  302. /**
  303. * @param int|null $secondaryReadingsPeriod
  304. * @return GaugePurpose
  305. */
  306. public function setSecondaryReadingsPeriod(?int $secondaryReadingsPeriod): GaugePurpose
  307. {
  308. $this->secondaryReadingsPeriod = $secondaryReadingsPeriod;
  309. return $this;
  310. }
  311. /**
  312. * @return bool
  313. */
  314. public function isSecondaryReadingsPeriodControl(): bool
  315. {
  316. return $this->secondaryReadingsPeriodControl;
  317. }
  318. /**
  319. * @param bool $secondaryReadingsPeriodControl
  320. * @return GaugePurpose
  321. */
  322. public function setSecondaryReadingsPeriodControl(bool $secondaryReadingsPeriodControl): GaugePurpose
  323. {
  324. $this->secondaryReadingsPeriodControl = $secondaryReadingsPeriodControl;
  325. return $this;
  326. }
  327. /**
  328. * TODO možná přidat jako argument datetime aby bylo možno se ptát i historicky na počet segmentů např podle sazby elektroměru
  329. * @return array
  330. */
  331. public function getSegments(): array
  332. {
  333. $gauge = $this->getGauge();
  334. if ($gauge->getLevel() !== GaugeType::LEVEL_MAIN && $gauge->getParent() !== null) {
  335. foreach ($gauge->getParent()->getPurposes() as $parentPurpose) {
  336. if ($parentPurpose->getPurpose() === $this->getPurpose()) {
  337. return $parentPurpose->getSegments();
  338. }
  339. }
  340. // EM-959: when purposes don't match (FVE case: CONSUMPTION sub-gauge under
  341. // PRODUCTION parent), fall through to own segment logic below instead of
  342. // returning []. The original commit 24553f76 commented out the entire block,
  343. // which broke ~130 ordinary CONSUMPTION → CONSUMPTION sub-gauges.
  344. }
  345. if ($gauge->getType() === GaugeType::TYPE_ELECTRICITY_METER && $this->getPurpose() === self::PURPOSE_CONSUMPTION) {
  346. $segments = [];
  347. if ($gauge->isElectricityWholesale()) {
  348. $segments[Segment::SEGMENT_HIGH_TARIFF] = Segment::SEGMENT_HIGH_TARIFF;
  349. if ($gauge->isForceLowTariff()) {
  350. $segments[Segment::SEGMENT_LOW_TARIFF] = Segment::SEGMENT_LOW_TARIFF;
  351. }
  352. if ($gauge->isForceSpecialTariff()) {
  353. $segments[Segment::SEGMENT_SPECIAL_TARIFF] = Segment::SEGMENT_SPECIAL_TARIFF;
  354. }
  355. return $segments;
  356. }
  357. $currentRate = $this->getCurrent('rate', null, $gauge->getRates());
  358. if ($currentRate instanceof GaugeRate) {
  359. $rate = $currentRate->getRate();
  360. if ($rate->isHighTariff() === true) {
  361. $segments[Segment::SEGMENT_HIGH_TARIFF] = Segment::SEGMENT_HIGH_TARIFF;
  362. }
  363. if ($rate->isLowTariff() === true) {
  364. $segments[Segment::SEGMENT_LOW_TARIFF] = Segment::SEGMENT_LOW_TARIFF;
  365. }
  366. } else {
  367. $segments[Segment::SEGMENT_HIGH_TARIFF] = Segment::SEGMENT_HIGH_TARIFF;
  368. }
  369. return $segments;
  370. }
  371. if ($this->getPurpose() === self::PURPOSE_PRODUCTION) {
  372. return [Segment::SEGMENT_PRODUCTION => Segment::SEGMENT_PRODUCTION];
  373. }
  374. if ($this->getPurpose() === self::PURPOSE_DELIVERY) {
  375. return [Segment::SEGMENT_ENERGY_DELIVERY => Segment::SEGMENT_ENERGY_DELIVERY];
  376. }
  377. return Segment::getSegmentsByPurpose($this->getPurpose());
  378. }
  379. /**
  380. * @param bool $primary
  381. * @return GaugeVolumeRatio|GaugeRemoteVolumeRatio|null
  382. */
  383. public function getCurrentVolumeRatio(bool $primary)
  384. {
  385. if ($primary) {
  386. if ($this->gauge->getPrimaryMode() === GaugeType::MODE_MANUAL) {
  387. // primary is manual return volumeRatio
  388. return $this->getCurrent('volumeRatio', null, $this->getVolumeRatio());
  389. }
  390. // primary is remote return remoteVolumeRatio
  391. return $this->getCurrent('remoteVolumeRatio', null, $this->getRemoteVolumeRatio());
  392. }
  393. // secondary is manual return volumeRatio
  394. if ($this->gauge->getSecondaryMode() === GaugeType::MODE_MANUAL) {
  395. return $this->getCurrent('volumeRatio', null, $this->getVolumeRatio());
  396. }
  397. // secondary is remote return remoteVolumeRatio
  398. return $this->getCurrent('remoteVolumeRatio', null, $this->getRemoteVolumeRatio());
  399. }
  400. /**
  401. * @return GaugeUnit[]|Collection
  402. */
  403. public function getUnits()
  404. {
  405. return $this->units;
  406. }
  407. /**
  408. * @return GaugeRemoteUnit[]|Collection
  409. */
  410. public function getRemoteUnits()
  411. {
  412. return $this->remoteUnits;
  413. }
  414. /**
  415. * @param \DateTime|null $date
  416. * @return int
  417. */
  418. public function getCurrentUnit(?\DateTime $date = null): int
  419. {
  420. $gUnit = $this->getCurrent('units', $date, $this->units);
  421. if ($gUnit instanceof GaugeUnitInterface) {
  422. return $gUnit->getUnit();
  423. }
  424. // return default unit by gauge type
  425. return Units::getDefaultUnitByGaugeType($this->gauge->getType());
  426. }
  427. /**
  428. * @param \DateTime|null $date
  429. * @return int
  430. */
  431. public function getCurrentRemoteUnit(?\DateTime $date = null): int
  432. {
  433. $gUnit = $this->getCurrent('remoteUnits', $date, $this->remoteUnits);
  434. if ($gUnit instanceof GaugeUnitInterface) {
  435. return $gUnit->getUnit();
  436. }
  437. // return default unit by gauge type
  438. return Units::getDefaultUnitByGaugeType($this->gauge->getType());
  439. }
  440. /**
  441. * @param int $remoteUnit
  442. * @return $this
  443. */
  444. public function newRemoteUnit(int $remoteUnit):self
  445. {
  446. $gru = (new GaugeRemoteUnit())->setUnit($remoteUnit)->setValidFrom(new \DateTime());
  447. $gru->setGaugePurpose($this);
  448. $this->remoteUnits->add($gru);
  449. return $this;
  450. }
  451. /**
  452. * @param int $unit
  453. * @return $this
  454. */
  455. public function newUnit(int $unit):self
  456. {
  457. $gru = (new GaugeUnit())->setUnit($unit)->setValidFrom(new \DateTime());
  458. $gru->setGaugePurpose($this);
  459. $this->units->add($gru);
  460. return $this;
  461. }
  462. public function getRemoteReadingsPeriod(): ?int
  463. {
  464. return $this->remoteReadingsPeriod;
  465. }
  466. public function setRemoteReadingsPeriod(?int $remoteReadingsPeriod): GaugePurpose
  467. {
  468. $this->remoteReadingsPeriod = $remoteReadingsPeriod;
  469. return $this;
  470. }
  471. public function getRemoteReadingsMinuteFrequency(): ?int
  472. {
  473. return $this->remoteReadingsMinuteFrequency;
  474. }
  475. public function setRemoteReadingsMinuteFrequency(?int $remoteReadingsMinuteFrequency): GaugePurpose
  476. {
  477. $this->remoteReadingsMinuteFrequency = $remoteReadingsMinuteFrequency;
  478. return $this;
  479. }
  480. }