work_time-1.0.x-dev/modules/fingerprint/src/Form/FingerprintImportForm.php

modules/fingerprint/src/Form/FingerprintImportForm.php
<?php

namespace Drupal\fingerprint\Form;

use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityDisplayRepositoryInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Provides fingerprint import attendance.
 */
class FingerprintImportForm extends FormBase implements ContainerInjectionInterface {

  /**
   * Entity display repository service.
   *
   * @var \Drupal\Core\Entity\EntityDisplayRepositoryInterface
   */
  public $entityDisplayRepository;

  /**
   * Entity field manager service.
   *
   * @var \Drupal\Core\Entity\EntityFieldManagerInterface
   */
  public $entityFieldManager;

  /**
   * Entity type manager service.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  public $entityTypeManager;

  /**
   * {@inheritdoc}
   */
  public function __construct(EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, EntityDisplayRepositoryInterface $entity_display_repository) {
    $this->entityDisplayRepository = $entity_display_repository;
    $this->entityFieldManager = $entity_field_manager;
    $this->entityTypeManager = $entity_type_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('entity_type.manager'),
      $container->get('entity_field.manager'),
      $container->get('entity_display.repository')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'fingerprint_import';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    if ($form_state->has('page') && $form_state->get('page') == 2) {
      return self::formPageNext($form, $form_state);
    }

    $filename = 'fingerprint-import.csv';
    $options_fields = [
      'uid' => $this->t("User id"),
      'label' => $this->t("Name"),
      'created' => $this->t("Time"),
      'status' => $this->t("State"),
      'note' => $this->t("Exception"),
    ];
    $separate = ',';
    $form['files']['csv_file_upload'] = [
      '#type' => 'managed_file',
      '#title' => $this->t('Choose a file'),
      '#description' => '<a class="btn btn-link button button--small" id="export" data-filename="' . $filename . '" download="' . $filename . '"> ' . "Download CSV template" . ' <i class="bi bi-filetype-csv"></i> : <br/></a>
      <span id="export-header" >' . implode($separate, $options_fields) . '</span>',
      '#required' => TRUE,
      '#upload_validators' => [
        'file_validate_extensions' => ['csv'],
      ],
    ];
    $form['files']['csv_delimiter'] = [
      '#type' => 'select',
      '#title' => $this->t('Character used to separate'),
      '#default_value' => $separate,
      '#options' => [
        ',' => ',',
        ';' => ';',
        'tab' => 'Tab',
      ],
    ];
    array_unshift($options_fields, $this->t('- Select -'));
    if ($fid = $form_state->getValue('csv_file_upload')) {
      $csv_rows = $this->convertCsvArray($fid, 10);
      $header_title = !empty($csv_rows) ? array_shift($csv_rows) : [$this->t('Empty')];
      $header = [];
      $field = [
        '#type' => 'select',
        '#options' => $options_fields,
        '#empty_option' => $this->t('- Select -'),
      ];
      foreach ($header_title as $col => $title_col) {
        $title_col = trim($title_col);
        $header[$col]["data"] = $field;
        $header[$col]["data"]["#title"] = $title_col;
        $header[$col]["data"]["#name"] = 'col[' . $col . ']';
        foreach ($options_fields as $val => $name) {
          if ($title_col == (string) $name) {
            $header[$col]["data"]["#value"] = $val;
          }
        }
      }

      $form['files']['csv_file_upload']['#description'] = [
        '#type' => 'details',
        '#title' => $this->t('Preview'),
        '#open' => TRUE,
        'preview' => [
          '#type' => 'table',
          '#header' => $header,
          '#rows' => !empty($csv_rows) ? $csv_rows : [],
          '#caption' => $this->t('Preview attendance'),
          '#attributes' => ['class' => ['admin-dblog']],
        ],
      ];
    }
    $form['files']['date_format'] = [
      '#type' => 'select',
      '#title' => $this->t('Select format date'),
      '#default_value' => 'd/m/Y',
      '#options' => [
        'd/m/Y' => implode('/', [
          $this->t('Day'),
          $this->t('Month'),
          $this->t('Year'),
        ]),
        'm/d/Y' => implode('/', [
          $this->t('Month'),
          $this->t('Day'),
          $this->t('Year'),
        ]),
      ],
    ];

    $form['#attached'] = [
      'library' => ['fingerprint/export'],
    ];

    $form['actions'] = [
      '#type' => 'actions',
    ];
    $form['actions']['next'] = [
      '#type' => 'submit',
      '#button_type' => 'success',
      '#value' => $this->t('Next'),
      '#submit' => ['::nextCsvSubmit'],
    ];
    return $form;
  }

