SF3 + Doctrine计算日期之间的价格

时间:2016-10-31 16:23:56

标签: php mysql symfony doctrine query-builder

所以在我的Symfony 3项目中,我需要创建一种带 3 params 的价格计算器: date_from date_to guest_number 即可。 MySql中的表格如下:

Dim dbConn as BackCompat.Database

例如,有人选择2016-01-01至2016-01-10为1位客人。计算器应返回1000.为此

创建SQL语句没什么大不了的

示例2 ,有人选择2016-04-15至2016-04-25为1人。

问题是如何使用 Doctrine QueryBuilder 语句构建的,该语句将计算'n'天数从一个周期乘以及'n'天从另一个时期乘以相应的价格?

1 个答案:

答案 0 :(得分:0)

我们假设你有一个实体日历:

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="CalendarRepository")
 * @ORM\Table(name="calendar")
 */
class Calendar
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="date")
     */
    private $dateFrom;

    /**
     * @ORM\Column(type="date")
     */
    private $dateTo;

    /**
     * @ORM\Column(type="integer")
     */
    private $people;

    /**
     * @ORM\Column(type="integer")
     */
    private $price;
}

然后您的存储库类可能如下所示:

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\EntityRepository;

class CalendarRepository extends EntityRepository
{
    public function findPriceFor(\DateTime $dateFrom, \DateTime $dateTo, $nrOfPeople)
    {
        $qb = $this->createQueryBuilder('calendar');
        $qb->select('SUM(
                        CASE 
                            WHEN calendar.dateFrom >= :dateFromChosen AND calendar.dateTo >= :dateToChosen THEN DATE_DIFF(:dateToChosen, calendar.dateFrom)
                            WHEN calendar.dateFrom <= :dateFromChosen AND calendar.dateTo >= :dateToChosen THEN DATE_DIFF(:dateToChosen, :dateFromChosen)
                            WHEN calendar.dateFrom <= :dateFromChosen AND calendar.dateTo <= :dateToChosen THEN DATE_DIFF(calendar.dateTo, :dateFromChosen)
                            WHEN calendar.dateFrom >= :dateFromChosen AND calendar.dateTo <= :dateToChosen THEN DATE_DIFF(calendar.dateTo, calendar.dateFrom)
                            ELSE 0
                        END
                    )*calendar.price AS intervalPrice');

        $qb->andWhere('calendar.people = :nrOfPeople')
            ->andWhere(
                $qb->expr()->andX(
                    $qb->expr()->lt('calendar.dateFrom', ':dateToChosen'),
                    $qb->expr()->gt('calendar.dateTo', ':dateFromChosen')
                )
            );

        $qb->setParameter('nrOfPeople', $nrOfPeople)
            ->setParameter('dateFromChosen', $dateFrom->format('Y-m-d'))
            ->setParameter('dateToChosen', $dateTo->format('Y-m-d'));

        $qb->groupBy('calendar.id');

        $query = $qb->getQuery();

        $resultArray = $query->execute();

        $totalPrice = array_sum(array_column($resultArray, 'intervalPrice'));

        return $totalPrice;
    }
}

如果我们采用你的示例MySQL表,并决定计算一个人的价格,从&#34; 2016-04-15&#34;到&#34; 2016-04-25&#34;,然后结果将是:

result array and total price