text: import os.path
  import json
  from datetime import datetime  # to validate period string
  from django.shortcuts import HttpResponse
  from django.shortcuts import render
  from django.shortcuts import redirect
  from django.shortcuts import resolve_url
  from django.views.generic import ListView
  from django.views.generic import TemplateView
  from django.contrib.auth.mixins import LoginRequiredMixin
  from django.contrib.auth.mixins import AccessMixin
  from django.conf import settings
  
  from svcommon.sv_sql_raw import SvSqlAccess
  from svacct.models import Account
  from svacct.ownership import get_owned_brand_list
  
  from .forms import UploadFileForm
  from .models import UploadFile
  from .models import EdiFile
  from .models import ProgressStatus
  from .models import HyperMartType
  from .models import EdiDataType
  
  # for logger
  import logging
  
  logger = logging.getLogger(__name__)
  
  
  # Create your views here.
  # http://ccbv.co.uk/
  # https://www.youtube.com/watch?v=Zx09vcYq1oc&feature=youtu.be
  # https://www.youtube.com/watch?v=KQJRwWpP8hs
  # https://www.youtube.com/watch?v=HSn-e2snNc8
  
  
  # django template grammar
  # https://jjinisystem.tistory.com/38
  class OwnerOnlyMixin(AccessMixin):
      raise_exception = True
      permission_denied_message = 'Owner only can modify the object'
  
      def get(self, request, *args, **kwargs):
          # logger.debug('OwnerOnlyMixin get')
          print('OwnerOnlyMixin get')
          obj = self.get_object()
          # print(obj.owner)
          # print(request.user)
          if not request.user == obj.owner:
              return self.handle_no_permission()
          return super().get(request, *args, **kwargs)
  
  
  class UploadedFileListView(LoginRequiredMixin, ListView):
      model = UploadFile
      form_class = UploadFileForm
      # template_name = 'class_bundle_list.html'
      context_object_name = 'UploadFiles'
      paginate_by = 10
  
      def get_context_data(self, **kwargs):
          context = super().get_context_data(**kwargs)
          dict_rst = get_acct_info(self.request, self.kwargs)
          context['form'] = UploadFileForm()
  
          context['s_brand_name'] = dict_rst['dict_ret']['s_brand_name']  # for global navigation
          context['n_brand_id'] = self.kwargs['sv_brand_id']
          context['lst_owned_acct'] = dict_rst['dict_ret']['lst_owned_acct']  # for global navigation
          return context
  
      # https://stackoverflow.com/questions/37299091/django-how-to-get-user-logged-in-get-queryset-in-listview
      # https://beomi.github.io/2017/08/25/DjangoCBV-queryset-vs-get_queryset/
      def get_queryset(self):
          dict_rst = get_acct_info(self.request, self.kwargs)
          # return UploadFile.objects.filter(owner=self.request.user).order_by('-id')
          return UploadFile.objects.filter(account=dict_rst['dict_ret']['n_acct_id']).order_by('-id')
  
      def post(self, request, *args, **kwargs):
          form = UploadFileForm(request.POST, request.FILES)
          if form.is_valid():
              dict_acct_rst = get_acct_info(request, kwargs)
              qd_sv_acct = Account.objects.get(pk=dict_acct_rst['dict_ret']['n_acct_id'])
              # print(form.cleaned_data['uploaded_file'].name)
              form.instance.owner = self.request.user
              form.instance.account = qd_sv_acct
              # pre-process
              o_initial_form = form.save(commit=False)
              o_initial_form.save()
              # commit form
              o_new_uploaded_file = form.save()
  
              from .tools import ProcUploadingFile
              o_tool_uploading_file = ProcUploadingFile()
              dict_rst = o_tool_uploading_file.lookup_attachment(request, o_initial_form, o_new_uploaded_file)
              del o_tool_uploading_file
              if not dict_rst['b_rst']:
                  dict_context = {'err_msg': dict_rst['s_msg']}
                  return render(request, "svtransform/upload_deny.html", context=dict_context)
  
              dict_param = dict_rst['dict_param']
              # begin - uploading file registration
              n_edi_yr_from_upload_filename = dict_param['n_edi_yr_from_upload_filename']
              # https://wayhome25.github.io/django/2017/04/01/django-ep9-crud/
              for s_unzipped_file in dict_param['lst_unzipped_files']:
                  o_edi_file = EdiFile(hyper_mart=HyperMartType.ESTIMATION, edi_data_year=n_edi_yr_from_upload_filename,
                                       owner=self.request.user, account=qd_sv_acct,
                                       edi_file_name=s_unzipped_file, uploaded_file=o_new_uploaded_file)
                  o_edi_file.save()
              # end - uploading file registration
              from .tasks import lookup_edi_file
              dict_param['s_tbl_prefix'] = dict_acct_rst['dict_ret']['s_tbl_prefix']  #self.request.user.analytical_namespace
              if len(dict_param['lst_unzipped_files']) > 2:
                  lookup_edi_file.apply_async([dict_param], queue='celery', priority=10)  # , countdown=10)
              else:
                  lookup_edi_file(dict_param)
  
              return redirect('svtransform:index', sv_brand_id=dict_acct_rst['dict_ret']['n_brand_id'])
          else:
              return render(request, 'svtransform/upload_bundle.html', {'form': form})
  
      def form_valid(self, form):
          # This method does not work if post() or get() defined
          # This method needs private var -> success_url = reverse_lazy('class_book_list')
          # This method is called when valid form data has been POSTed.
          # It should return an HttpResponse.
          return super().form_valid(form)
  
  
  class UnzippedFileListView(LoginRequiredMixin, ListView):
      # model = EdiFile
      # template_name = 'svtransform/edifile_list.html'
      context_object_name = 'UnzippedFiles'
      # paginate_by = 10
  
      # https://stackoverflow.com/questions/50275355/django-listview-with-a-form
      # https://stackoverflow.com/questions/37299091/django-how-to-get-user-logged-in-get-queryset-in-listview
      # https://beomi.github.io/2017/08/25/DjangoCBV-queryset-vs-get_queryset/
      def get_queryset(self):
          # print(self.kwargs['pk'])
          return EdiFile.objects.filter(uploaded_file=self.kwargs['pk']).filter(owner=self.request.user). \
              exclude(status=ProgressStatus.DENIED)
  
      # https://stackoverflow.com/questions/50275355/django-listview-with-a-form
      # make tableview form
      # build up context object for template
      # https://wayhome25.github.io/django/2017/06/25/django-ajax-like-button/ <-- ajax button
      def get_context_data(self, **kwargs):
          context = super().get_context_data(**kwargs)
          dict_rst = get_acct_info(self.request, self.kwargs)
          context['s_brand_name'] = dict_rst['dict_ret']['s_brand_name']  # for global navigation
          context['n_brand_id'] = self.kwargs['sv_brand_id']
          context['lst_owned_acct'] = dict_rst['dict_ret']['lst_owned_acct']  # for global navigation
          # print(EdiFile.HyperMartType.names)  # .labels  .values
          context['pk_upload_file'] = self.kwargs['pk']
          context['hyper_mart_type'] = HyperMartType
          context['edi_data_type'] = EdiDataType
          context['edi_data_year'] = range(2010, 2025)  # define data year for Emart EDI
          return context
  
  
  class UnzippedFileListAuth(LoginRequiredMixin, TemplateView):
      # context_object_name = 'UnzippedFiles'
      template_name = None
  
      def post(self, request):
          # template에서 ajax.POST로 전달
          n_pk_upload_file = request.POST.get('pk_upload_file', None)
          s_req_mode = request.POST.get('req_mode', None)
          # context를 json 타입으로
          context = {'b_success': 0,  # false
                     'message': '통신 실패',
                     'href': ''}
          # print(request.user.company_name)
          if not request.user.is_authenticated:
              context['message'] = 'you re not logged in.'
              return HttpResponse(json.dumps(context), content_type="application/json")
  
          o_uploaded_file = UploadFile.objects.get(pk=n_pk_upload_file)  # Model.get() returns single record
          if not o_uploaded_file.owner == request.user:
              if not request.user.is_admin:
                  context['message'] = 'you don\'t own the file you request.'
                  return HttpResponse(json.dumps(context), content_type="application/json")
  
          # basically, check an upload file level progress status
          if o_uploaded_file.status != ProgressStatus.UPLOADED and o_uploaded_file.status != ProgressStatus.DENIED:
              if not request.user.is_admin:
                  context['message'] = 'uploaded_file is out of status'
                  return HttpResponse(json.dumps(context), content_type="application/json")
              else:
                  if o_uploaded_file.status == ProgressStatus.TRANSFORMED:
                      context['message'] = 'edi_file has been transformed'
                      return HttpResponse(json.dumps(context), content_type="application/json")
  
          # secondly, check an each edi file progress status
          qs_edi_file = EdiFile.objects.filter(uploaded_file=n_pk_upload_file).filter(owner=self.request.user)
          # Model.filter() returns queryset; n_owner_id = qs_uploaded_file.values('owner')[0]['owner']
          for o_edi_file in qs_edi_file:
              if o_edi_file.status != ProgressStatus.UPLOADED:
                  if not request.user.is_admin:
                      context['message'] = 'edi_file is out of status'
                      return HttpResponse(json.dumps(context), content_type="application/json")
  
          # finally, check an each edi file data type and req_mode
          if s_req_mode == 'update':
              for o_edi_file in qs_edi_file:
                  if o_edi_file.edi_data_type == EdiDataType.ESTIMATION:
                      if not request.user.is_admin:
                          context['message'] = 'edi_file is on estimation'
                          return HttpResponse(json.dumps(context), content_type="application/json")
              self.__update_edi_file(request)
          elif s_req_mode == 'delete':
              for o_edi_file in qs_edi_file:
                  if o_edi_file.edi_data_type == EdiDataType.ESTIMATION:
                      if not request.user.is_admin:
                          context['message'] = 'edi_file is on estimation'
                          return HttpResponse(json.dumps(context), content_type="application/json")
              # print('do ' + s_req_mode)
              o_uploaded_file.delete()
          elif s_req_mode == 'transform':  # 모든 edi 파일이 QTY 혹은 AMNT로 결정되어야 진행 시작
              n_sv_brand_id = request.POST.get('sv_brand_id', None)
              dict_kwargs = {'sv_brand_id': int(n_sv_brand_id)}
              dict_acct_rst = get_acct_info(request, dict_kwargs)
              del dict_kwargs
              for o_edi_file in qs_edi_file:
                  if o_edi_file.edi_data_type != EdiDataType.QTY_AMNT and \
                          o_edi_file.edi_data_type != EdiDataType.QTY and \
                          o_edi_file.edi_data_type != EdiDataType.AMNT and \
                          o_edi_file.edi_data_type != EdiDataType.IGNORE:
                      context['message'] = 'undecided edi_file exists'
                      return HttpResponse(json.dumps(context), content_type="application/json")
                  if o_edi_file.edi_data_year == 0:
                      context['message'] = 'edi_file data year is not confirmed'
                      return HttpResponse(json.dumps(context), content_type="application/json")
              self.__transform_edi_file(request, dict_acct_rst, o_uploaded_file)
              context['message'] = 'transforming launched!'
              context['href'] = resolve_url('svtransform:on_transforming', sv_brand_id=n_sv_brand_id, pk=n_pk_upload_file)
          del o_uploaded_file
          del qs_edi_file
          context['b_success'] = 1  # true
          return HttpResponse(json.dumps(context), content_type="application/json")
  
      def __update_edi_file(self, request):
          # edi 파일 수정
          lst_edifile_id = request.POST.getlist('arr_edifile_id[]')  # need [] if array transmitted via ajax
          lst_hypermart_title = request.POST.getlist('arr_hypermart_title[]')
          lst_edi_data_year = request.POST.getlist('arr_edi_data_year[]')
          lst_edi_data_type = request.POST.getlist('arr_edi_data_type[]')
          for n_edifile_id in lst_edifile_id:
              o_edi_file = EdiFile.objects.get(id=n_edifile_id)
              o_edi_file.hyper_mart = lst_hypermart_title.pop(0)
              o_edi_file.edi_data_year = lst_edi_data_year.pop(0)
              o_edi_file.edi_data_type = lst_edi_data_type.pop(0)
              o_edi_file.save()
          return
  
      def __transform_edi_file(self, request, dict_acct_rst, o_uploaded_file):
          # launch pre-process
          # https://stackoverrun.com/ko/q/1880252 <- long running task
          # https://stackoverflow.com/questions/25570910/executing-two-tasks-at-the-same-time-with-celery
          # celery -A svcommon worker -l INFO <- activate celery server
          s_tbl_prefix = dict_acct_rst['dict_ret']['s_tbl_prefix']
          if not s_tbl_prefix:
              dict_context = {'err_msg': 'your analytical context is not defined. plz contact system admin'}
              return render(request, "svtransform/transform_deny.html", context=dict_context)
          # transfer status to ProgressStatus.ON_TRANSFORMING
          o_uploaded_file.status = ProgressStatus.ON_TRANSFORMING
          o_uploaded_file.save()
          # for sv_sql_raw tester
          # from svcommon.sv_sql_raw import SvSqlAccess
          # oDb = SvSqlAccess()
          # oDb.set_tbl_prefix(s_analytical_namespace)
          # oDb.set_app_name(__name__)
          # oDb.initialize()
          # lst_rst = oDb.executeQuery('getEmartExistingLog', 1, 1, 20190103)
          # print(lst_rst)
          dict_param = {
              's_tbl_prefix': s_tbl_prefix,
              'n_owner_id': o_uploaded_file.owner.id,
              'n_req_upload_file_id': request.POST['pk_upload_file']
          }
          # https://stackoverflow.com/questions/47979831/how-to-use-priority-in-celery-task-apply-async
          from .tasks import transform_edi
          transform_edi.apply_async([dict_param], queue='celery', priority=0)
          # for TransferEdiExcelToDb tester
          # from .tasks import TransferEdiExcelToDb
          # o_edi_excel_handler = TransferEdiExcelToDb()
          # o_edi_excel_handler.initialize(dict_param)
          # o_edi_excel_handler.transfer_excel_to_csv()
          # o_edi_excel_handler.transform_csv_to_db()
          print('transform_edi_file done')
          # return HttpResponseRedirect('/redirect/')
  
  
  class TransformRawData(OwnerOnlyMixin, TemplateView):
      # model = UploadFile
      # https://www.agiliq.com/blog/2017/12/when-and-how-use-django-templateview/
      # template_name = 'svtransform/transform_confirm.html'  # for get method template
      def get(self, request, *args, **kwargs):  # show a pre-process confirm screen
          dict_rst = get_acct_info(request, kwargs)
          context = {'s_brand_name': dict_rst['dict_ret']['s_brand_name'],
                     'n_brand_id': dict_rst['dict_ret']['n_brand_id'],
                     'lst_owned_acct': dict_rst['dict_ret']['lst_owned_acct'],
                     'duration': '33min 28sec', }
          o_uploaded_file = UploadFile.objects.get(pk=self.kwargs['pk'])
          # return render(request, "svtransform/transform_on_progress.html", context=context)
          if o_uploaded_file.status == ProgressStatus.ON_TRANSFORMING:
              return render(request, "svtransform/transform_on_progress.html", context=context)
          else:
              return render(request, "svtransform/transform_deny.html", context=context)
  
  
  class ExtractView(LoginRequiredMixin, TemplateView):
      # https://www.agiliq.com/blog/2017/12/when-and-how-use-django-templateview/
      template_name = 'svtransform/extract_select.html'  # for get method template
      # model = UploadFile
  
      def get(self, request, *args, **kwargs):
          if request.user.is_authenticated:
              context = super().get_context_data(*args, **kwargs)
              # begin - read edi date info cached json
              # TODO: move to /storage
              s_edi_date_json_fullpath = os.path.join(settings.MEDIA_ROOT, settings.EDI_STORAGE_ROOT,
                                                      str(self.request.user.pk), 'edi_date_info.json')
              try:
                  with open(s_edi_date_json_fullpath, "r") as st_json:
                      dict_edi_date_info = json.load(st_json)
              except FileNotFoundError:
                  dict_edi_date_info = {'s_start_date': None, 's_end_date': None, 'lst_missing_date': None}
  
              context['s_start_date'] = dict_edi_date_info['s_start_date']
              context['s_end_date'] = dict_edi_date_info['s_end_date']
              context['lst_missing_date'] = dict_edi_date_info['lst_missing_date']
              # end - read edi date info cached json
              o_sv_db = SvSqlAccess()
              if not o_sv_db:
                  raise Exception('invalid db handler')
  
              dict_rst = get_acct_info(request, kwargs, o_sv_db)
              context['s_brand_name'] = dict_rst['dict_ret']['s_brand_name']  # for global navigation
              context['lst_owned_acct'] = dict_rst['dict_ret']['lst_owned_acct']  # for global navigation
              # retrieve sku info
              lst_sku_rst = o_sv_db.executeQuery('getEdiSkuNameAll', self.request.user.pk)
              if len(lst_sku_rst) == 0:
                  dict_context = {'err_msg': 'no SKUs to extract'}
                  return render(request, "svtransform/extract_deny.html", context=dict_context)
  
              # translate mart_id to mart_name
              dict_hyper_mart_type = HyperMartType.get_dict_by_idx()
              lst_mart_type_converted_sku = []
              for dict_sku in lst_sku_rst:
                  lst_mart_type_converted_sku.append({'id': dict_sku['id'], 'item_name': dict_sku['item_name'],
                                                      'brand_id': dict_sku['brand_id'],
                                                      'mart_name': dict_hyper_mart_type[dict_sku['mart_id']]})
              del lst_sku_rst
              # retrieve brand info
              lst_brand_rst = []
              for dict_single_brand in dict_rst['dict_ret']['lst_brand_by_cur_acct']:
                  lst_brand_rst.append({'id': dict_single_brand['n_brand_id'], 'brand_name': dict_single_brand['s_brand_ttl']})
              context['lst_brand'] = lst_brand_rst
              # group skus by brand
              from collections import defaultdict
              dict_sku_by_brand = defaultdict(list)
              for dict_brand in lst_brand_rst:
                  for dict_sku in lst_mart_type_converted_sku:
                      if dict_sku['brand_id'] == dict_brand['id']:
                          dict_sku_by_brand[dict_brand['id']].append(dict_sku)
              # 전체 SKU 리스트에서 브랜드 속한 SKU를 제거함
              for n_brand_id, lst_skus in dict_sku_by_brand.items():
                  for dict_sku in lst_skus:
                      del lst_mart_type_converted_sku[lst_mart_type_converted_sku.index(dict_sku)]
              context['lst_non_brand_skus'] = lst_mart_type_converted_sku
              context['dict_sku_by_brand'] = dict(dict_sku_by_brand)
              return render(request, "svtransform/extract_select.html", context=context)
          else:
              dict_context = {'err_msg': 'no access right'}
              return render(request, "svtransform/extract_deny.html", context=dict_context)
  
      def post(self, request, *args, **kwargs):
          # celery -A svcommon worker -l INFO <- activate celery server
          o_sv_db = SvSqlAccess()
          if not o_sv_db:
              raise Exception('invalid db handler')
  
          dict_rst = get_acct_info(request, kwargs, o_sv_db)
          dict_context = {'n_brand_id': dict_rst['dict_ret']['n_brand_id'], 'duration': None, 'err_msg': None}
  
          s_period_start = request.POST.get('id_extract_period_start')
          s_period_end = request.POST.get('id_extract_period_end')
          if len(s_period_start) > 0 and len(s_period_end) > 0:
              try:
                  datetime.strptime(s_period_start, '%Y%m%d')
              except ValueError:
                  dict_context['err_msg'] = 'invalid start period'
                  return render(request, "svtransform/extract_deny.html", context=dict_context)
              try:
                  datetime.strptime(s_period_end, '%Y%m%d')
              except ValueError:
                  dict_context['err_msg'] = 'invalid end period'
                  return render(request, "svtransform/extract_deny.html", context=dict_context)
  
          lst_edi_sku_id = []
          n_sv_brand_id = dict_rst['dict_ret']['n_brand_id']
          lst_sku_rst = o_sv_db.executeQuery('getEdiSkuByBrandId', n_sv_brand_id)
          if len(lst_sku_rst) == 0:
              dict_context['err_msg'] = 'no EDI SKUs selected'
              return render(request, "svtransform/extract_deny.html", context=dict_context)
  
          for dict_sku in lst_sku_rst:  # connect sku IDs to brand group
              lst_edi_sku_id.append(str(dict_sku['id']))
          del lst_sku_rst
          del o_sv_db
          dict_extraction_option = {'debug_mode': False,
                                    'google_data_studio_edi': False, 'excel_pivot': False,
                                    'aws_quicksight': False, 'oracle_analytics_cloud': False}
          if request.POST.get('id_extract_debug'):
              dict_extraction_option['debug_mode'] = True
          if request.POST.get('id_extract_excel_pivot'):
              dict_extraction_option['excel_pivot'] = True
          if request.POST.get('id_google_data_studio_edi'):
              dict_extraction_option['google_data_studio_edi'] = True
          if request.POST.get('id_extract_aws_quicksight'):
              dict_extraction_option['aws_quicksight'] = True
          if request.POST.get('id_extract_oac'):
              dict_extraction_option['oracle_analytics_cloud'] = True
          dict_param = {
              's_tbl_prefix': dict_rst['dict_ret']['s_tbl_prefix'],
              'n_owner_id': request.user.id,  # TODO: change to n_sv_acct_id
              'n_brand_id': n_sv_brand_id,
              's_extract_filename_prefix': request.POST.get('extract_filename_prefix'),
              's_req_sku_set': ','.join(lst_edi_sku_id),
              'b_excel_pivot': dict_extraction_option['excel_pivot'],
              'b_google_data_studio_edi': dict_extraction_option['google_data_studio_edi'],
              'b_aws_quicksight': dict_extraction_option['aws_quicksight'],
              'b_oracle_analytics_cloud': dict_extraction_option['oracle_analytics_cloud'],
              'b_debug_mode': dict_extraction_option['debug_mode'],
              's_period_start': s_period_start,
              's_period_end': s_period_end
          }
          # TODO: 페이지 새로고침 눌러도 중복 실행되지 않도록 해야 함
          from .tasks import extract_edi_file
          extract_edi_file.apply_async([dict_param], queue='celery', priority=10)  # , countdown=10)
          # for ExtractDb tester
          # from .tasks import ExtractDb
          # o_extractor = ExtractDb()
          # o_extractor.initialize(dict_param)
          # o_extractor.clear()
  
          dict_context['duration'] = '33min 28sec'
          return render(request, "svtransform/extract_on_progress.html", context=dict_context)
  
  
  class ConcatenateSkuIntoBrand(LoginRequiredMixin, TemplateView):
      template_name = None
  
      def post(self, request):
          import json
          from django.shortcuts import HttpResponse
          # template에서 ajax.POST로 전달
          s_req_mode = request.POST.get('req_mode', None)
          print(s_req_mode + ' launched')  # 지워야 함.
          # context를 json 타입으로
          context = {'b_success': 0,  # false
                     'message': '통신 실패',
                     'href': ''}
          if not request.user.is_authenticated:
              context['message'] = 'you re not logged in.'
              return HttpResponse(json.dumps(context), content_type="application/json")
  
          # from svcommon.sv_sql_raw import SvSqlAccess
          # o_svdb = SvSqlAccess()
          # o_svdb.set_tbl_prefix(request.user.analytical_namespace)
          # o_svdb.set_app_name(__name__)
          # o_svdb.initialize()
          o_sv_db = SvSqlAccess()
          if not o_sv_db:
              raise Exception('invalid db handler')
  
          n_brand_id = request.POST.get('brand_id', None)  # request.POST['pk_upload_file']
          dict_kwargs = {'sv_brand_id': int(n_brand_id)}
          dict_rst = get_acct_info(request, dict_kwargs, o_sv_db)
          del dict_kwargs
          context['s_brand_name'] = dict_rst['dict_ret']['s_brand_name']  # for global navigation
          context['lst_owned_acct'] = dict_rst['dict_ret']['lst_owned_acct']  # for global navigation
          # finally, do request
          if s_req_mode == 'invite_sku':
              lst_sku_id = request.POST.getlist('sku_id[]', None)  # need [] if array transmitted via ajax
              for n_sku_id in lst_sku_id:
                  o_sv_db.executeQuery('updateBrandId', n_brand_id, n_sku_id)
  
  
  def get_acct_info(request, kwargs, o_db=None):
      dict_rst = {'b_error': False, 's_msg': None, 'dict_ret': None}
      dict_owned_brand = get_owned_brand_list(request, kwargs)
      s_tbl_prefix = None
      n_acct_id = None
      n_brand_id = None
      s_brand_name = None
      lst_owned_acct = []
      lst_brand_by_cur_acct = []
      for _, dict_single_acct in dict_owned_brand.items():
          lst_owned_acct.append({'n_acct_id': dict_single_acct['n_acct_id'], 's_acct_ttl': dict_single_acct['s_acct_ttl'],
                                 'n_rep_brand_id': dict_single_acct['lst_brand'][0]['n_brand_id']})
          for dict_single_brand in dict_single_acct['lst_brand']:
              if dict_single_brand['b_current_brand']:
                  lst_brand_by_cur_acct += dict_single_acct['lst_brand']
                  n_acct_id = dict_single_acct['n_acct_id']
                  s_tbl_prefix = str(n_acct_id)
                  n_brand_id = dict_single_brand['n_brand_id']
                  s_brand_name = dict_single_brand['s_brand_ttl']
                  break
  
      if not s_tbl_prefix or not n_brand_id:
          dict_rst['b_error'] = True
          dict_rst['s_msg'] = 'not allowed brand'
          return dict_rst
      if o_db:
          o_db.set_tbl_prefix(s_tbl_prefix)
          o_db.set_app_name(__name__)
          o_db.initialize()
          o_db.set_reserved_tag_value({'brand_id': n_brand_id})
      dict_rst['s_msg'] = 'success'
      dict_rst['dict_ret'] = {'n_acct_id': n_acct_id, 'n_brand_id': n_brand_id, 's_brand_name': s_brand_name,
                              's_tbl_prefix': s_tbl_prefix, 'lst_owned_acct': lst_owned_acct,
                              'lst_brand_by_cur_acct': lst_brand_by_cur_acct}
      return dict_rst
  