条令-与相关实体的验证



我与条令有以下关联:

Charge:
id
amount
adjustmentItems
Adjustment
id
date
adjustmentItems
AdjustmentItem
id
adjustment
charge
amount

有收费,也有调整。每次调整由调整项目组成,这些项目是对一项或多项费用的调整。

当添加新的调整时,我是通过反序列化添加调整和相关项目。Ie:

$adjustment = 
["date" => "2020-12-14", 
"items" => [
["charge" => 84, "amount" => 600],
["charge" => 85, "amount" => 200],
]
];

一切都很好,除了我在AdjustmentItem::charge上使用Assert/Valid验证费用。

在费用验证中,我进行检查以确保所有调整的总和不超过费用金额。

但是,Charge::getAdjustmentItems((不会显示刚刚创建的adjustmentItems。

$adjustment->getAdjustmentItems()->first()->getCharge()->getAdjustmentItems()->toArray()

是:

[]

我如何才能将费用设置为";参见";反序列化后的项是否保留以进行验证?

来源:

<?php
namespace AppEntityTestFin;
use AppRepositoryTestFinChargeRepository;
use DoctrineCommonCollectionsArrayCollection;
use DoctrineCommonCollectionsCollection;
use DoctrineORMMapping as ORM;
use SymfonyComponentValidatorConstraints as Assert;
use SymfonyComponentValidatorContextExecutionContextInterface;
/**
* @ORMEntity(repositoryClass=ChargeRepository::class)
* @ORMTable(name="`test_financials_charge`")
*/
class Charge
{
/**
* @ORMId()
* @ORMGeneratedValue()
* @ORMColumn(type="integer")
*/
private $id;
/**
* @ORMColumn(type="integer")
*/
private $amount;
/**
* @ORMOneToMany(targetEntity=AdjustmentItem::class, mappedBy="charge")
*/
private $adjustmentItems;
public function __construct()
{
$this->adjustmentItems = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getAmount(): ?int
{
return $this->amount;
}
public function setAmount(int $amount): self
{
$this->amount = $amount;
return $this;
}
/**
* @return Collection|AdjustmentItem[]
*/
public function getAdjustmentItems(): Collection
{
return $this->adjustmentItems;
}
public function addAdjustmentItem(AdjustmentItem $adjustmentItem): self
{
if (!$this->adjustmentItems->contains($adjustmentItem)) {
$this->adjustmentItems[] = $adjustmentItem;
$adjustmentItem->setCharge($this);
}
return $this;
}
public function removeAdjustmentItem(AdjustmentItem $adjustmentItem): self
{
if ($this->adjustmentItems->contains($adjustmentItem)) {
$this->adjustmentItems->removeElement($adjustmentItem);
// set the owning side to null (unless already changed)
if ($adjustmentItem->getCharge() === $this) {
$adjustmentItem->setCharge(null);
}
}
return $this;
}

/**
* @AssertCallback
*/
public function validateBalance(ExecutionContextInterface $context, $payload)
{
dd(count($this->adjustmentItems->toArray()));
if (1) {
$context->buildViolation('Charge balance (after adjustments) must be greater or equal to $0.')
->atPath('invoice')
->addViolation();
}
}
}
<?php
namespace AppEntityTestFin;
use AppRepositoryTestFinAdjustmentRepository;
use DoctrineCommonCollectionsArrayCollection;
use DoctrineCommonCollectionsCollection;
use DoctrineORMMapping as ORM;
use SymfonyComponentValidatorConstraints as Assert;
/**
* @ORMEntity(repositoryClass=AdjustmentRepository::class)
* @ORMTable(name="`test_financials_adjustment`")
*/
class Adjustment
{
/**
* @ORMId()
* @ORMGeneratedValue()
* @ORMColumn(type="integer")
*/
private $id;
/**
* @ORMColumn(type="string", length=255, nullable=true)
*/
private $note;
/**
* @ORMOneToMany(targetEntity=AdjustmentItem::class, mappedBy="adjustment", orphanRemoval=true)
* @AssertValid
*/
private $adjustmentItems;
public function __construct()
{
$this->adjustmentItems = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getNote(): ?string
{
return $this->note;
}
public function setNote(?string $note): self
{
$this->note = $note;
return $this;
}
/**
* @return Collection|AdjustmentItem[]
*/
public function getAdjustmentItems(): Collection
{
return $this->adjustmentItems;
}
public function addAdjustmentItem(AdjustmentItem $adjustmentItem): self
{
if (!$this->adjustmentItems->contains($adjustmentItem)) {
$this->adjustmentItems[] = $adjustmentItem;
$adjustmentItem->setAdjustment($this);
}
return $this;
}
public function removeAdjustmentItem(AdjustmentItem $adjustmentItem): self
{
if ($this->adjustmentItems->contains($adjustmentItem)) {
$this->adjustmentItems->removeElement($adjustmentItem);
// set the owning side to null (unless already changed)
if ($adjustmentItem->getAdjustment() === $this) {
$adjustmentItem->setAdjustment(null);
}
}
return $this;
}
}
<?php
namespace AppEntityTestFin;
use AppRepositoryTestFinAdjustmentItemRepository;
use DoctrineORMMapping as ORM;
use SymfonyComponentValidatorConstraints as Assert;
/**
* @ORMEntity(repositoryClass=AdjustmentItemRepository::class)
* @ORMTable(name="`test_financials_adjustment_item`")
*/
class AdjustmentItem
{
/**
* @ORMId()
* @ORMGeneratedValue()
* @ORMColumn(type="integer")
*/
private $id;
/**
* @ORMManyToOne(targetEntity=Adjustment::class, inversedBy="adjustmentItems")
* @ORMJoinColumn(nullable=false)
*/
private $adjustment;
/**
* @ORMManyToOne(targetEntity=Charge::class, inversedBy="adjustmentItems")
* @ORMJoinColumn(nullable=false)
* @AssertValid
*/
private $charge;
public function getId(): ?int
{
return $this->id;
}
public function getAdjustment(): ?Adjustment
{
return $this->adjustment;
}
public function setAdjustment(?Adjustment $adjustment): self
{
$this->adjustment = $adjustment;
return $this;
}
public function getCharge(): ?Charge
{
return $this->charge;
}
public function setCharge(?Charge $charge): self
{
$this->charge = $charge;
return $this;
}
}
$json = json_encode([
"note" => "bla",
"adjustmentItems" => [
["charge" => 1],
],
]);
$credit = $this->_deserializeJson($json, Adjustment::class);
//dd($credit);
//dd($credit->getAdjustmentItems()->first()->getCharge()->getAdjustmentItems()->toArray());
$this->_validate($credit);

AdjustmentItem::setCharge中调用Charge::addAdjustmentItem为我解决了问题。

有人知道为什么需要这样做吗?

public function setCharge(?Charge $charge): self
{
$this->charge = $charge;

// This is needed so that the Assert/Callback in Charge knows about this adjustmentItem.
$charge->addAdjustmentItem($this);
return $this;
}

最新更新