diff --git a/modules/shareholder_register_dividend/shareholder_register_dividend.drush.inc b/modules/shareholder_register_dividend/shareholder_register_dividend.drush.inc index d63fcb6db49f500355d9413c4705a8a10b399ca1..75e73ed94c6d19b7b7c11ad0649f488db6f714fb 100644 --- a/modules/shareholder_register_dividend/shareholder_register_dividend.drush.inc +++ b/modules/shareholder_register_dividend/shareholder_register_dividend.drush.inc @@ -22,9 +22,62 @@ function shareholder_register_dividend_drush_command() { 'examples' => [], ]; + $commands['register-dividend'] = [ + 'description' => 'This command will register a dividend.', + 'aliases' => ['sr-rdiv'], + 'arguments' => + [ + 'dividend_date' => 'The date of the dividend distribution', + 'dividend' => 'The dividend per share', + 'begin_of_period' => 'Start date of dividend allocation period', + 'end_of_period' => 'End date of dividend allocation period', + 'allocation_method' => 'Plugin id of the allocation method', + 'tax_method' => 'Plugin id of the tax method', + 'distribution' => 'Name of the distribution', + ], + 'options' => [], + 'examples' => [], + ]; + return $commands; } +/** + * Drush command logic. + */ +function drush_shareholder_register_dividend_register_dividend( + $dividend_date, + $dividend, + $begin_of_period, + $end_of_period, + $allocation_method, + $tax_method, + $distribution) { + $dividend_config = [ + 'dividend_date' => $dividend_date, + 'dividend' => $dividend, + 'start_date' => $begin_of_period, + 'end_date' => $end_of_period, + 'allocation' => $allocation_method, + 'tax' => $tax_method, + ]; + + $s = \Drupal::service('shareholder_register_dividend.default'); + $batch = $s->getDividendAllocationBatch($dividend_config); + $batch['operations'][] = [ + '\Drupal\shareholder_register_dividend\Form\DividendForm::registerDividend', + [ + $distribution, + ], + ]; + + batch_set($batch); + $batch =& batch_get(); + $batch['progressive'] = FALSE; + + // Process the batch. + drush_backend_batch_process(); +} /** * Drush command logic. diff --git a/modules/shareholder_register_dividend/shareholder_register_dividend.install b/modules/shareholder_register_dividend/shareholder_register_dividend.install index d78d6780f9d9fa365250d7064cf9676a7023da37..d84b20517f542b7832dfea4ad412ddcad79d4c17 100644 --- a/modules/shareholder_register_dividend/shareholder_register_dividend.install +++ b/modules/shareholder_register_dividend/shareholder_register_dividend.install @@ -23,3 +23,15 @@ function shareholder_register_dividend_update_8001(&$sandbox) { \Drupal::entityDefinitionUpdateManager() ->installFieldStorageDefinition('state', 'shareholder_dividend', 'shareholder_dividend', $storage_definition); } + +/** + * Add extra to shareholder_dividend. + */ +function shareholder_register_dividend_update_8002(&$sandbox) { + $storage_definition = BaseFieldDefinition::create('map') + ->setLabel(t('Extra')) + ->setDescription(t('Extra data for this Dividend.')); + + \Drupal::entityDefinitionUpdateManager() + ->installFieldStorageDefinition('extra', 'shareholder_dividend', 'shareholder_dividend', $storage_definition); +} diff --git a/modules/shareholder_register_dividend/shareholder_register_dividend.services.yml b/modules/shareholder_register_dividend/shareholder_register_dividend.services.yml index 254b220d95a7ad6a3671ce0cf272d034aecd637e..3fcbdf3201a197dc4dbfaedc589805e53f425568 100644 --- a/modules/shareholder_register_dividend/shareholder_register_dividend.services.yml +++ b/modules/shareholder_register_dividend/shareholder_register_dividend.services.yml @@ -10,3 +10,9 @@ services: shareholder_register_dividend.default: class: Drupal\shareholder_register_dividend\DividendService + + shareholder_register_dividend.twig.extension: + class: Drupal\shareholder_register_dividend\TwigExtension\ShareholderRegisterDividendTwigExtension + arguments: [] + tags: + - { name: twig.extension } diff --git a/modules/shareholder_register_dividend/src/DividendService.php b/modules/shareholder_register_dividend/src/DividendService.php index 85c5ebe7078c5fb71533f4ecced45cce7cb56a29..02ca6eb13d1505c379fa7526f55bd821a3747c5c 100644 --- a/modules/shareholder_register_dividend/src/DividendService.php +++ b/modules/shareholder_register_dividend/src/DividendService.php @@ -121,10 +121,12 @@ class DividendService implements DividendServiceInterface { 'tax' => $details->tax, 'fraction' => $details->fraction, 'shareholder_id' => $details->shareholder_id, + 'details' => [(array) $details], ]; } else { $context['results']['totals'][$hash]['fraction'] += $details->fraction; + $context['results']['totals'][$hash]['details'][] = (array) $details; } } @@ -175,9 +177,11 @@ class DividendService implements DividendServiceInterface { $gross = 0; $net = 0; $tax = 0; + $dividends = []; foreach ($entity->get('dividends')->referencedEntities() as $d) { if ($d->get('distribution_id')->target_id == $distribution) { + $dividends[] = $d; $gross = bcadd($gross, $d->get('gross')->value, 2); $net = bcadd($net, $d->get('net')->value, 2); } @@ -187,6 +191,7 @@ class DividendService implements DividendServiceInterface { if ($tax > 0 || $gross > 0) { $context = [ 'shareholder' => $entity, + 'dividends' => $dividends, 'gross' => $gross, 'net' => $net, 'tax' => $tax, diff --git a/modules/shareholder_register_dividend/src/Entity/ShareholderDividend.php b/modules/shareholder_register_dividend/src/Entity/ShareholderDividend.php index 74ad935e019dce83122bc17463ccc44e7722b610..d42e50764a6408973b30b7c06a42a612f963c186 100644 --- a/modules/shareholder_register_dividend/src/Entity/ShareholderDividend.php +++ b/modules/shareholder_register_dividend/src/Entity/ShareholderDividend.php @@ -126,6 +126,25 @@ class ShareholderDividend extends ContentEntityBase implements ShareholderDivide return $this; } + /** + * {@inheritdoc} + */ + public function getData($key, $default = NULL) { + $data = []; + if (!$this->get('extra')->isEmpty()) { + $data = $this->get('extra')->first()->getValue(); + } + return isset($data[$key]) ? $data[$key] : $default; + } + + /** + * {@inheritdoc} + */ + public function setData($key, $value) { + $this->get('extra')->__set($key, $value); + return $this; + } + /** * {@inheritdoc} */ @@ -270,6 +289,10 @@ class ShareholderDividend extends ContentEntityBase implements ShareholderDivide ->setRevisionable(TRUE) ->setDefaultValue('draft'); + $fields['extra'] = BaseFieldDefinition::create('map') + ->setLabel(t('Extra')) + ->setDescription(t('Extra data for this Dividend.')); + $fields['created'] = BaseFieldDefinition::create('created') ->setLabel(t('Created')) ->setDescription(t('The time that the entity was created.')); diff --git a/modules/shareholder_register_dividend/src/Form/DividendForm.php b/modules/shareholder_register_dividend/src/Form/DividendForm.php index f8c0d59dad2c1d95b7c8192e2ba4dc6b3b964956..a898a05d7e2489e2e010a11c29aeb2c30a222577 100644 --- a/modules/shareholder_register_dividend/src/Form/DividendForm.php +++ b/modules/shareholder_register_dividend/src/Form/DividendForm.php @@ -15,11 +15,73 @@ use PhpOffice\PhpSpreadsheet\Reader\Xlsx; use Drupal\shareholder_register\Entity\Shareholder; use Drupal\shareholder_register\Entity\Share; +use Drupal\shareholder_register_dividend\Entity\DividendDistribution; +use Drupal\shareholder_register_dividend\Entity\ShareholderDividend; + /** * Class DividendForm. */ class DividendForm extends FormBase { + /** + * {@inheritdoc} + */ + public static function registerDividend($distribution, &$context) { + $config = $context['results']['config']; + if (!isset($context['sandbox']['to_write'])) { + $context['sandbox']['to_write'] = $context['results']['totals']; + $dist = DividendDistribution::create([ + 'name' => $distribution, + ]); + $dist->save(); + $context['sandbox']['distribution'] = $dist; + } + + for ($i = 0; $i < 100; $i++) { + if ($line = array_pop($context['sandbox']['to_write'])) { + $gross = bcdiv( + bcmul( + $line['fraction'], + $config['dividend'], + 2 + ), + $context['results']['base'], + 2 + ); + + $tax = bcdiv( + bcmul( + $gross, + $line['tax'], + 2), + 100, + 2 + ); + + $div = ShareholderDividend::create([ + 'distribution_id' => $context['sandbox']['distribution']->id(), + 'shareholder_id' => $line['shareholder_id'], + 'gross' => $gross, + 'net' => bcsub($gross, $tax, 2), + ]); + $div->setData('details', $line['details']); + $div->save(); + } + } + + $context['finished'] = (count($context['results']['totals']) - count($context['sandbox']['to_write'])) / count($context['results']['totals']); + } + + /** + * {@inheritdoc} + */ + public static function finishRegisterDividend($success, $results, $operations) { + drupal_set_message(t( + 'Dividend registered!', + [] + )); + } + /** * {@inheritdoc} */ @@ -30,7 +92,7 @@ class DividendForm extends FormBase { $spreadsheet = new Spreadsheet(); - // Set document properties + // Set document properties. $spreadsheet->getProperties()->setCreator('DSR') ->setLastModifiedBy(t('DSR')) ->setTitle(t('DSR Dividend simulation')) @@ -270,6 +332,19 @@ class DividendForm extends FormBase { ], ]; + $form['distribution'] = [ + '#type' => 'textfield', + '#title' => $this->t('Distribution name'), + '#states' => [ + 'visible' => [ + ':input[name="action"]' => array('value' => '2'), + ], + 'required' => [ + ':input[name="action"]' => array('value' => '2'), + ], + ], + ]; + $form['submit'] = [ '#type' => 'submit', '#value' => $this->t('Submit'), @@ -310,15 +385,27 @@ class DividendForm extends FormBase { ]; $batch = $s->getDividendAllocationBatch($dividend_config); - $batch['operations'][] = [ - '\Drupal\shareholder_register_dividend\Form\DividendForm::writeExportDividend', - [], - ]; - $batch['operations'][] = [ - '\Drupal\shareholder_register_dividend\Form\DividendForm::writeExportDividendDetails', - [], - ]; - $batch['finished'] = '\Drupal\shareholder_register_dividend\Form\DividendForm::finishExportDividend'; + + if ($form_state->getValue('action') == '1') { + $batch['operations'][] = [ + '\Drupal\shareholder_register_dividend\Form\DividendForm::writeExportDividend', + [], + ]; + $batch['operations'][] = [ + '\Drupal\shareholder_register_dividend\Form\DividendForm::writeExportDividendDetails', + [], + ]; + $batch['finished'] = '\Drupal\shareholder_register_dividend\Form\DividendForm::finishExportDividend'; + } + else { + $batch['operations'][] = [ + '\Drupal\shareholder_register_dividend\Form\DividendForm::registerDividend', + [ + $form_state->getValue('distribution'), + ], + ]; + $batch['finished'] = '\Drupal\shareholder_register_dividend\Form\DividendForm::finishRegisterDividend'; + } batch_set($batch); } diff --git a/modules/shareholder_register_dividend/src/Plugin/DividendTax/BE2018.php b/modules/shareholder_register_dividend/src/Plugin/DividendTax/BE2018.php index 6c47b7ba7e6fd654b65bb200ebb481dbba79063e..14f49236aa4bfe7b9bdbbe1a848389c264ada6a0 100644 --- a/modules/shareholder_register_dividend/src/Plugin/DividendTax/BE2018.php +++ b/modules/shareholder_register_dividend/src/Plugin/DividendTax/BE2018.php @@ -19,6 +19,7 @@ class BE2018 extends DividendTaxDefinitionBase { public function computeDividendTaxRate($shareholder, $dividends, $dividend_config) { foreach ($dividends as $dividend) { $dividend->tax = 30; + $dividend->taxcode = '30'; } } diff --git a/modules/shareholder_register_dividend/src/Plugin/DividendTax/BE2018VVPR.php b/modules/shareholder_register_dividend/src/Plugin/DividendTax/BE2018VVPR.php index b872dfa7ac4a5c43ace32ce419e232d017145542..7f4235509be6c3971642aee8b83f2ab6120a7919 100644 --- a/modules/shareholder_register_dividend/src/Plugin/DividendTax/BE2018VVPR.php +++ b/modules/shareholder_register_dividend/src/Plugin/DividendTax/BE2018VVPR.php @@ -49,6 +49,7 @@ class BE2018VVPR extends DividendTaxDefinitionBase { $issue_date = $share->getIssuingTransaction()->getDate(); if ($issue_date < '2013-07-01' || $share->getShareholder()->bundle() != 'natural_person') { $dividend->tax = 30; + $dividend->taxcode = 'pre2013'; continue; } @@ -61,6 +62,7 @@ class BE2018VVPR extends DividendTaxDefinitionBase { 2), 2); $dividend->tax = 30; + $dividend->taxcode = 'vvpr-abuse'; continue; } @@ -68,12 +70,15 @@ class BE2018VVPR extends DividendTaxDefinitionBase { $dividend_year = substr($dividend_config['start_date'], 0, 4); if (($dividend_year - $issue_year) > 2) { $dividend->tax = 15; + $dividend->taxcode = 'vvpr-year-2'; } elseif (($dividend_year - $issue_year) > 1) { $dividend->tax = 20; + $dividend->taxcode = 'vvpr-year-1'; } else { $dividend->tax = 30; + $dividend->taxcode = 'vvpr-year-0'; } } } diff --git a/modules/shareholder_register_dividend/src/TwigExtension/ShareholderRegisterDividendTwigExtension.php b/modules/shareholder_register_dividend/src/TwigExtension/ShareholderRegisterDividendTwigExtension.php new file mode 100644 index 0000000000000000000000000000000000000000..69930ecbe651926ba1e1401d19b61725c64ca8ce --- /dev/null +++ b/modules/shareholder_register_dividend/src/TwigExtension/ShareholderRegisterDividendTwigExtension.php @@ -0,0 +1,150 @@ +<?php +namespace Drupal\shareholder_register_dividend\TwigExtension; + +use Drupal\shareholder_register\Entity\Share; + +/** + * Class ShareholderRegisterDividendTwigExtension. + */ +class ShareholderRegisterDividendTwigExtension extends \Twig_Extension { + + /** + * {@inheritdoc} + */ + public function getTokenParsers() { + return []; + } + + /** + * {@inheritdoc} + */ + public function getNodeVisitors() { + return []; + } + + /** + * {@inheritdoc} + */ + public function getFilters() { + return [ + new \Twig_SimpleFilter('shareholder_dividend_gross', [$this, 'shareholderDividendGross']), + new \Twig_SimpleFilter('shareholder_dividend_net', [$this, 'shareholderDividendNet']), + new \Twig_SimpleFilter('shareholder_dividend_tax', [$this, 'shareholderDividendTax']), + new \Twig_SimpleFilter('shareholder_dividend_details', [$this, 'shareholderDividendDetails']), + ]; + } + + /** + * {@inheritdoc} + */ + public function getTests() { + return []; + } + + /** + * {@inheritdoc} + */ + public function getFunctions() { + return [ + ]; + } + + /** + * {@inheritdoc} + */ + public function getOperators() { + return []; + } + + /** + * {@inheritdoc} + */ + public function getName() { + return 'shareholder_register_dividend.twig.extension'; + } + + /** + * {@inheritdoc} + */ + public function shareholderDividendGross($object, $distribution_id) { + $s = \Drupal::service('shareholder_register_dividend.default'); + $c = $s->getDividendContext($object, $distribution_id); + return $c['gross']; + } + + /** + * {@inheritdoc} + */ + public function shareholderDividendNet($object, $distribution_id) { + $s = \Drupal::service('shareholder_register_dividend.default'); + $c = $s->getDividendContext($object, $distribution_id); + return $c['net']; + } + + /** + * {@inheritdoc} + */ + public function shareholderDividendTax($object, $distribution_id) { + $s = \Drupal::service('shareholder_register_dividend.default'); + $c = $s->getDividendContext($object, $distribution_id); + return $c['tax']; + } + + /** + * {@inheritdoc} + */ + public function shareholderDividendDetails($object, $distribution_id) { + $s = \Drupal::service('shareholder_register_dividend.default'); + $c = $s->getDividendContext($object, $distribution_id); + + $result = [ + '#type' => 'table', + '#header' => [ + 'Aandelen', + 'RV %', + 'Bruto', + 'RV', + 'Netto', + ], + '#rows' => [], + ]; + + $groups = []; + foreach ($c['dividends'] as $dividend) { + if ($details = $dividend->getData('details')) { + foreach ($details as $detail) { + $detail_hash = "{$detail[start_date]}-{$detail[end_date]}-{$detail[taxcode]}-{$detail[tax]}"; + if (!isset($groups[$dividend->id()]['details'][$detail_hash])) { + $groups[$dividend->id()]['details'][$detail_hash] = $detail; + $groups[$dividend->id()]['details'][$detail_hash]['share_ids'] = []; + $groups[$dividend->id()]['dividend'] = $dividend; + } + $groups[$dividend->id()]['details'][$detail_hash]['share_ids'][] = $detail['share_id']; + } + } + } + + foreach ($groups as $dividend) { + $share_details = []; + foreach ($dividend['details'] as $group) { + error_log($group['share_ids']); + $shares = Share::loadMultiple($group['share_ids']); + $share_names = \Drupal::service('shareholder_register.formatter')->sharesToRanges($shares); + $share_details[] = "{$group[start_date]} - {$group[end_date]}: {$share_names}"; + } + + $group = reset($dividend['details']); + + $result['#rows'][] = [ + implode('<br/>', $share_details), + "{$group[tax]} ({$group[taxcode]})", + $dividend['dividend']->get('gross')->value, + bcsub($dividend['dividend']->get('gross')->value, $dividend['dividend']->get('net')->value, 2), + $dividend['dividend']->get('net')->value, + ]; + + } + + return $result; + } +}