diff --git a/src/DataFixtures/InstrumentFixture.php b/src/DataFixtures/InstrumentFixture.php index ede3a27..c66ef99 100644 --- a/src/DataFixtures/InstrumentFixture.php +++ b/src/DataFixtures/InstrumentFixture.php @@ -30,6 +30,7 @@ public function load(ObjectManager $manager): void $appl_inst->setEusipa(Instrument::EUSIPA_KNOCKOUT); $appl_inst->setCurrency("EUR"); $appl_inst->setUnderlying($appl); + $appl_inst->setExecutionTaxRate(0.0012); // 0.12 % $manager->persist($appl_inst); $appl_terms = new InstrumentTerms(); @@ -48,6 +49,7 @@ public function load(ObjectManager $manager): void $msft_inst->setEusipa(Instrument::EUSIPA_UNDERLYING); $msft_inst->setCurrency("USD"); $msft_inst->setUnderlying($msft); + $appl_inst->setExecutionTaxRate(0.0035); // 0.35 % $manager->persist($msft_inst); $manager->flush(); diff --git a/src/Entity/Instrument.php b/src/Entity/Instrument.php index 45676cf..6f455ce 100644 --- a/src/Entity/Instrument.php +++ b/src/Entity/Instrument.php @@ -106,6 +106,10 @@ class Instrument #[ORM\Column(type: "text", length: 50000, nullable: true)] private $notes; + #[ORM\Column(type: "decimal", precision: 5, scale: 4, nullable: true, options: ["unsigned" => true])] + #[Assert\Range(min: 0, max: 1)] + private $executionTaxRate; + public function getId(): ?int { return $this->id; @@ -200,6 +204,18 @@ public function setNotes(?string $notes): self return $this; } + public function getExecutionTaxRate(): ?string + { + return $this->executionTaxRate; + } + + public function setExecutionTaxRate(?string $executionTaxRate): self + { + $this->executionTaxRate = $executionTaxRate; + + return $this; + } + public function getUnderlying(): ?Asset { return $this->underlying; diff --git a/src/Form/ExecutionType.php b/src/Form/ExecutionType.php index cc1bd1b..b72d3ee 100644 --- a/src/Form/ExecutionType.php +++ b/src/Form/ExecutionType.php @@ -62,6 +62,8 @@ public function buildForm(FormBuilderInterface $builder, array $options): void $user = $this->token->getToken()->getUser(); if ($data->instrument) { + $executionTaxRate = $data->instrument->getExecutionTaxRate(); + $direction = $data->instrument->getDirection(); $builder->add('instrument', TextType::class, ['disabled' =>'true']); } else { $builder->add('instrument', EntityType::class, ['class' => Instrument::class]); @@ -109,7 +111,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void ->add('execution_id', NumberType::class, ['label' => 'Execution ID', 'html5' => true, 'required' => false, 'help' => 'Execution ID used by the broker']) ->add('marketplace', TextType::class, ['required' => false, 'help' => 'Location of the exchange']) ->add('commission', MoneyType::class, ['required' => false, 'html5' => false, 'currency' => $currency, 'scale' => 4, 'help' => 'Commission cost (negative amount)']) - ->add('tax', MoneyType::class, ['required' => false, 'html5' => false, 'currency' => $currency, 'scale' => 4, 'help' => 'paid tax is negative, refunded tax positive']) + ->add('tax', MoneyType::class, ['required' => false, 'html5' => false, 'currency' => $currency, 'scale' => 4, 'help' => 'Paid tax is negative, refunded tax positive' . (!empty($executionTaxRate) && !empty($direction) ? ' (applying execution tax rate of -' . $executionTaxRate * 100 . '% when empty)' : '')]) ->add('interest', MoneyType::class, ['required' => false, 'html5' => false, 'currency' => $currency, 'scale' => 4, 'help' => 'Paid interest (negative amount)']) ->add('notes', TextareaType::class, ['required' => false]) ->add('consolidated', CheckboxType::class, ['required' => false, 'help' => 'Check if this transaction matches with your broker']) diff --git a/src/Form/InstrumentType.php b/src/Form/InstrumentType.php index 50de485..4f2525f 100644 --- a/src/Form/InstrumentType.php +++ b/src/Form/InstrumentType.php @@ -14,6 +14,7 @@ use Symfony\Component\Form\Extension\Core\Type\ResetType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextType; +use Symfony\Component\Form\Extension\Core\Type\MoneyType; use Symfony\Component\Form\Extension\Core\Type\TextareaType; use Symfony\Component\Form\Extension\Core\Type\UrlType; use Symfony\Component\OptionsResolver\OptionsResolver; @@ -89,6 +90,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void ->add('terminationdate', DateType::class, ['required' => false, 'label'=>'Termination date', 'widget' => 'single_text']) ->add('url', UrlType::class, ['required' => false, 'label' => 'Instrument website']) ->add('notes', TextareaType::class, ['required' => false]) + ->add('executiontaxrate', TextType::class, ['required' => false, 'label'=>'Execution tax rate %', 'help' => 'Tax rate percentage applicable to executed trades (e.g. 0.12% is 0.0012)']) ->add('save', SubmitType::class, ['label' => 'Submit', 'attr' => ['class' => 'btn btn-primary']]) ->add('reset', ResetType::class, ['label' => 'Reset', 'attr' => ['class' => 'btn btn-secondary']]) ->add('back', ButtonType::class, ['label' => 'Back', 'attr' => ['class' => 'btn btn-secondary']]) diff --git a/src/Form/Model/ExecutionFormModel.php b/src/Form/Model/ExecutionFormModel.php index 3551e80..5124f88 100644 --- a/src/Form/Model/ExecutionFormModel.php +++ b/src/Form/Model/ExecutionFormModel.php @@ -102,8 +102,11 @@ private function populateTransaction(Transaction $transaction) } else { $transaction->setCommission(null); } - if ($this->tax) { + if ($this->tax !== null) { $transaction->setTax($this->tax); + } elseif($this->instrument->getExecutionTaxRate() != null && $this->direction != 0 && isset($total)) { + // apply execution tax rate of the instrument if no tax provided in the tax field + $transaction->setTax($this->direction * $total * $this->instrument->getExecutionTaxRate()); } else { $transaction->setTax(null); } diff --git a/templates/instrument/edit.html.twig b/templates/instrument/edit.html.twig index 806fc8a..61554a7 100644 --- a/templates/instrument/edit.html.twig +++ b/templates/instrument/edit.html.twig @@ -19,6 +19,7 @@