<?php
/**
* Created by IntelliJ IDEA.
* User: stefano
* Date: 29/05/17
* Time: 16.59
*/
namespace App\AppBundle\Twig;
use App\AppBundle\Annotations\Frontend;
use App\AppBundle\Entity\CronJob;
use App\AppBundle\Entity\Currency;
use App\AppBundle\Entity\Log;
use App\AppBundle\Entity\MvMycmMyamsDealerGroup;
use App\AppBundle\Entity\MyamsUserProfile;
use App\AppBundle\Entity\User;
use App\AppBundle\Repository\CountryRepository;
use App\AppBundle\Repository\MacroDealerRepository;
use App\AppBundle\Repository\UserRepository;
use App\AppBundle\Controller\DefaultController;
use App\AppBundle\Entity\Application_Data;
use App\AppBundle\Other\Constants;
use App\AppBundle\Services\ImportService;
use App\AppBundle\Services\ThemeService;
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\NoResultException;
use EasyCorp\Bundle\EasyAdminBundle\Configuration\ConfigManager;
use EasyCorp\Bundle\EasyAdminBundle\Twig\EasyAdminTwigExtension;
use ReflectionClass;
use Symfony\Component\HttpFoundation\ParameterBag;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Twig\TwigFunction;
class UserTwigExtension extends EasyAdminTwigExtension
{
// import tabs
const TYPE_CUSTOMER = "customer";
const TYPE_SELLOUT = "sellout";
const TYPE_CUSTOMER_PARK = "park";
const potentialTabs = ["PSD_Potential", "PSD_Potential_Technicians", "PSD_Customer"];
private ConfigManager $configManager;
private EntityManager $em;
private AuthorizationCheckerInterface $authChecker;
private ThemeService $themeService;
private ContainerInterface $container;
private ArrayCollection $checks;
private ImportService $importService;
public function __construct(ConfigManager $configManager, EntityManager $em, AuthorizationCheckerInterface $ac, ThemeService $themeService, ContainerInterface $container)
{
$this->configManager = $configManager;
$this->em = $em;
$this->authChecker = $ac;
$this->themeService = $themeService;
$this->container = $container;
$this->checks = new ArrayCollection();
$this->importService = $container->get(ImportService::class);
}
public function getFunctions()
{
return array(
new TwigFunction('get_countries', array($this, 'getCountries')),
new TwigFunction('get_macro_dealers', array($this, 'getMacroDealers')),
new TwigFunction('get_macro_dealers_codes', array($this, 'getMacroDealersCodes')),
new TwigFunction('get_countries_in_macrodealer', array($this, 'getCountriesInMacrodealers')),
new TwigFunction('get_allowed_macro_dealers', array($this, 'getAllowedMacroDealers')),
new TwigFunction('get_warehouses', array($this, 'getWarehouse')),
new TwigFunction('get_last_import_date', array($this, 'getLastImportDate')),
new TwigFunction('is_import_in_progress', array($this, 'isImportInProgress')),
new TwigFunction('last_job_exec', array($this, 'getLastJob')),
new TwigFunction('get_currencies', array($this, 'getCurrencies')),
new TwigFunction('get_current_currency_description', array($this, 'getCurrentCurrencyDescription')),
new TwigFunction('get_current_macro_dealer_group_label', array($this, 'getCurrentMacroDealerGroupLabel')),
new TwigFunction('pdf_labels', array($this, 'PDFLabels')),
new TwigFunction('contextual_help', array($this, 'getContextualHelp')),
new TwigFunction('get_macro_datasets', array($this, 'getMacroDatasets')),
new TwigFunction('search_in_array_objects', array($this, 'searchInArrayObjects')),
new TwigFunction('get_user_by_username', array($this, 'getUserByUsername')),
new TwigFunction('get_theme_file_name', array($this, 'getThemeFileName')),
new TwigFunction('get_theme_brand_name', array($this, 'getThemeBrandName')),
new TwigFunction('get_theme_brand_code', array($this, 'getSelectedBrandCodes')),
new TwigFunction('get_switch_to_old', array($this, 'getSwitchToOld')),
new TwigFunction('get_default_url', array($this, 'getDefaultUrl')),
new TwigFunction('get_enable_user_edit', array($this, 'getEnableUserEdit')),
new TwigFunction('get_access_to_new', array($this, 'getAccessToNew')),
new TwigFunction('get_access_to_old', array($this, 'getAccessToOld')),
new TwigFunction('get_sellout_enabled', array($this, 'getSelloutEnabled')),
new TwigFunction('get_label_bulkedit_enabled', array($this, 'getLabelBulkEditEnabled')),
new TwigFunction('get_label_management_enabled', array($this, 'getLabelManagementEnabled')),
new TwigFunction('get_dashboard_enabled', array($this, 'getDashboardEnabled')),
new TwigFunction('get_sellin_enabled', array($this, 'getSellinEnabled')),
new TwigFunction('get_advanced_analytics_enabled', array($this, 'getAdvancedAnalyticsEnabled')),
new TwigFunction('get_stock_and_logistics_enabled', array($this, 'getStockAndLogisticsEnabled')),
new TwigFunction('get_take_rate_enabled', array($this, 'getTakeRateEnabled')),
new TwigFunction('get_prim_enabled', array($this, 'getPrimEnabled')),
new TwigFunction('get_portfolio_enabled', array($this, 'getPortfolioEnabled')),
new TwigFunction('get_distinct_brands', array($this, 'getDistinctBrands')),
new TwigFunction('get_brands', array($this, 'getBrands')),
new TwigFunction('get_dealerships', array($this, 'getDealerships')),
new TwigFunction('get_dealer_groups', array($this, 'getDealerGroups')),
new TwigFunction('get_unique_id', array($this, 'getUniqId')),
new TwigFunction('one_time', array($this, 'oneTime')),
new TwigFunction('get_exposable_entities', array($this, 'getExposableEntities')),
new TwigFunction('get_exposable_entity', array($this, 'getExposableEntity')),
new TwigFunction('get_exposable_name', array($this, 'getExposableName')),
new TwigFunction('is_single_dealership_user', array($this, 'isSingleDealershipUser')),
new TwigFunction('is_user_edit_enabled', array($this, 'isUserEditEnabled')),
new TwigFunction('has_not_connected_dealer_groups', array($this, 'hasNotConnectedDealerGroups')),
new TwigFunction('get_import_tabs', array($this, 'getImportTabs')),
new TwigFunction('get_potential_tabs', array($this, 'getPotentialTabs')),
new TwigFunction('get_full_user', array($this, 'getFullUser')),
new TwigFunction('get_mib_roles', array($this, 'getMibRoles')),
);
}
public function getPotentialTabs(User $user = null) {
$authChecker = $this->container->get('security.authorization_checker');
$tabs = [];
if($authChecker->isGranted('ROLE_GRANT_POTENTIALS')){
$tabs = self::potentialTabs;
}
return $tabs;
}
public function getPortfolioEnabled(User $user = null)
{
return (!$user) ? false : $this->isEnablePortfolio($user);
}
public function getMibRoles()
{
return json_encode(Constants::MIB_ROLES);
}
public function getPrimEnabled(User $user = null){
return (!$user) ? false : $user->isEnablePrim() && $_ENV['ENABLE_PRIM'] === "true";
}
public function getEnableUserEdit(User $user = null){
return (!$user) ? false : $user->isEnableUserEdit();
}
public function getSelloutEnabled(User $user = null){
return (!$user) ? false : $user->isEnableSellout() && $_ENV['ENABLE_SELLOUT'] === "true";
}
public function getLabelBulkEditEnabled(User $user = null) {
return (!$user) ? false : $user->getEnableLabelBulkEdit();
}
public function getLabelManagementEnabled(User $user = null) {
if(!$user)
return false;
/** @var Application_DataRepository $applicationDataRepository */
$applicationDataRepository = $this->em->getRepository(Application_Data::class);
$users = $applicationDataRepository->getValueFromKey('LABEL_MANAGEMENT_ALLOWED_USERS');
if(!$users)
return false;
$users = explode(",", $users["value"]);
$users = array_map('trim', $users);
return in_array($user->getUsername(), $users);
}
public function getDashboardEnabled(User $user = null){
return (!$user) ? false : $user->getEnableDashboard();
}
public function getSellinEnabled(User $user = null){
return (!$user) ? false : $user->getEnableSellIn();
}
public function getAdvancedAnalyticsEnabled(User $user = null){
return (!$user) ? false : $user->getEnableAdvancedAnalytics();
}
public function getStockAndLogisticsEnabled(User $user = null){
return (!$user) ? false : $user->getEnableStockAndLogistics();
}
public function getTakeRateEnabled(User $user = null){
return (!$user) ? false : $user->getEnableTakeRate();
}
public function getSwitchToOld(User $user = null){
return (!$user) ? false : $user->getSwitchToOld();
}
public function getDefaultUrl(User $user = null) {
$menu = $this->configManager->getBackendConfig('design')['menu'];
$authChecker = $this->container->get('security.authorization_checker');
if($authChecker->isGranted('ROLE_GRANT_DASHBOARD')) {
if ($user && !$user->getDefaultUrl()) {
$user->setDefaultUrl($menu);
}
return (!$user) ? false : $user->getDefaultUrl();
} else {
return '/admin/?action=list&entity=User';
}
}
public function getAccessToNew(User $user = null){
return (!$user) ? false : $user->getAccessToNew();
}
public function getAccessToOld(User $user = null){
return (!$user) ? false : $user->getAccessToOld();
}
// Theme selection (CSS and top logo)
public function getThemeBrandName(User $user = null){
return $this->themeService->getTheme($user)->getFullname();
}
public function getThemeFileName(User $user = null){
return $this->themeService->getTheme($user)->getFilepath();
}
public function getImportTabs(User $user = null) {
$authChecker = $this->container->get('security.authorization_checker');
$tabs = [];
if($authChecker->isGranted('ROLE_GRANT_IMPORTER_SELLOUT') && $this->hasNotConnectedDealerGroups($user))
$tabs[] = self::TYPE_SELLOUT;
if($authChecker->isGranted('ROLE_GRANT_IMPORTER_CUSTOMER'))
$tabs[] = self::TYPE_CUSTOMER;
if($authChecker->isGranted('ROLE_GRANT_IMPORTER_PARK'))
$tabs[] = self::TYPE_CUSTOMER_PARK;
return $tabs;
}
// Brand selector
public function getSelectedBrandCodes(User $user = null) {
$brandRepository = $this->em->getRepository('AppBundle:Brand');
$brands = $user->getSelectedBrands();
// select first brand by default
if(!$brands) {
$brands = $brandRepository->getBrandList($user);
$brands = reset($brands);
if(!$brands) {
return null;
}
$brands = $brands["id"];
// Made selection persist
$user->setSelectedBrands($brands);
$this->em->flush($user);
$this->em->persist($user);
}
$brands = explode(',', $brands);
$brands = $brandRepository->findBy(array('id' => $brands));
$brands = array_map(function($brand) {
return $brand->getCode();
}, $brands);
return implode(",", $brands);
}
public function getDistinctBrands(User $user = null){
$brandRepository = $this->em->getRepository('AppBundle:Brand');
$brandlist=$brandRepository->getBrandDistinctList();
return $brandlist;
}
public function getBrands(User $user = null){
$brandRepository = $this->em->getRepository('AppBundle:Brand');
$brandlist=$brandRepository->getBrandList($user);
return $brandlist;
}
public function getFullUser($username)
{
$userRepository = $this->em->getRepository('AppBundle:User');
$user = $userRepository ->findOneByUsername($username);
return $user->getFullUsername();
}
public function getUserByUsername($username)
{
$userRepository = $this->em->getRepository('AppBundle:User');
return $userRepository ->findOneByUsername($username);
}
public function getLastJob()
{
$cronRepo = $this->em->getRepository('AppBundle:CronJob');
/** @var CronJob $job */
$job = $cronRepo->findOneBy(array("active" => 1), array("lastRunAt" => 'DESC'));
$lastRun = $job ? $job->getLastRunAt() : new \DateTime();
return $lastRun->format('Y-m-d H:i:s');
}
public function getCountries(User $user)
{
if(!$user->getCountries()->isEmpty()){
$countries= $user->getCountries();
}else{
/** @var CountryRepository $countryRepo */
$countryRepo = $this->em->getRepository('AppBundle:Country');
$countries = $countryRepo->findBy(array(), array('description' => 'ASC'));
}
return $countries;
}
public function getMacroDealers(User $user)
{
$country = $user->getSelectedCountry();
/** @var MacroDealerRepository $macroDealerRepo */
$macroDealerRepo = $this->em->getRepository('AppBundle:MacroDealer');
$macroDealers = $macroDealerRepo->findBy(array(
"country" => $country
),
array('description' => 'ASC')
);
return $macroDealers;
}
public function getMacroDealersCodes(User $user){
/** @var ArrayCollection $mds */
$mds =$user->getMacroDealers();
return $mds->map(function ($macrodealer){
return $macrodealer->getCode();
});
}
public function getCountriesInMacrodealers(User $user) {
/** @var MacroDealerRepository $macroDealerRepo */
$macroDealerRepo = $this->em->getRepository('AppBundle:MacroDealer');
$countries= $macroDealerRepo->getCountriesInMacrodealers($user->getMacroDealers());
return $countries;
}
public function getAllowedMacroDealers(User $user){
$country = $user->getSelectedCountry();
return $user->getMacroDealers()
->filter(
function($entry) use ($country) {
return $entry->getCountry() == $country;
}
);
}
public function getWarehouse(User $user)
{
// $warehouses = $user->getWarehouses();
$warehouses = array();
// if (count($warehouses) < 1) {
/** @var UserRepository $userRepository */
$userRepository = $this->em->getRepository('AppBundle:User');
if ($this->authChecker->isGranted('ROLE_INTERNAL') || $this->authChecker->isGranted('ROLE_ADMIN')) {
$warehouses = $userRepository->getSelectedMacroDealerWharehouses($user);
} else {
$macrodealers = $user->getSelectedMacroDealer()?: $this->getAllowedMacroDealers($user);
$warehouses = $userRepository->getWarehousesAvailable($user,$macrodealers);
}
// }
return $warehouses;
// // NB: Prediligo i Prim che iniziano con F. Ma se ci fosse un whId che non ha Prim che iniziano con F, in questo modo lo prendo lo stesso
// $toreturn = array();
// $F_array = array();
// foreach ($warehouses as $warehouse) {
// if (!in_array($warehouse->getWhId(), $F_array)) {
// $toreturn[$warehouse->getWhId()] = $warehouse;
// if (strrpos($warehouse->getPrim(), 'F') === 0) {
// $F_array[] = $warehouse->getWhId();
// }
// }
// }
// return $toreturn;
}
public function getLastImportDate(User $user)
{
$lastDate=$this->em->getRepository("AppBundle:Warehouse")->getLastDduDateByUser($user);
if(is_null($lastDate)){
return "";
}
$date = \DateTime::createFromFormat('Y-m-d H:i:s', $lastDate);
$date->sub(new \DateInterval('P1D'));
return $date->format("d-m-Y");
}
/**
* Se tra i log trovo un log di tipo TYPE_IMPORT senza la data di fine (endedAt),
* allora c'è un download in corso
*/
public function isImportInProgress(){
$logRepository = $this->em->getRepository("AppBundle:Log");
$results = $logRepository->findBy(array(
"type" => Log::TYPE_IMPORT,
"endedAt" => null
));
return count($results)>0;
}
public function getCurrencies(User $user,$sameCountryFlag = null)
{
//return $this->em->getRepository("AppBundle:Currency")->getDistinctList($user->getSelectedMacroDealer(), $user->getSelectedCountry());
if(!$user->getSwitchToOld()){
return $this->em->getRepository("AppBundle:Currency")->getSelectList();
}
$country = $user->getSelectedCountry() ;
$countryCode = is_null($country) ? $this->container->getParameter("default_country_code") : $country->getCode();
$currencylist = $this->em->getRepository("AppBundle:Currency")->getCountryList($countryCode);
if(!$currencylist || empty($currencylist))
{
// Set euro as defaults
$currencylist = null;
$currencylist = array();
$currencylist[] = [ "code" => 200, "description" => "EUR", "defaultValue" => true ];
}
if(!$sameCountryFlag){
$user->setSelectedCurrencyCode($currencylist[0]['code']);
$this->em->persist($user);
$this->em->flush();
}
return $currencylist;
}
public function getCurrentCurrencyDescription(User $user,$avilablecurrencies)
{
/** @var Currency $currency */
$currencyCode=(array_search($user->getSelectedCurrencyCode(), array_column($avilablecurrencies, 'code')) !==false) ? $user->getSelectedCurrencyCode() : DefaultController::EUR_CURRENCY_CODE;
$currency = $this->em->getRepository("AppBundle:Currency")->findOneByCode($currencyCode);
$description = "Currencies";
if (!is_null($currency)) {
$description = $currency->getDescription();
}
return $description;
}
public function getCurrentMacroDealerGroupLabel($macroDealerGroupId){
return self::getMacroDealaerGroupLabel($macroDealerGroupId);
}
public static function getMacroDealaerGroupLabel($macroDealerGroupId){
if($macroDealerGroupId==User::DOP){
return 'menu.allDOP';
}elseif ($macroDealerGroupId==User::THIRD_PARTS){
return 'menu.allThirdParts';
}
return "";
}
public function PDFLabels($config)
{
if(isset($config->filters)){
foreach($config->filters[0] as $filter){
if($config->activeFilters){
$activeFilter = $config->activeFilters->{$filter->name};
yield array_values(array_filter($filter->values,function($value)use($activeFilter){
return $activeFilter == $value->value;
}))[0]->label;
}else{
yield $filter->values[0]->label;
}
}
}
}
public function getContextualHelp($route,ParameterBag $routeParams,User $user){
if($route=='/admin/'){
$easyAdminName=$routeParams->get('easyadmin')['entity']['name'];
$route=strtolower($easyAdminName);
}
$locale=$user->getSelectedLocale();
if(!$locale || !in_array($locale,array('it','en')))
$locale='en';
return $this->em->getRepository('AppBundle:ContextualHelpImage')->findBy(array(
'page'=>$route,
'role'=>$user->getPrettyRole(),
'locale'=>$locale
),array('path'=>'asc'));
}
/**
* @param $user User
* @return array
*/
public function getMacroDatasets($user)
{
$macroDatasets = array();
$datasets = array();
if(count($user->getDatasets())>0)
{
$datasets = $user->getDatasets() ;
}
else
{
$datasetRepository =$this->em->getRepository("AppBundle:Dataset");
$datasets = $datasetRepository->findAll();
}
usort($datasets, function($a, $b) {return ($a->getId() > $b->getId());});
foreach ($datasets as $dataset){
if(!isset($macroDatasets[$dataset->getMacroDataset()->getId()])){
$macroDatasets[$dataset->getMacroDataset()->getId()] = array("name"=>$dataset->getMacroDataset()->getName(), "datasets"=>array());
}
$macroDatasets[$dataset->getMacroDataset()->getId()]["datasets"][] = array("id"=>$dataset->getId(),"name"=>$dataset->getName());
}
return $macroDatasets;
}
/**
* @param $arrayObjects
* @param $property
* @param $value
*/
public function searchInArrayObjects($arrayObjects, $property, $value)
{
$found = false;
foreach ($arrayObjects as $obj){
if($obj[$property] == $value){
$found = true;
break;
}
}
return $found;
}
public function isSingleDealershipUser(User $user)
{
return count($this->getDealerships($user)) == 1 ? '1' : '0';
}
public function isUserEditEnabled(User $user)
{
return $user->isEnableUserEdit();
}
public function getDealerships(User $user) {
return $this->em->getRepository(MyamsUserProfile::class)->GetAllUserDealership($user);
}
public function getDealerGroups(User $user) {
return $this->em->getRepository(MyamsUserProfile::class)->GetAllUserDealerGroups($user);
}
/**
* @throws NonUniqueResultException
* @throws NoResultException
*/
public function hasNotConnectedDealerGroups(User $user): bool {
$userDealerGroup = array_column($this->getDealerGroups($user), 'cdDealerGroup');
$notConnected = $this->em->getRepository(MvMycmMyamsDealerGroup::class)
->countNotConnectedDealerGroups($userDealerGroup);
return (int) $notConnected > 0;
}
public function getUniqId($prefix = "", $more_entropy = false) {
return uniqid($prefix, $more_entropy);
}
public function oneTime($check) {
return !$this->checks->contains($check) && $this->checks->add($check);
}
public function getExposableEntities():array {
$entities = [];
$reader = new AnnotationReader();
$baseFrontend = new Frontend();
$this->importService->addAnnotation(Frontend::class);
foreach($this->em->getMetadataFactory()->getAllMetadata() as $metadata) {
$annotationFrontendClass = $reader->getClassAnnotation($metadata->getReflectionClass(), Frontend::class) ?? $baseFrontend;
$reflectionClass = $metadata->getReflectionClass();
$class = $reflectionClass->getName();
$metadata = $this->importService->calculateMetadata($class, ["expose" => true]);
$exposeName = $annotationFrontendClass->getExposeAs() ?: $class;
if(isset($entities[$exposeName])) throw new HttpException(500, "Mapping \"".($exposeName)."\" is already defined");
if(!empty($metadata)) $entities[$exposeName] = $metadata;
}
return $entities;
}
public function getExposableEntity($class):array {
$this->importService->addAnnotation(Frontend::class);
return $this->importService->calculateMetadata($class, ["expose" => true]);
}
public function getExposableName($class):string {
$reader = new AnnotationReader();
$annotationFrontendClass = $reader->getClassAnnotation(new ReflectionClass($class), Frontend::class) ?? new Frontend();
return $annotationFrontendClass->getExposeAs();
}
public function getFilters() {
return array(
new \Twig_SimpleFilter('attrs', array($this, 'get_attributes'), ["is_safe" => ["html"]]),
new \Twig_SimpleFilter('setProperty', array($this, 'set_property')),
);
}
public function get_attributes($attributes):string {
$attrs = [];
foreach($attributes??[] as $key => $value) {
$attrs[] = "$key=\"$value\"";
}
return implode(" ", $attrs);
}
public function set_property($object, $property, $value = null) {
$object[$property] = $value;
return $object;
}
public function isEnablePortfolio($user) {
if($this->authChecker->isGranted('ROLE_IS_INTERNAL') || $this->authChecker->isGranted('ROLE_IS_ADMIN'))
return true;
elseif($this->authChecker->isGranted('ROLE_IS_DEALER')) {
$dealergroups = $this->getDealerGroups($user);
$marketRegion = array_column($dealergroups,'dsMarketRegion');
if(in_array('UK & ROI',$marketRegion) or in_array('Italy',$marketRegion) )
return true;
}
return false;
}
}