  /**
   * Step 2 form.
   *
   * @param array $form
   *   An associative array containing the structure of the form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   *
   * @return array
   *   The render array defining the elements of the form.
   */
  public function formPageNext(array &$form, FormStateInterface $form_state) {
    $col = array_flip($form_state->getUserInput()['col']);
    $rows = $this->calculateCsv($form_state->getValue("csv_file_upload"), $col);
    $header = [
      $this->t('uid'),
      $this->t('Name'),
      $this->t('Day'),
      $this->t('Check in'),
      $this->t('Check out'),
      $this->t('Time break'),
      $this->t('Total'),
      $this->t('Night shift'),
      $this->t('Overtime'),
      $this->t('Sunday'),
      $this->t('Holiday'),
      $this->t('Note'),
    ];
    $form['table'] = [
      '#type' => 'table',
      '#caption' => $this->t('Attendance calculate'),
      '#title' => $this->t('Attendance'),
      '#header' => $header,
      '#rows' => $rows,
      '#attributes' => [
        'data-toggle' => "table",
        'data-search' => "true",
        'data-show-refresh' => "true",
        'data-show-toggle' => "true",
        'data-show-fullscreen' => "true",
        'data-click-to-select' => "true",
        'data-show-columns-toggle-all' => "true",
        'data-detail-view' => "true",
        'data-show-columns' => "true",
        'data-show-export' => "true",
        'data-pagination' => "true",
      ],
    ];
    $form['timeline'] = [
      '#type' => 'container',
      '#title' => $this->t('Visualize'),
      '#attributes' => [
        'class' => ['timeline'],
      ],
    ];
    $form['#attached']['library'][] = 'work_time/bootstrapTable';
    $form['#attached']['library'][] = 'fingerprint/fingerprint';
    $form['back'] = [
      '#type' => 'submit',
      '#value' => $this->t('Back'),
      '#submit' => ['::pageBack'],
      '#limit_validation_errors' => [],
    ];
    $form['submit'] = [
      '#type' => 'submit',
      '#button_type' => 'primary',
      '#value' => $this->t('Submit'),
    ];
    return $form;
  }

