PaymentRequestItem.php

PHOTO EMBED

Mon Oct 10 2022 16:41:42 GMT+0000 (Coordinated Universal Time)

Saved by @igor #drupal #mysql

<?php

namespace Drupal\cfp_payment_request\Entity;

use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Entity\EntityChangedTrait;
use Drupal\Core\Entity\EntityPublishedTrait;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\pos_core\PosFieldVariables;
use Drupal\pos_entity_autocalculate\AutoCalculateFormula;
use Drupal\pos_entity_autocalculate\Entity\AutocalculateEntityTrait;
use Drupal\pos_entity_cost_item\AdditionalCostItem;
use Drupal\pos_entity_cost_item\Entity\CostItemAcceptableInterface;
use Drupal\pos_parent_entity\Entity\ChildEntityTrait;
use Drupal\user\UserInterface;

/**
 * Defines the Payment request item entity.
 *
 * @ingroup cfp_payment_request
 *
 * @ContentEntityType(
 *   id = "cfp_payment_request_item",
 *   label = @Translation("Payment request item"),
 *   bundle_label = @Translation("Payment request item type"),
 *   handlers = {
 *     "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
 *     "list_builder" = "Drupal\cfp_payment_request\PaymentRequestItemListBuilder",
 *     "views_data" = "Drupal\cfp_payment_request\Entity\PaymentRequestItemViewsData",
 *
 *     "form" = {
 *       "default" = "Drupal\cfp_payment_request\Form\PaymentRequestItemForm",
 *       "add" = "Drupal\cfp_payment_request\Form\PaymentRequestItemForm",
 *       "edit" = "Drupal\cfp_payment_request\Form\PaymentRequestItemForm",
 *       "delete" = "Drupal\cfp_payment_request\Form\PaymentRequestItemDeleteForm",
 *     },
 *     "route_provider" = {
 *       "html" = "Drupal\cfp_payment_request\PaymentRequestItemHtmlRouteProvider",
 *     },
 *     "access" = "Drupal\cfp_payment_request\PaymentRequestItemAccessControlHandler",
 *     "inline_form" = "\Drupal\cfp_payment_request\Form\PaymentRequestItemInlineForm",
 *   },
 *   base_table = "cfp_payment_request_item",
 *   translatable = FALSE,
 *   admin_permission = "administer payment request item entities",
 *   entity_keys = {
 *     "id" = "id",
 *     "bundle" = "type",
 *     "uuid" = "uuid",
 *     "uid" = "user_id",
 *     "langcode" = "langcode",
 *     "published" = "status",
 *   },
 *   links = {
 *     "canonical" = "/admin/structure/cfp_payment_request_item/{cfp_payment_request_item}",
 *     "add-page" = "/admin/structure/cfp_payment_request_item/add",
 *     "add-form" = "/admin/structure/cfp_payment_request_item/add/{cfp_payment_request_item_type}",
 *     "edit-form" = "/admin/structure/cfp_payment_request_item/{cfp_payment_request_item}/edit",
 *     "delete-form" = "/admin/structure/cfp_payment_request_item/{cfp_payment_request_item}/delete",
 *     "collection" = "/admin/structure/cfp_payment_request_item",
 *   },
 *   bundle_entity_type = "cfp_payment_request_item_type",
 *   field_ui_base_route = "entity.cfp_payment_request_item_type.edit_form"
 * )
 */
class PaymentRequestItem extends ContentEntityBase implements PaymentRequestItemInterface {

  use EntityChangedTrait;
  use EntityPublishedTrait;
  use ChildEntityTrait;
  use AutocalculateEntityTrait {
    preSave as autoCalculatePreSave;
    addFormulas as autoCalculateAddFormulas;
  }

