vendor/roothirsch/shop-bundle/Entity/PositionTemplate.php line 23

Open in your IDE?
  1. <?php
  2. namespace Roothirsch\ShopBundle\Entity;
  3. use App\Entity\Company;
  4. use Roothirsch\CoreBundle\Entity\Traits\TimetrackedTrait;
  5. use Roothirsch\CoreBundle\UserAware\UserAwareInterface;
  6. use Roothirsch\CoreBundle\UserAware\UserAwareTrait;
  7. use Roothirsch\ShopBundle\Repository\EstimatePositionRepository;
  8. use Doctrine\Common\Collections\ArrayCollection;
  9. use Doctrine\Common\Collections\Collection;
  10. use Doctrine\ORM\Mapping as ORM;
  11. use \Roothirsch\ShopBundle\Entity\PositionTemplateAttribute;
  12. use ApiPlatform\Core\Annotation\ApiResource;
  13. use Roothirsch\PimBundle\Entity\Product;
  14. /**
  15. * @ORM\Entity
  16. * @ORM\Table(name="shop_position_template")
  17. * @ApiResource(
  18. * shortName="Shop/PositionTemplate"
  19. * )
  20. */
  21. class PositionTemplate implements UserAwareInterface
  22. {
  23. use UserAwareTrait;
  24. use TimetrackedTrait;
  25. /**
  26. * @ORM\Id
  27. * @ORM\GeneratedValue
  28. * @ORM\Column(type="integer")
  29. */
  30. private $id;
  31. /**
  32. * @ORM\Column(type="string", length=255)
  33. */
  34. private $state = 'draft';
  35. /**
  36. * @ORM\ManyToOne(targetEntity=Product::class)
  37. * @ORM\JoinColumn(nullable=true, onDelete="SET NULL")
  38. */
  39. private $type;
  40. /**
  41. * @ORM\Column(type="string", length=255)
  42. */
  43. private $title;
  44. /**
  45. * @ORM\Column(type="string", length=255, nullable=true)
  46. */
  47. private $label;
  48. /**
  49. * @ORM\Column(type="float")
  50. */
  51. private $unitPrice;
  52. /**
  53. * @ORM\Column(type="integer")
  54. */
  55. private $amount;
  56. /**
  57. * @ORM\Column(type="boolean")
  58. */
  59. private $optional;
  60. /**
  61. * @ORM\OneToMany(targetEntity=PositionTemplateAttribute::class, mappedBy="position", orphanRemoval=true, cascade={"persist", "remove"})
  62. * @ORM\OrderBy({"name" = "ASC"})
  63. */
  64. private $attributes;
  65. /**
  66. * @ORM\Column(type="json")
  67. */
  68. private $articles = [];
  69. /**
  70. * @ORM\Column(type="json")
  71. */
  72. private $priceAdjustments = [];
  73. /**
  74. * @ORM\Column(type="json")
  75. */
  76. private $additionalDiscounts = [];
  77. /**
  78. * @ORM\Column(type="json")
  79. */
  80. private $surcharges = [];
  81. public function __construct()
  82. {
  83. $this->attributes = new ArrayCollection();
  84. }
  85. public function __clone() {
  86. $this->id = null;
  87. $this->setCreatedAt(new \DateTime());
  88. $this->setUpdatedAt(new \DateTime());
  89. $oldAttributes = $this->attributes;
  90. $this->attributes = new ArrayCollection();
  91. foreach($oldAttributes as $oldAttribute) {
  92. $newAttribute = clone $oldAttribute;
  93. $this->attributes->add($newAttribute);
  94. $newAttribute->setPosition($this);
  95. }
  96. if ($this->articles === null) {
  97. $this->articles = [];
  98. }
  99. }
  100. public function getId(): ?int
  101. {
  102. return $this->id;
  103. }
  104. public function getTitle(): ?string
  105. {
  106. return $this->title;
  107. }
  108. public function setTitle(string $title): self
  109. {
  110. $this->title = $title;
  111. return $this;
  112. }
  113. public function getUnitPrice(): ?float
  114. {
  115. return $this->unitPrice;
  116. }
  117. public function setUnitPrice(float $unitPrice): self
  118. {
  119. $this->unitPrice = $unitPrice;
  120. return $this;
  121. }
  122. public function getAmount(): ?int
  123. {
  124. return $this->amount;
  125. }
  126. public function setAmount(int $amount): self
  127. {
  128. $this->amount = $amount;
  129. return $this;
  130. }
  131. /**
  132. * @return string
  133. */
  134. public function getState(): string
  135. {
  136. return $this->state;
  137. }
  138. /**
  139. * @param string $state
  140. */
  141. public function setState(string $state): void
  142. {
  143. $this->state = $state;
  144. }
  145. /**
  146. * @return Collection|PositionTemplateAttribute[]
  147. */
  148. public function getAttributes(): Collection
  149. {
  150. return $this->attributes;
  151. }
  152. /**
  153. * @param ArrayCollection $attributes
  154. */
  155. public function setAttributes($attributes): void
  156. {
  157. foreach ($this->attributes as $attribute) {
  158. if (!isset($attributes[$attribute->getName()])) {
  159. $this->attributes->removeElement($attribute);
  160. }
  161. }
  162. /** @var PositionTemplateAttribute $attribute */
  163. foreach ($attributes as $attributeName => $attribute) {
  164. $existingAttribute = $this->getAttribute($attributeName);
  165. if ($existingAttribute instanceof PositionTemplateAttribute) {
  166. $existingAttribute->setValue($attribute->getValue());
  167. $existingAttribute->setTitle($attribute->getTitle());
  168. $existingAttribute->setName($attribute->getName());
  169. $existingAttribute->setAmount($attribute->getAmount());
  170. $existingAttribute->setAmountFormat($attribute->getAmountFormat());
  171. $existingAttribute->setArticle($attribute->getArticle());
  172. } else {
  173. $attribute->setPosition($this);
  174. $this->attributes->add($attribute);
  175. }
  176. }
  177. }
  178. public function getAttribute($name)
  179. {
  180. foreach ($this->attributes as $attribute) {
  181. if ($attribute->getName() == $name) {
  182. return $attribute;
  183. }
  184. }
  185. return null;
  186. }
  187. public function __get($name) {
  188. if ($this->hasAttribute($name)) {
  189. return $this->getAttribute($name)->getValue();
  190. }
  191. }
  192. public function hasAttribute($name)
  193. {
  194. return $this->getAttribute($name) !== null;
  195. }
  196. public function __has($name) {
  197. return $this->hasAttribute($name);
  198. }
  199. public function getEstimate(): ?Estimate
  200. {
  201. return $this->estimate;
  202. }
  203. public function setEstimate(?Estimate $estimate): self
  204. {
  205. $this->estimate = $estimate;
  206. return $this;
  207. }
  208. /**
  209. * @return mixed
  210. */
  211. public function getOptional()
  212. {
  213. return $this->optional;
  214. }
  215. /**
  216. * @param mixed $optional
  217. */
  218. public function setOptional($optional): void
  219. {
  220. $this->optional = $optional;
  221. }
  222. /**
  223. * @return array
  224. */
  225. public function getArticles(): array
  226. {
  227. return (array) $this->articles;
  228. }
  229. /**
  230. * @return array
  231. */
  232. public function getArticleNames(): array
  233. {
  234. $names = [];
  235. if (is_iterable($this->articles)) {
  236. foreach ($this->articles as $article) {
  237. $names[] = $article['name'];
  238. }
  239. }
  240. return $names;
  241. }
  242. /**
  243. * @param array $articles
  244. */
  245. public function setArticles(array $articles): void
  246. {
  247. $this->articles = $articles;
  248. }
  249. public function getTotal()
  250. {
  251. $total = 0;
  252. foreach($this->getArticles() as $article) {
  253. $total+= $article['total'];
  254. }
  255. return intval($this->amount * $total);
  256. }
  257. public function getTotalAfterPriceAdjustments() {
  258. $total = $this->getTotal();
  259. foreach($this->getPriceAdjustments() as $priceAdjustment) {
  260. $total += $priceAdjustment['total'] * $this->getAmount();
  261. }
  262. return $total;
  263. }
  264. public function getTotalAfterDiscounts() {
  265. $total = $this->getTotalAfterPriceAdjustments();
  266. foreach($this->getDiscounts() as $discount) {
  267. $total += $discount['total'];
  268. }
  269. return $total;
  270. }
  271. public function getTotalWithTax() {
  272. return $this->getTotalAfterDiscounts();
  273. }
  274. /**
  275. * Get the value of type
  276. */
  277. public function getType()
  278. {
  279. return $this->type;
  280. }
  281. /**
  282. * Set the value of type
  283. *
  284. * @return self
  285. */
  286. public function setType($type)
  287. {
  288. $this->type = $type;
  289. return $this;
  290. }
  291. public function getArticlesSortedBySection()
  292. {
  293. $groups = [];
  294. $articles = $this->getArticles();
  295. usort($articles, function($l, $r){
  296. $key = 'sorting';
  297. $leftPriority = (array_key_exists($key, $l) ? $l[$key] : 0);
  298. $rightPriority = (array_key_exists($key, $r) ? $r[$key] : 0);
  299. return ($leftPriority < $rightPriority) ? 1 : -1;
  300. });
  301. foreach ($articles as $index => $article)
  302. {
  303. $hasGroupName = array_key_exists('group', $article);
  304. $groupName = $hasGroupName ? $article['group'] : '__none__';
  305. if(!array_key_exists($groupName, $groups)){
  306. $groups[$groupName] = [
  307. "label" => $hasGroupName ? $article['group'] : '',
  308. "subtotal" => 0,
  309. "total" => 0,
  310. "articles" => []
  311. ];
  312. }
  313. $groups[$groupName]['subtotal'] += $article['total'];
  314. $groups[$groupName]['total'] = $groups[$groupName]['subtotal'];
  315. $groups[$groupName]['priceAdjustments'] = [];
  316. foreach($this->getPriceAdjustments() as $priceAdjustment) {
  317. if ($groupName == $priceAdjustment['group']) {
  318. $groups[$groupName]['priceAdjustments'][] = $priceAdjustment;
  319. }
  320. }
  321. array_push($groups[$groupName]['articles'], $article);
  322. }
  323. return array_values($groups);
  324. }
  325. public function getArticleAttributes(){
  326. if($this->articleAttributes) {
  327. return $this->articleAttributes;
  328. }
  329. $attributes = [];
  330. foreach ($this->getArticles() as $article) {
  331. if(!array_key_exists("attributes", $article)){
  332. continue;
  333. }
  334. $articleAttributes = $article['attributes'];
  335. foreach ($articleAttributes as $attribute => $value){
  336. if(!$value){
  337. continue;
  338. }
  339. if(!array_key_exists($article['type'], $attributes)) {
  340. $attributes[$article['type']] = [];
  341. }
  342. $attributes[$article['type']][$attribute] = $value;
  343. }
  344. }
  345. $this->articleAttributes = $attributes;
  346. return $this->articleAttributes;
  347. }
  348. /**
  349. * @return array
  350. */
  351. public function getPriceAdjustments(): array
  352. {
  353. if (is_array($this->priceAdjustments)) {
  354. $articleGroups = $this->getArticlesGrouped();
  355. foreach($this->priceAdjustments as $index => $priceAdjustment) {
  356. $total = 0;
  357. if ($this->priceAdjustments[$index]['group'] == 'Panneau de porte') {
  358. $this->priceAdjustments[$index]['group'] = 'Türblatt';
  359. }
  360. if (isset($articleGroups[$priceAdjustment['group']])) {
  361. foreach($articleGroups[$priceAdjustment['group']] as $article) {
  362. $total+= $article['total'];
  363. }
  364. }
  365. switch($priceAdjustment['type']) {
  366. case 'percentage':
  367. $this->priceAdjustments[$index]['total'] = intval($total / 100 * $priceAdjustment['value']);
  368. default:
  369. break;
  370. }
  371. }
  372. }
  373. return is_array($this->priceAdjustments) ? $this->priceAdjustments : [];
  374. }
  375. /**
  376. * @return array
  377. */
  378. public function getDiscounts(): array
  379. {
  380. $discounts = [];
  381. $totalAfterDiscounts = $this->getTotalAfterPriceAdjustments();
  382. return $discounts;
  383. }
  384. /**
  385. * @param array $priceAdjustments
  386. */
  387. public function setPriceAdjustments(array $priceAdjustments): void
  388. {
  389. $this->priceAdjustments = $priceAdjustments;
  390. }
  391. public function getArticlesGrouped() {
  392. $articleGroups = [];
  393. foreach($this->getArticles() as $article) {
  394. if (!isset($article['group']) || empty($article['group'])) {
  395. $article['group'] = 'Türblatt';
  396. }
  397. if (!isset($articleGroups[$article['group']])) {
  398. $articleGroups[$article['group']] = [];
  399. }
  400. $articleGroups[$article['group']][] = $article;
  401. }
  402. return $articleGroups;
  403. }
  404. /**
  405. * @return array
  406. */
  407. public function getSurcharges(): array
  408. {
  409. return is_array($this->surcharges) ? $this->surcharges : [];
  410. }
  411. /**
  412. * @param array $surcharges
  413. */
  414. public function setSurcharges(array $surcharges): void
  415. {
  416. $this->surcharges = $surcharges;
  417. }
  418. /**
  419. * @return mixed
  420. */
  421. public function getLabel()
  422. {
  423. return $this->label;
  424. }
  425. /**
  426. * @param mixed $label
  427. */
  428. public function setLabel($label): void
  429. {
  430. $this->label = $label;
  431. }
  432. public function addAttribute(PositionTemplateAttribute $attribute): self
  433. {
  434. if (!$this->getAttributes()->contains($attribute)) {
  435. $this->getAttributes()->add($attribute);
  436. $attribute->setPosition($this);
  437. }
  438. return $this;
  439. }
  440. public function removeAttribute(PositionTemplateAttribute $attribute): self
  441. {
  442. if ($this->getAttributes()->removeElement($attribute)) {
  443. // set the owning side to null (unless already changed)
  444. if ($attribute->getPosition() === $this) {
  445. $attribute->setPosition(null);
  446. }
  447. }
  448. return $this;
  449. }
  450. /**
  451. * @return array
  452. */
  453. public function getAdditionalDiscounts(): array
  454. {
  455. if (!is_array($this->additionalDiscounts)) {
  456. return [];
  457. }
  458. return $this->additionalDiscounts;
  459. }
  460. /**
  461. * @param array $additionalDiscounts
  462. */
  463. public function setAdditionalDiscounts(array $additionalDiscounts): void
  464. {
  465. $this->additionalDiscounts = $additionalDiscounts;
  466. }
  467. }