Commit 16d0368b authored by Karamel's avatar Karamel
Browse files

Fix Payment mode and Tariff area submodel management with Mysql.

parent fed644a6
......@@ -84,7 +84,115 @@ class PaymentmodeAPI extends APIRefHelper
$imgApi = new ImageAPI(null, $this->dao);
$imgApi->delete($deleteImgIds);
}
/* Delete orphaned values and returns, because it doesn't work well
* with Mysql. */
foreach ($data as $d) {
$update = $d->getId() !== null;
$this->dao->write($d);
if (!$update) {
continue;
}
// Remove orphan prices
// Get values and returns of products that are still in prices
// and delete those that are not in it from database.
$keptValues = [];
$keptReturns = [];
foreach ($d->getValues() as $value) {
$keptValues[] = $value->getValue();
}
foreach ($d->getReturns() as $return) {
$keptReturns[] = $return->getMinAmount();
}
$em = $this->dao->getEntityManager();
$dqlVal = 'delete \Pasteque\Server\Model\PaymentModeValue p '
. 'where p.paymentMode = ?1';
$qVal = null;
if (count($keptValues) > 0) {
$dqlVal .= ' and (p.value not in (';
$params = [];
for ($i = 0; $i < count($keptValues); $i++) {
$params[] = '?' . ($i + 2);
}
$dqlVal .= implode(', ', $params);
$dqlVal .= '))';
$qVal = $em->createQuery($dqlVal);
for ($i = 0; $i < count($keptValues); $i++) {
$qVal->setParameter($i + 2, $keptValues[$i]);
}
} else {
$qVal = $em->createQuery($dql);
}
// TODO: payment mode value images are not deleted.
$qVal->setParameter(1, $d);
$qVal->execute();
$dqlRet = 'delete \Pasteque\Server\Model\PaymentModeReturn p '
. 'where p.paymentMode = ?1';
$qRet = null;
if (count($keptReturns) > 0) {
$dqlRet .= ' and (p.minAmount not in (';
$params = [];
for ($i = 0; $i < count($keptReturns); $i++) {
$params[] = '?' . ($i + 2);
}
$dqlRet .= implode(', ', $params);
$dqlRet .= '))';
$qRet = $em->createQuery($dqlRet);
for ($i = 0; $i < count($keptReturns); $i++) {
$qRet->setParameter($i + 2, $keptReturns[$i]);
}
} else {
$qRet = $em->createQuery($dqlRet);
}
$qRet->setParameter(1, $d);
$qRet->execute();
}
// Write and commit PaymentModes
return parent::write(($arrayArgs) ? $data : $data[0]);
}
public function delete($id) {
/* This is the same as APIHelper delete but explicitely delete
* associated values and returns because cascading doesn't work well
* with Mysql for an obscure reason. */
$id = (is_array($id)) ? $id : array($id);
$references = array();
$deleteImgIds = [];
foreach ($id as $i) {
$model = $this->dao->read(static::MODEL_NAME, $i);
if ($model === null) {
continue;
}
$references[] = $model;
foreach ($model->getValues() as $val) {
if ($val->hasImage()) {
$deleteImgIds[] = ['model' => 'paymentmodevalue',
'modelId' => json_encode(['paymentMode' => $model->getId(),
'value' => $val->getValue()])];
}
}
}
if (count($deleteImgIds) > 0) {
$imgApi = new ImageAPI(null, $this->dao);
$imgApi->delete($deleteImgIds);
}
$em = $this->dao->getEntityManager();
$dqlRet = 'delete \Pasteque\Server\Model\PaymentModeReturn p '
. 'where p.paymentMode = ?1';
$dqlVal = 'delete \Pasteque\Server\Model\PaymentModeValue p '
. 'where p.paymentMode = ?1';
$qRet = $em->createQuery($dqlRet);
$qVal = $em->createQuery($dqlVal);
if (count($deleteImgIds) == 0) {
$this->dao->startTransaction();
}
foreach ($references as $ref) {
$qRet->setParameter(1, $ref);
$qVal->setParameter(1, $ref);
$qRet->execute();
$qVal->execute();
$this->dao->delete($ref);
}
$this->dao->commit();
return count($references);
}
}
......@@ -31,4 +31,84 @@ class TariffareaAPI extends APIRefHelper
{
const MODEL_NAME = 'Pasteque\Server\Model\TariffArea';
const DEFAULT_ORDER = 'dispOrder';
public function write($data) {
/* This is the same as APIHelper::write but using dql to remove
* orphaned prices because it doesn't work with Mysql because of the
* composite primary key. */
$this->supportOrDie($data);
$arrayArgs = is_array($data);
$data = ($arrayArgs) ? $data : array($data);
foreach ($data as $d) {
$update = $d->getId() !== null;
$this->dao->write($d);
if (!$update) {
continue;
}
// Remove orphan prices
// Get ids of products that are still in prices
// and delete those that are not in it from database.
$keptPrd = [];
foreach ($d->getPrices() as $price) {
$prdId = $price->getProduct()->getId();
if ($prdId !== null) {
// just in case
$keptPrd[] = $price->getProduct();
}
}
$em = $this->dao->getEntityManager();
$dql = 'delete \Pasteque\Server\Model\TariffAreaPrice p '
. 'where p.tariffArea = ?1';
$q = null;
if (count($keptPrd) > 0) {
$dql .= ' and (p.product not in (';
$params = [];
for ($i = 0; $i < count($keptPrd); $i++) {
$params[] = '?' . ($i + 2);
}
$dql .= implode(', ', $params);
$dql .= '))';
$q = $em->createQuery($dql);
for ($i = 0; $i < count($keptPrd); $i++) {
$q->setParameter($i + 2, $keptPrd[$i]);
}
} else {
$q = $em->createQuery($dql);
}
$q->setParameter(1, $d);
$q->execute();
}
$this->dao->commit();
if ($arrayArgs) {
return $data;
} else {
return $data[0];
}
}
public function delete($id) {
/* This is the same as APIHelper delete but explicitely delete
* associated prices because cascading doesn't work well
* with Mysql for an obscure reason. */
$id = (is_array($id)) ? $id : array($id);
$references = array();
foreach ($id as $i) {
$model = $this->dao->read(static::MODEL_NAME, $i);
if ($model != null) {
$references[] = $model;
}
}
$em = $this->dao->getEntityManager();
$dql = 'delete \Pasteque\Server\Model\TariffAreaPrice p '
. 'where p.tariffArea = ?1';
$q = $em->createQuery($dql);
$this->dao->startTransaction();
foreach ($references as $ref) {
$q->setParameter(1, $ref);
$q->execute();
$this->dao->delete($ref);
}
$this->dao->commit();
return count($references);
}
}
......@@ -132,9 +132,10 @@ class PaymentMode extends DoctrineModel
}
/**
* @OneToMany(targetEntity="\Pasteque\Server\Model\PaymentModeValue", mappedBy="paymentMode", cascade={"all"}, orphanRemoval=true)
* @OneToMany(targetEntity="\Pasteque\Server\Model\PaymentModeValue", mappedBy="paymentMode", cascade={"all"})
* @OrderBy({"value" = "DESC"})
*/
// Warning: no orphan removal as it doesn't work with Mysql. This is handled in PaymentModeAPI.
protected $values;
public function getValues() { return $this->values; }
public function setValues($values) {
......@@ -149,19 +150,18 @@ class PaymentMode extends DoctrineModel
}
public function clearValues() {
foreach ($this->values->getKeys() as $key) {
$this->values->get($key)->setPaymentMode(null);
$this->values->remove($key);
}
}
public function removeValue($value) {
$this->values->removeElement($value);
$value->setPaymentMode(null);
}
/**
* @OneToMany(targetEntity="\Pasteque\Server\Model\PaymentModeReturn", mappedBy="paymentMode", cascade={"all"}, orphanRemoval=true)
* @OneToMany(targetEntity="\Pasteque\Server\Model\PaymentModeReturn", mappedBy="paymentMode", cascade={"all"})
* @OrderBy({"minAmount" = "DESC"})
*/
// Warning: no orphan removal as it doesn't work with Mysql. This is handled in PaymentModeAPI.
protected $returns;
public function getReturns() { return $this->returns; }
public function setReturns($returns) {
......@@ -179,13 +179,11 @@ class PaymentMode extends DoctrineModel
}
public function clearReturns() {
foreach ($this->returns->getKeys() as $key) {
$this->returns->get($key)->setPaymentMode(null);
$this->returns->remove($key);
}
}
public function removeReturn($return) {
$this->returns->removeElement($return);
$return->setPaymentMode(null);
}
/**
......
......@@ -105,7 +105,8 @@ class TariffArea extends DoctrineModel
public function setDispOrder($dispOrder) { $this->dispOrder = $dispOrder; }
/**
* @OneToMany(targetEntity="\Pasteque\Server\Model\TariffAreaPrice", mappedBy="tariffArea", cascade={"all"}, orphanRemoval=true) */
* @OneToMany(targetEntity="\Pasteque\Server\Model\TariffAreaPrice", mappedBy="tariffArea", cascade={"all"}) */
// Warning: no orphan removal as it doesn't work with Mysql. This is handled in TariffAreaAPI.
protected $prices;
public function getPrices() { return $this->prices; }
public function setPrices($prices) {
......@@ -116,7 +117,6 @@ class TariffArea extends DoctrineModel
}
public function clearPrices() {
foreach ($this->prices->getKeys() as $key) {
$this->prices->get($key)->setTariffArea(null);
$this->prices->remove($key);
}
}
......@@ -128,7 +128,6 @@ class TariffArea extends DoctrineModel
}
public function removePrice($price) {
$this->prices->removeElement($price);
$price->setTariffArea(null);
}
}
......@@ -85,7 +85,10 @@ class DoctrineDAO implements DAO
else { return null; }
}
private function startTransaction() {
/** Start a transaction. It should be a private method automatically called
* through write/delete calls, but it may be required for hacky tricks.
* Do not use it unless starting updates from a dql request. */
public function startTransaction() {
$this->em->beginTransaction();
$this->inTransaction = true;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment