Итак, это мой первый пост в stackoverflow, извините, если я пропустил некоторую обязательную информацию.
Позвольте мне объяснить проблему, с которой я сталкиваюсь.
При попытке загрузить данные используйте команду Doctrine -fixture: php bin/console doctrine:fixture:load -e test
, я получаю следующую ошибку:
In DebtService.php line 152:
Call to a member function getSession() on null
Итак, как это происходит, у меня есть прослушиватель событий pre persist, который вызывает мой сервис DebtService, чтобы проверить, можно ли использовать платеж для выплаты долга.
Я использую:
Symfony: ~3.4.*
Doctrine-Fixture-bundle: 3.0
Вот класс, который я использую для загрузки данных
class LoadBasicData extends Fixture implements FixtureInterface
{
private $container;
public function load(ObjectManager $manager)
{
new Session(new MockFileSessionStorage());
$entities = array(
Client::class,
Landlord::class,
Contact::class,
Month::class,
Year::class,
Honorary::class,
Room::class,
Pension::class,
Warranty::class,
Flat::class,
Contract::class,
Debt::class,
PiggyBank::class,
Transfer::class,
Material::class,
Budget::class,
Cleaning::class,
Expense::class,
ClientPayment::class, // Class That makes the error pop up
//Payment::class
);
foreach($entities as $entity){
$object = new $entity();
$className =explode('\\', get_class($object));
$objName=end($className);
if(method_exists($object, "test")) {
$object = $object->test(); // Returns the object with mocked values
if(method_exists($object, "setDate")){
$object->setDate(new \Datetime("now"));
}
if(method_exists($object, "setRoom")){
$object->setRoom($this->getReference("Room"));
}
if(method_exists($object, "addRoom")){
$object->addRoom($this->getReference("Room"));
}
if(method_exists($object, "setClient")){
$object->setClient($this->getReference("Client"));
}
if(method_exists($object, "setHonorary")){
$object->setHonorary($this->getReference("Honorary"));
}
if(method_exists($object, "setAdministrationHonorary")){
$object->setAdministrationHonorary($this->getReference("Honorary"));
}
if(method_exists($object, "setLandlord")){
$object->setLandlord($this->getReference("Landlord"));
}
if(method_exists($object, "setWarranty")){
$object->setWarranty($this->getReference("Warranty"));
}
if(method_exists($object, "setMonth")){
$object->setMonth($this->getReference("Month"));
}
if(method_exists($object, "setYear")){
$object->setYear($this->getReference("Year"));
}
if(method_exists($object, "addMaterial")){
$object->addMaterial($this->getReference("Material"));
}
if(method_exists($object, "addClientPayment")){
$object->addClientPayment($this->getReference("ClientPayment"));
}
if(method_exists($object, "setPension") && $objName != "Room"){
$object->setPension($this->getReference("Pension"));
}
$this->addReference($objName, $object);
$manager->persist($object);
$manager->flush();
}
}
}
}
Мой слушатель:
class PrePersistListener {
protected $mailService;
protected $requestStack;
protected $translator;
protected $debtService;
public function __construct(MailConstructorService $mailService, RequestStack $requestStack,TranslatorInterface $translator,DebtService $debtService){
$this->mailService = $mailService;
$this->requestStack = $requestStack;
$this->translator = $translator;
$this->debtService = $debtService;
}
public function prePersist(LifecycleEventArgs $args) {
$entity = $args->getObject ();
$em = $args->getObjectManager ();
if ( $entity instanceof Expense) {
$this->expense($entity, $em);
}else if ($entity instanceof Transfer){
$this->transfer($entity, $em);
}else if ($entity instanceof Cleaning){
$this->cleaning($entity, $em);
}else if($entity instanceof ClientPayment){
$this->clientPayment($entity, $em);
}else if ($entity instanceof Debt){
$this->debt($entity,$em);
}else{
return;
}
}
private function clientPayment(ClientPayment $clientPayment,$em){
$contract = $em->getRepository ( 'CoreBundle:Contract' )->findContractByClient ( $clientPayment->getClient () );
$clientPayment->getRentAmount()>0?$this->debtService->generateDeptFromLatePayment($clientPayment, $contract,$em):null;
$clientPayment->getRentAmount()>0?$this->debtService->generateRentDebtFromContract($clientPayment,$contract,$em):null;
$this->debtService->generateHonoraryDebtFromContract($clientPayment,$contract,$em);
$this->debtService->generateWarrantyDebtFromContract($clientPayment,$contract,$em);
if($contract->getRoom() != null){
$pensionCleaning = $contract->getRoom()->getPension()->getCleaningPerClient();
if($pensionCleaning > 0 && $clientPayment->getRentAmount() > 0){
$payments = $em->getRepository ( 'CoreBundle:ClientPayment' )->findByMonthAndYearAndClientAndRentAmount ( $clientPayment->getMonth(), $clientPayment->getYear(),
$clientPayment->getClient());
if($payments == null){
$clientPayment->setRentAmount($clientPayment->getRentAmount() - $pensionCleaning);
$clientPayment->setCleaningAmount($pensionCleaning);
}
}
}
}
//... The rest of the functions
}
Мой service.yml
services:
AD\CoreBundle\Service\DebtService:
arguments: ["@doctrine.orm.default_entity_manager", "@translator","@request_stack", "@logger"]
core_bundle.debt:
alias: AD\CoreBundle\Service\DebtService
public: true
autowire: true
AD\CoreBundle\EventListener\PrePersistListener:
arguments: ["@core_bundle.mail","@request_stack","@translator", "@core_bundle.debt"]
tags:
- { name: doctrine.event_listener, event: prePersist }
loadBasicData:
class: AD\CoreBundle\DataFixtures\ORM\LoadBasicData
tags: ['doctrine.fixture.orm']
#And much more
И, наконец, часть моего DebtService. php:
class DebtService {
public $em;
public $translator;
protected $logger;
public function __construct(EntityManagerInterface $entityManager, TranslatorInterface $translator,RequestStack $requestStack,LoggerInterface $logger) {
$this->em = $entityManager;
$this->translator = $translator;
$this->requestStack = $requestStack;
$this->logger = $logger;
}
public function generateDeptFromLatePayment(ClientPayment $clientPayment,Contract $contract,$em){
$contractDateStr = $contract->getDuePaymentDate()."-".$clientPayment->getMonth()->getNumber()."-".$clientPayment->getYear()->getNumber();
$request = $this->requestStack->getCurrentRequest();
dump($this->requestStack);
dump($this->requestStack->getCurrentRequest());
$latePaymentDebt = $em->getRepository('CoreBundle:Debt')->findOneBy(array(
"client" => $contract->getClient(),
"isLatePayment" => true,
"month" => $clientPayment->getMonth(),
"year" => $clientPayment->getYear()
));
$timestamp = $contract->getArrivalDate()->getTimestamp();
$arrivalMonth = date('m',$timestamp);
$arrivalYear = date('Y',$timestamp);
if(($arrivalMonth != $clientPayment->getMonth()->getNumber() && $arrivalYear == $clientPayment->getYear()->getNumber()) || $clientPayment->getYear()->getNumber() != $arrivalYear){
$pd = $clientPayment->getDate ()->getTimestamp();
$cd = strtotime( $contractDateStr);
if($pd > $cd){
$contractDate = new DateTime($contractDateStr);
$diff = $clientPayment->getDate ()->diff($contractDate)->format("%a");
// IF more not the same day of before
if($diff > 0){
if($latePaymentDebt != null){ // If he already has a debt for late payment
if($clientPayment->getPenaltyAmount() > 0)
$diff = $latePaymentDebt->getAmount() -$clientPayment->getPenaltyAmount() ;
if($diff > 0){ // Si todavia falta pa pagar
$latePaymentDebt->setAmount($diff);
if($contract->getFlat() == null){
$latePaymentDebt->setComment("El pago estaba atrasado de ".$diff." Dia(s) - Pension, pero ya pago $".number_format($clientPayment->getPenaltyAmount(),0,",",".")
." de un monto total de $".number_format($latePaymentDebt->getOldAmount(),0,",","."));
}else{
$latePaymentDebt->setComment("El pago estaba atrasado de ".$diff." Dia(s) - Propiedad, pero ya pago $".number_format($clientPayment->getPenaltyAmount(),0,",",".")
." de un monto total de $".number_format($latePaymentDebt->getOldAmount(),0,",","."));
}
}else if( $diff < 0 ){ //Si pago demas
$this->reduceClientDebt($diff, $clientPayment);
}
else{ // sinon on enlève la dete /!\ A ver que hacer si paga demas
$message = "Se ha removido una deuda al cliente: ".$clientPayment->getClient()->getName()." de un monto de $". number_format($latePaymentDebt->getAmount(),0,",",".").
" por culpa de :".$latePaymentDebt->getComment();
$request->getSession()->getFlashBag()->add("warning", $message);
$amount -= $latePaymentDebt->getAmount();
$em->remove($latePaymentDebt);
}
}else{ // IF he doen't havea debt
if($clientPayment->getPenaltyAmount() != 0){ //Si ya paga una parte o toda su deuda
$amount = 0;
if($contract->getFlat() == null){
$amount = 1000*$diff; // 1000 pesos por dia en caso de pension
}else{
$amount = 1/100*$contract->getFullMonthPrice()*$diff; // 1% per day in case of flat
}
if($amount > $clientPayment->getPenaltyAmount()){ // Si no pago suffisiente
$debt = new Debt();
$debt->setClient($clientPayment->getClient());
$debt->setAutomated(true);
$debt->setAmount($amount - $clientPayment->getPenaltyAmount());
if($contract->getFlat() == null){
$debt->setComment("El pago estaba atrasado de ".$diff." Dia(s) - Pension, pero ya pago $".number_format($clientPayment->getPenaltyAmount(),0,",",".")
." de un monto total de $".number_format($amount,0,",","."));
}else{
$debt->setComment("El pago estaba atrasado de ".$diff." Dia(s) - Propiedad, pero ya pago $".number_format($clientPayment->getPenaltyAmount(),0,",",".")
." de un monto total de $".number_format($amount,0,",","."));
}
$debt->setPaid(false);
$debt->setAdministration(null);
$debt->setMonth($clientPayment->getMonth());
$debt->setYear($clientPayment->getYear());
$debt->setIsLatePayment(true);
$em->persist($debt);
$message = "Se ha añadido una deuda al cliente: ".$clientPayment->getClient()->getName()." de a un monto de $". number_format($debt->getAmount(),0,",",".").
" por culpa de haber pagado con ".$diff." dia(s) de atraso. Pero ya pago $".number_format($clientPayment->getPenaltyAmount(),0,",",".")
." de un monto total de $".number_format($amount,0,",",".");
$request->getSession()->getFlashBag()->add("warning", $message);
}else if($amount < $clientPayment->getPenaltyAmount()){ // Si pago mas de lo que debia por el atraso, se busca las otras deudas
$amount = $clientPayment->getPenaltyAmount() - $amount;
$this->reduceClientDebt($amount,$clientPayment);
}
}
else{ // Sino se crea una deuda del monto entero.
$debt = new Debt();
$debt->setClient($clientPayment->getClient());
$debt->setAutomated(true);
if($contract->getFlat() == null){
$debt->setAmount(1000*$diff); // 1000 pesos por dia en caso de pension
$debt->setComment("El pago estaba atrasado de ".$diff." Dia(s) - Pension");
}else{
$debt->setAmount(1/100*$contract->getFullMonthPrice()*$diff); // 1% per day in case of flat
$debt->setComment("El pago estaba atrasado de ".$diff." Dia(s) - Propiedad");
}
$debt->setPaid(false);
$debt->setAdministration(null);
$debt->setMonth($clientPayment->getMonth());
$debt->setYear($clientPayment->getYear());
$debt->setIsLatePayment(true);
// Message to the user telling him that a debt has been added
$message = "Se ha añadido una deuda al cliente: ".$clientPayment->getClient()->getName()." de a un monto de $". number_format($debt->getAmount(),0,",",".").
" por culpa de haber pagado con ".$diff." dia(s) de atraso.";
$request->getSession()->getFlashBag()->add("warning", $message); // Line 152 that throws the error.
$em->persist($debt);
}
}
}
}else{
if($clientPayment->getPenaltyAmount() != 0){
$this->reduceClientDebt($clientPayment->getPenaltyAmount(),$clientPayment);
}
}
}else{
if($clientPayment->getPenaltyAmount() != 0){
$this->reduceClientDebt($clientPayment->getPenaltyAmount(),$clientPayment);
}
}
}
}
Я попытался прокомментировать $ request-> getSession (); // Это работает для тестирования, но я теряю flashBags в моем приложении.
Я впервые использую Test / Doctrine -Fixture в своих приложениях. Мои знания по этому вопросу все еще ограничены.
Спасибо за любую помощь.
Адриан