  /**
   * {@inheritdoc}
   */
  public static function preCreate(EntityStorageInterface $storage_controller, array &$values) {
    parent::preCreate($storage_controller, $values);
    $values += [
      'user_id' => \Drupal::currentUser()->id(),
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function preSave(EntityStorageInterface $storage) {
    parent::preSave($storage);
    if ($this->getPRIType()->arePricesInCurrencies()) {
      if (($currency = $this->getCurrency()) && ($currency_date = $this->getCurrencyDate())) {
        if ($exchange_rate = self::getExchangeRate($currency, $currency_date)) {
          $this->populateValuesWithExchange($exchange_rate);
        }
      }
      $this->autoCalculatePreSave($storage);
    } else {
      $this->autoCalculatePreSave($storage);
    }
    if ($this->get('accepted')->value !== 'accepted_with_new_value') {
      $this->set('new_item_pay_off', NULL)
        ->set('new_item_support', NULL);
    }
  }

  /**
   * {@inheritDoc}
   * Some computed field directly depend on another field, and we need to access
   *   it right after.
   */
  public function onChange($name) {
    parent::onChange($name);
    $field_influence_connection = [
      'accepted' => ['item_pay_off_computed', 'item_support_computed'],
      'item_pay_off' => ['item_pay_off_computed'],
      'new_item_pay_off' => ['item_pay_off_computed'],
      'new_item_support' => ['item_support_computed'],
      'item_support' => ['item_support_computed'],
    ];
    foreach ($field_influence_connection[$name] ?? [] as $field_influence) {
      $this->get($field_influence)->forceRecomputeValue();
    }
  }

  /**
   * @param $exchange_value
   */
  public function populateValuesWithExchange($exchange_value) {
    $exchange_value = (float) $exchange_value;
    foreach ($this->getFieldDefinitions() as $field_definition) {
      if (strpos($field_definition->getName(), '_currency_value') !== FALSE) {
        $value = $this->get($field_definition->getName())->value;
        if ($value) {
          $forint_field_name = str_replace('_currency_value', '', $field_definition->getName());
          $this->set($forint_field_name, bcmul($value, $exchange_value));
        } elseif(is_numeric($value)) {
          $forint_field_name = str_replace('_currency_value', '', $field_definition->getName());
          $this->set($forint_field_name, 0);
        } else {
          $this->set($forint_field_name, NULL);
        }
      }
    }
  }

  public static function getExchangeRate($currency, $currency_date) {
    if ($currency === 'HUF') {
      return 1;
    }
    $exchange_rate = str_replace(',', '.', _get_mnb_currency_value($currency, $currency_date));
    return is_numeric($exchange_rate) ? $exchange_rate : NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function getName() {
    return $this->get('name')->value;
  }

  /**
   * {@inheritdoc}
   */
  public function setName($name) {
    $this->set('name', $name);
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function getCreatedTime() {
    return $this->get('created')->value;
  }

  /**
   * {@inheritdoc}
   */
  public function setCreatedTime($timestamp) {
    $this->set('created', $timestamp);
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function getOwner() {
    return $this->get('user_id')->entity;
  }

  /**
   * {@inheritdoc}
   */
  public function getOwnerId() {
    return $this->get('user_id')->target_id;
  }

  /**
   * {@inheritdoc}
   */
  public function setOwnerId($uid) {
    $this->set('user_id', $uid);
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function setOwner(UserInterface $account) {
    $this->set('user_id', $account->id());
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function label() {
    return $this->getName();
  }

  /**
   * Payment request item type.
   *
   * @return \Drupal\cfp_payment_request\Entity\PaymentRequestItemType
   */
  public function getPRIType() {
    return PaymentRequestItemType::load($this->bundle());
  }

  /**
   * @return mixed
   */
  public function getCurrency() {
    $currency = $this->get('currency')->value;
    return $currency;
  }

  /**
   *
   */
  public function getCurrencyDate() {
    if (!$this->get('currency_date')->isEmpty()) {
      return $this->get('currency_date')->date->format(CURRENCY_DATE_FORMAT);
    }
  }

  /**
   * Cost item identifier.
   *
   * @return string
   *   Identifier of item.
   */
  public function getCostItemIdentifier() {
    return $this->get('cost_item_name')->value;
  }

  /**
   * Returns accepted state.
   *
   * @return string
   *   Accepted state.
   */
  public function getAcceptedState() {
    return $this->get('accepted')->value;
  }

  /**
   * {@inheritdoc}
   */
  public function addFormulas() {
    $this->autoCalculateAddFormulas();
    if ($this->getPRIType()->arePricesInCurrencies()) {
      // Currency values.
      $this->addAutoCalculateFormula('item_net_amount_currency_value', AutoCalculateFormula::create()
        ->addFieldWithOperation('item_net_unit_currency_value')
        ->multiplyField('item_quantity'));

      $this->addAutoCalculateFormula('item_vat_currency_value', AutoCalculateFormula::create()
        ->addFieldWithOperation('item_unit_vat_currency_value')
        ->multiplyField('item_quantity')
      );

      $this->addAutoCalculateFormula('item_bruto_currency_value', AutoCalculateFormula::create()
        ->addFieldWithOperation('item_net_amount_currency_value')
        ->addField('item_vat_currency_value')
      );

    }

    // Forint values.
    $this->addAutoCalculateFormula('item_net_amount', AutoCalculateFormula::create()
      ->addFieldWithOperation('item_net_unit')
      ->multiplyField('item_quantity'));

    $this->addAutoCalculateFormula('item_vat', AutoCalculateFormula::create()
      ->addFieldWithOperation('item_unit_vat')
      ->multiplyField('item_quantity')
    );

    $this->addAutoCalculateFormula('item_bruto', AutoCalculateFormula::create()
      ->addFieldWithOperation('item_net_amount')
      ->addField('item_vat')
    );

    $this->addAutoCalculateFormula('item_support_percentage', AutoCalculateFormula::create()
      ->addField('item_support')
      ->divideField('item_pay_off')
      ->addNumberWithOperation(100, AutoCalculateFormula::MULTIPLY)
    );

    $this->addAutoCalculateFormula('item_own_source', AutoCalculateFormula::create()
      ->addFieldWithOperation('item_pay_off')
      ->subtractField('item_support'));

    $this->addAutoCalculateFormula('item_bruto_unit', AutoCalculateFormula::create()
      ->addFieldWithOperation('item_bruto')
      ->divideField('item_quantity')
    );
  }

  /**
   * {@inheritDoc}
   */
  public static function bundleFieldDefinitions(EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) {
    $fields = [];
    if ($bundle) {
      /** @var \Drupal\cfp_payment_request\Entity\PaymentRequestItemType $pri_type */
      $pri_type = \Drupal::entityTypeManager()
        ->getStorage('cfp_payment_request_item_type')
        ->load($bundle);
      if ($pri_type) {
        $prices_in_currencies = $pri_type->arePricesInCurrencies();
        foreach ($base_field_definitions as $field_name => $base_field_definition) {
          if (strpos($field_name, '_currency_value') !== FALSE) {
            if (!$prices_in_currencies) {
              $fields[$field_name] = clone $base_field_definition;
              $fields[$field_name]->setDisplayConfigurable('form', FALSE)
                ->setDisplayConfigurable('view', FALSE);
            }
            else {
              $basic_field_name = str_replace('_currency_value', '', $field_name);
              $fields[$basic_field_name] = clone $base_field_definitions[$basic_field_name];
              $fields[$basic_field_name]->setDisplayConfigurable('form', FALSE);
            }
          }
        }
      }
    }

    return $fields;

  }

  /**
   * {@inheritdoc}
   */
  public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
    $fields = parent::baseFieldDefinitions($entity_type);

    // Add the published field.
    $fields += static::publishedBaseFieldDefinitions($entity_type);

    $fields['user_id'] = BaseFieldDefinition::create('entity_reference')
      ->setLabel(t('Authored by'))
      ->setDescription(t('The user ID of author of the Payment request item entity.'))
      ->setRevisionable(TRUE)
      ->setSetting('target_type', 'user')
      ->setSetting('handler', 'default')
      ->setDisplayConfigurable('form', TRUE)
      ->setDisplayConfigurable('view', TRUE);

    $fields['name'] = BaseFieldDefinition::create('string')
      ->setLabel(t('Tétel sorszáma'))
      ->setDescription(t('The name of the Payment request item entity.'))
      ->setSettings([
        'max_length' => 50,
        'text_processing' => 0,
      ])
      ->setDefaultValue('')
      ->setDisplayConfigurable('view', TRUE);

    $fields['cost_item_name'] = BaseFieldDefinition::create('list_string')
      ->setLabel('Stavka na koju se isplata odnosi')
      ->setSetting('allowed_values_function', '\Drupal\cfp_payment_request\Entity\PaymentRequestItem::itemNames')
      ->setDisplayConfigurable('form', TRUE)
      ->setDisplayConfigurable('view', TRUE);
    // NUMERIC FIELDS.
    $numeric_fields = [
      'item_net_unit' => 'Neto jedinična cijena',
      'item_unit_vat' => 'PDV po neto jediničnoj cijeni',
      'item_bruto_unit' => 'Jedinična bruto cijena',
      'item_quantity' => 'Količina',
      'item_pay_off' => 'Prihvatljivi trošak nabavke artikla',
      'item_support' => 'Iznos bespovratnih sredstava koji tražite za artikal (EUR)',
      'item_net_amount' => 'Neto ukupni trošak nabavke artikla (EUR)',
      'item_vat' => 'Ukupan PDV',
      'item_bruto' => 'Bruto ukupni trošak nabavke artikla (EUR)',
      'item_own_source' => 'Iznos sopstvenog učešća (EUR)',
    ];
    $exception_numeric_field_names = [
      'item_quantity',
      'item_pay_off',
      'item_support',
      'item_own_source',
    ];
    foreach ($numeric_fields as $numeric_field_machine_name => $numeric_field) {
      $fields[$numeric_field_machine_name] = BaseFieldDefinition::create($numeric_field_machine_name === 'item_quantity' ? 'integer' : 'decimal')
        ->setLabel($numeric_field)
        ->setSettings([
          'precision' => 12,
          'scale' => 2,
          'suffix' => '€',
        ])
        ->setDisplayConfigurable('form', TRUE)
        ->setDisplayConfigurable('view', TRUE);
      if (!in_array($numeric_field_machine_name,  $exception_numeric_field_names)) {
        $fields[$numeric_field_machine_name .'_currency_value'] = BaseFieldDefinition::create('decimal')
          ->setLabel(str_replace(' (Ft)', '', $numeric_field))
          ->setSettings([
            'precision' => 12,
            'scale' => 2,
          ])
          ->setDisplayConfigurable('form', TRUE)
          ->setDisplayConfigurable('view', TRUE);
      }
    }

    $fields['new_item_pay_off'] = BaseFieldDefinition::create('decimal')
      ->setLabel('New payoff')
      ->setSettings([
        'precision' => 12,
        'scale' => 2,
        'suffix' => '€',
      ]);

    $fields['new_item_support'] = BaseFieldDefinition::create('decimal')
      ->setLabel('New Support')
      ->setSettings([
        'precision' => 12,
        'scale' => 2,
        'suffix' => '€',
      ]);

    $fields['currency'] = BaseFieldDefinition::create('list_string')
      ->setLabel(t('Currency'))
      ->setSetting('allowed_values_function', '_get_mnb_currencies')
      ->setDisplayConfigurable('form', TRUE)
      ->setDisplayConfigurable('view', TRUE);

    $fields['currency_date'] = BaseFieldDefinition::create('datetime')
      ->setLabel(t('Currency date'))
      ->setSettings([
        'datetime_type' => 'date',
      ])
      ->setDisplayConfigurable('form', TRUE)
      ->setDisplayConfigurable('view', TRUE);

    $fields['item_support_percentage'] = BaseFieldDefinition::create('decimal')
      ->setLabel('Postotak bespovratnih sredstava koji tražite (%)')
      ->setSettings([
        'prefix' => '',
        'suffix' => '%',
      ])
      ->setSettings(PosFieldVariables::PERCENTAGE_DEFAULT_FIELD_SETTINGS)
      ->setDisplayConfigurable('form', TRUE)
      ->setDisplayConfigurable('view', TRUE);

    $fields['item_pay_off_computed'] = BaseFieldDefinition::create('decimal')
      ->setLabel('Ügyintéző által jóváhagyott elszámolható költség')
      ->setComputed(TRUE)
      ->setClass('\Drupal\cfp_payment_request\Plugin\Field\ItemPayOffComputedFieldItemList')
      ->setDisplayConfigurable('view', TRUE);

    $fields['item_support_computed'] = BaseFieldDefinition::create('decimal')
      ->setLabel('Ügyintéző által jóváhagyott támogatási összeg')
      ->setComputed(TRUE)
      ->setClass('\Drupal\cfp_payment_request\Plugin\Field\ItemSupportComputedFieldItemList')
      ->setDisplayConfigurable('view', TRUE);

    $fields['supplier'] = BaseFieldDefinition::create('entity_reference')
      ->setLabel(t('Supplier'))
      ->setSetting('target_type', 'supplier')
      ->setSetting('handler', 'default:supplier')
      ->setDisplayConfigurable('form', TRUE)
      ->setDisplayConfigurable('view', TRUE);

    $fields['accepted'] = BaseFieldDefinition::create('list_string')
      ->setLabel(t('Status'))
      ->setDefaultValue('accepted')
      ->setInitialValue('accepted')
      ->setSetting('allowed_values', PaymentRequestItem::getAllowedAcceptedValues())
      ->setDisplayConfigurable('view', TRUE);

    $fields['status']->setDescription(t('A boolean indicating whether the Payment request item is published.'));

    $fields['created'] = BaseFieldDefinition::create('created')
      ->setLabel(t('Created'))
      ->setDescription(t('The time that the entity was created.'));

    $fields['changed'] = BaseFieldDefinition::create('changed')
      ->setLabel(t('Changed'))
      ->setDescription(t('The time that the entity was last edited.'));

    return $fields;
  }

  public static function getAllowedAcceptedValues() {
    return [
      'rejected' => t('Rejected'),
      'accepted' => t('Accepted'),
      'accepted_with_new_value' => t('Accepted with new value'),
    ];
  }

  /**
   * Get item names.
   *
   * @param \Drupal\Core\Field\FieldStorageDefinitionInterface $definition
   *   Field definition.
   * @param \Drupal\Core\Entity\ContentEntityInterface|null $entity
   *   Content entity.
   *
   * @return array
   *   Item names.
   */
  public static function itemNames(FieldStorageDefinitionInterface $definition = NULL, ContentEntityInterface $entity = NULL) {
    if ($parent = $entity->getParent()) {
      /** @var \Drupal\pos_payment_request\Entity\PaymentRequest $parent */
      if ($parent_cfp = $parent->get('parent')->entity) {
        /** @var \Drupal\pos_entity_cost_item\Entity\CostItemsParentEntityInterface $parent_cfp */
        $additional_options= array_filter(array_map(function (CostItemAcceptableInterface $cost_item) {
          if ($cost_item->isNewTotalSupportDefined() || $cost_item->isAccepted()) {
            return $cost_item->getName();
          }
        }, $parent_cfp->getCostItemEntities()));
        foreach ($parent_cfp->getAdditionalCostItems() as $key => $cost_item) {
          $additional_options["additional_cost_item_$key"] = $cost_item['name'];
        }
        return $additional_options;
      }
    }
    return [];
  }

  /**
   * @return array
   */
  public function getItemsCriteria() {
    if ($parent = $this->getParent()) {
      /** @var \Drupal\pos_payment_request\Entity\PaymentRequest $parent */
      if ($parent_cfp = $parent->get('parent')->entity) {
        /** @var \Drupal\pos_entity_cost_item\Entity\CostItemsParentEntityInterface $parent_cfp */
        $additional_options= array_filter(array_map(function (CostItemAcceptableInterface $cost_item) {
          if ($cost_item->isNewTotalSupportDefined() || $cost_item->isAccepted()) {
            return new AdditionalCostItem([
              'name' => $cost_item->getName(),
              'value' => $cost_item->getAcceptedTotalSupport(),
              'own_contribution_value' => $cost_item->getAcceptedOwnContribution(),
            ]);
          }
        }, $parent_cfp->getCostItemEntities()));
        foreach ($parent_cfp->getAdditionalCostItems() as $key => $cost_item) {
          $additional_options["additional_cost_item_$key"] = $cost_item;
        }
        return $additional_options;
      }
    }
  }

}
content_copyCOPY