  /**
   * Button submit back.
   *
   * @param array $form
   *   An associative array containing the structure of the form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   */
  public function pageBack(array &$form, FormStateInterface $form_state) {
    $form_state
      ->set('col', $form_state->get('col'))
      ->set('page', 1)
      ->setRebuild(TRUE);
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    if (!empty($form_state->getValue('csv_file_upload'))) {
      $csv_rows = $this->convertCsvArray($form_state->getValue("csv_file_upload"), 5);
      if (count($csv_rows) < 1) {
        $form_state->setErrorByName('csv_file_upload', $this->t('The list should be at least 1 line.'));
      }
      if (count($csv_rows[0]) < 2 && $csv_rows[0][0] != 'Email' && $csv_rows[0][1] != 'First name' && $csv_rows[0][0] != 'Last name') {
        $form_state->setErrorByName('csv_file_upload', $this->t('The file csv is not compatible.'));
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function nextCsvSubmit(array &$form, FormStateInterface $form_state) {
    $form_state->set('page', 2)->setRebuild(TRUE);
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $this->messenger()
      ->addStatus($this->t('The fingerprint has been imported.'));
    $form_state->setRedirect('fingerprint.list');
  }

  /**
   * {@inheritDoc}
   */
  protected function getFile($fid) {
    if (is_array($fid)) {
      $fid = end($fid);
    }
    $file = $this->entityTypeManager->getStorage('file')->load($fid);
    if (empty($file)) {
      return FALSE;
    }
    return $file->get('uri')->value;
  }

  /**
   * {@inheritDoc}
   */
  protected function getDelimiter($row, &$delimiter = ',') {
    $line = explode($delimiter, $row);
    if (count($line) <= 1) {
      $delimiters = [',', ';', "\t"];
      foreach ($delimiters as $delimiter) {
        $line = explode($delimiter, $row);
        if (count($line) > 1) {
          break;
        }
      }
    }
    return $line;
  }

  /**
   * {@inheritDoc}
   */
  protected function convertTimestamp($date, $formatDay = 'd/m/Y') {
    $date = str_replace(['/', '.'], '-', $date);
    // Convert format US month day Year.
    if ($formatDay == 'm/d/Y H:i') {
      $extract = explode('-', $date);
      $temp = $extract[0];
      $extract[0] = $extract[1];
      $extract[1] = $temp;
      $date = implode('-', $extract);
    }
    return strtotime($date);
  }

  /**
   * {@inheritDoc}
   */
  public function calculateCsv($fid, $col) {
    $filename = $this->getFile($fid);
    if (($f = fopen($filename, "r")) !== FALSE) {
      $line = trim(fgets($f));
      $delimiter = ',';
      $this->getDelimiter($line, $delimiter);
      $label = $lines = [];
      $formatDay = 'd/m/Y';
      if (!ini_get('auto_detect_line_endings')) {
        ini_set('auto_detect_line_endings', TRUE);
      }
      $processService = \Drupal::service('fingerprint.process_services');
      $workingHours = $processService->getShifts();
      $margin = 30 * 60;
      while (($data = fgetcsv($f, 0, $delimiter)) !== FALSE) {
        $uid = $data[$col['uid']] ?? '';
        $date = $data[$col['created']] ?? '';
        $label[$uid] = $data[$col['label']] ?? '';
        if (empty($uid) || empty($date)) {
          continue;
        }
        $date = $this->convertTimestamp($date, $formatDay);
        $lines[$uid][] = $date;
      }
      fclose($f);
      if (!empty($lines)) {
        $calculated = [];
        $fingerprintStorage = $this->entityTypeManager->getStorage('fingerprint');

        foreach ($lines as $uid => $attendance) {
          sort($attendance);
          $date = $processService->processTimeRecords($attendance, $workingHours, $margin);
          foreach ($date as $day => $process) {
            $calculated[] = [
              'uid' => $uid,
              'label' => $label[$uid],
              'date' => date($formatDay, strtotime($day)),
              'checkin' => $process['checkin'],
              'checkout' => $process['checkout'],
              'lunch' => $process['lunch'],
              'total' => $process['total'],
              'night' => $process['night'],
              'over_time' => $process['over_time'],
              'sunday' => $process['sunday'],
              'holiday' => $process['holiday'],
              'description' => $process['description'],
            ];

            $query = \Drupal::entityQuery('fingerprint');
            $query->condition('uid', $uid);
            $query->condition('created', $process['check_in']);
            $fingerprint_ids = $query->execute();
            if (empty($fingerprint_ids)) {
              $fingerprint = $fingerprintStorage->create([
                'label' => $label[$uid],
                'uid' => $uid,
                'created' => $process['created'],
                'stopped' => $process['stopped'],
                'time_total' => $process['time_total'],
                'description' => $process['description'],
                'break' => $process['break'],
              ]);
              $fingerprint->save();
            }
          }
        }
        return $calculated;
      }
      return $lines;
    }
  }

  /**
   * {@inheritDoc}
   */
  public function convertCsvArray($fid, $limit = FALSE) {
    $filename = $this->getFile($fid);
    if (($f = fopen($filename, "r")) !== FALSE) {
      $line = trim(fgets($f));
      $delimiter = ',';
      $csv_rows = [$this->getDelimiter($line, $delimiter)];
      $i = 0;
      if (!ini_get('auto_detect_line_endings')) {
        ini_set('auto_detect_line_endings', TRUE);
      }
      while (($data = fgetcsv($f, 0, $delimiter)) !== FALSE) {
        $csv_rows[] = $data;
        if ($limit && $i++ > $limit) {
          break;
        }
      }
      fclose($f);
      return $csv_rows;
    }
    return FALSE;
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc