有人可以帮我解决这个问题。我在创建查询时遇到问题,或者如何向createAction添加更改以实现以下目的。在点击创建时,它会检查工资核算期是否有效,因为在工资核算周表中,当用户输入两周时,它会填充一周。
工资核算期:payrollperiodid,开始日期,结束日期和州 工资周:id,startDAte,enddate,numofdays,正常工作时间。
例如。用户输入startdate:16-07-2017 enddate:29-07-2017在工资核算期间然后在工资核算周表期间1 startdate:16-07-2017 endDate:22-07-2017 period 2 startdate:23-07-2017结束日期:29-07-2017
因此,该期间将被视为有效的其他错误,然后在创建一旦期间有效时检查是否存在于工资核算期间表中的其他错误。但我不确定如何添加确保用户进入2周时间的部分。 > 7天< = 14天了,我不想使用硬数字我怎么能实现这个
public function createAction(Request $request,$startDate, $endDate)
{
$entity = new Payrollperiod();
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('comtwclagripayrollBundle:Payrollperiod')->findByPayrollPeriod(array('startDate'=>$startDate,'endDate'=> $endDate));
if ($entity){
$this->addFlash('error','ERROR! Payroll Period exist');
return $this->redirect($this->generateUrl('payrollperiod_create'));
}
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('payrollperiod_show', array('payrollperiodid' => $entity->getpayrollperiodid())));
}
return array(
'entity' => $entity,
'form' => $form->createView(), );
}
public function findByPayrollPeriod($startDate, $endDate)
{
return $this->getEntityManager()
->createQuery(
'SELECT p FROM comtwclagripayrollBundle:PayrollWeek
WHERE startDate = :startDate or endDate = :endDate'
)
->setParameter('startDate', $startDate)
->setParameter('endDate', $endDate)
->getResult();
}
**** ****更新
<?php
namespace com\twcl\agripayrollBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
//use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
/**
* Payrollperiod
*
* @ORM\Table(name="PayrollPeriod")
* @ORM\Entity
*
*/
class Payrollperiod
{
/**
* @var integer
*
* @ORM\Column(name="payrollperiodid", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $payrollperiodid;
/**
* @var \DateTime
*
* @ORM\Column(name="startDate", type="datetime", nullable=false)
* @Assert\Type("DateTime")
*/
private $startdate;
/**
* @var \DateTime
*
* @ORM\Column(name="endDate", type="datetime", nullable=false)
* @Assert\Type("DateTime")
*
*/
private $enddate;
/**
* @var integer
*
* @ORM\Column(name="State", type="integer", nullable=false)
*
*/
private $state;
public function getPayrollperiodid() {
return $this->payrollperiodid;
}
public function getStartdate() {
return $this->startdate;
}
public function getEnddate() {
return $this->enddate;
}
public function getState() {
return $this->state;
}
public function setPayrollperiodid($payrollperiodid) {
$this->payrollperiodid = $payrollperiodid;
}
public function setStartdate(\DateTime $startdate) {
$this->startdate = $startdate;
}
public function setEnddate(\DateTime $enddate) {
$this->enddate = $enddate;
}
public function setState($state) {
$this->state = $state;
}
/**
* Render a payrollPeriodID as a string.
*
* @return string
*/
public function __toString()
{
return (string) $this->getPayrollperiodid();
}
/**
* @Assert\Callback
*/
public function validatePayrollPeriod(Payrollperiod $Payrollperiod,ExecutionContextInterface $context)
{
$conflicts = $this->getDoctrine()
->getRepository('comtwclagripayrollBundle:Payrollperiod')
->findbyPayrollPeriod($Payrollperiod->getstartDate(), $Payrollperiod->getendDate())
;
if (count($conflicts) > 0) {
$context->buildViolation('Start date and end date exists')
->atPath('startdate')
->addViolation();
}
}
}
public function findbyPayrollPeriod(\DateTime $startDate, \DateTime $endDate)
{
$qb = $this->createQueryBuilder('e');
return $qb->andWhere('e.startDate = :startDate AND e.endDate = :endDate')
->setParameter('startDate', $startDate)
->setParameter('endDate', $endDate)
->getQuery()
->execute()
;
}
但是我仍然没有收到错误消息,我错过了什么
答案 0 :(得分:1)
我认为你可以通过以下方式解决问题
//create new trait
<?php
namespace yourBundlePath\Form\Type\Utility;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
*
* @package Daim\CoreBundle\Form\Type\Utility
*/
trait ContainerTrait
{
/**
* @var ContainerInterface
*/
private $containerObject;
/**
* @param ContainerInterface $container
* @return ContainerInterface
*/
public function setContainer(ContainerInterface $container)
{
return $this->containerObject = $container;
}
/**
* @return ContainerInterface
*/
public function getContainer()
{
return $this->containerObject;
}
}
//form
use yourBundlePath\Form\Type\Utility\ContainerTrait;
class yourFormClass
{
//call after the class declaration
use ContainerTrait;
$builder->addEventListener(
FormEvents::SUBMIT,
function (FormEvent $event) {
$form = $event->getForm();
$em = $this->getContainer()->get('doctrine');
$startDate = $form->get('startDate')->getData();
$endDate = $form->get('endDate')->getData();
$entity = $em->getRepository('comtwclagripayrollBundle:Payrollperiod')->findByPayrollPeriod(array('startDate'=>$startDate,'endDate'=> $endDate));
if ($entity){
$form->get('startDate')->addError(
new FormError(
'ERROR! Payroll Period exist'
)
);
}
}
);
您也可以参考网址:https://symfony.com/doc/current/form/dynamic_form_modification.html
答案 1 :(得分:0)
可以通过各种方式解决这个问题。如果这是一个常见问题(和/或您更喜欢全局解决方案),请使用Class Constraint Validator。如果您不介意“本地”解决方案,请查看Callback Constraint。
两者都在文档页面中解释。另一个参考是this SO question。
剩下的就是如何计算我建议使用PHP的DateTime::diff
之类的日期之间的差异:
$days = $startDate->diff($endDate)->days;
if ($days <= 7 && $days > 14) {
// build my constraint error message because the period is invalid.
}
所以,让我先说一下我们的评论垃圾邮件,或许可以从某个地方开始轻松一点。看来你正好在中间潜水,没有Symfony和/或PHP的任何基础。 Symfony有很好的教程和示例,但是如果你不能应用那些你将会遇到困难的事情。
回调验证仅用于检查两个日期之间的差异。一般来说,实体不应该与数据库交谈,而只应与自身/相关的实体类进行对话。
class Payrollperiod {
...
/**
* @Assert\Callback
*/
public function validatePayrollPeriod(ExecutionContextInterface $context) {
$days = $this->startdate->diff($this->enddate)->days;
if ($days <= 7 && $days > 14) {
$context->buildViolation('There have to be at least 7 and a maximum of 13 days for your payroll period.')
->atPath('enddate') // this is where the message is bound to, can be either start or end date depending on where you prefer.
->addViolation();
}
}
}
您的
findbyPayrollPeriod
似乎有效,只要它在您的PayrollperiodRepository
类文件中。而你确实想要进行单一的等于检查,而不是看范围是否重叠等。
此功能也可以使用多个列上的doctrine unique constraints来处理,例如(user,startdate)和(user,enddate)。当您尝试添加它时,这应该会给您一个错误,因为它需要一个唯一的值。即使没有findbyPayrollPeriod
功能。
在您的控制器中,您的存储库行存在多个问题。
- 您正在使用数组作为参数,而不是函数具有的两个参数。
- 您正在覆盖表单数据实体,因为您使用的是相同的变量名称。
- 您的
醇>$startdate
和$enddate
看似神奇。他们来自实体,因此请使用吸气剂。作为旁注,您可能不想重定向闪存,但只是继续正常(因此您不会丢失表单数据)。
总而言之,你会得到一些部分的东西:
...
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$entityExists = $em->getRepository('comtwclagripayrollBundle:Payrollperiod')
->findByPayrollPeriod($entity->getStartdate(), $entity->getEnddate());
// If the entity does not exist we can add it and redirect to the new page.
if (!$entityExists) {
// Add our form entity to the database.
$em->persist($entity);
$em->flush();
// redirectToRoute is a controller helper function and is a tiny bit shorter.
return $this->redirectToRoute('payrollperiod_show', array(
'payrollperiodid' => $entity->getPayrollperiodid()
));
}
// Form is valid but we didn't return anything so far.
// So there is an entity with the same period start or end.
// Add a flash and show the form again.
$this->addFlash('error', 'A payroll period is already present
with the same start or end date.');
}
return ...