예제 #1
0
    def create(self, request):
        """
            API tạo mới và cập nhật quy đổi point Pos365 \n
            Giá trị type_code lấy từ API /api/pos365s/list-contract-durations
            Request body for this api : Không được bỏ trống \n
                {
                    "exchange_point_pos365s": [
                        {
                            "type_code": 0,
                            "point": 1
                        },
                        {
                            "type_code": 1,
                            "point": 2
                        }
                    ]
                }
        """
        try:
            body = json.loads(request.body)

            exchange_point_pos365s = body.get('exchange_point_pos365s')

            type_code_list = []
            for i in Pos365ContractDuration.CHOICES:
                type_code_list.append(i[0])

            validate_type_code = []

            for item in exchange_point_pos365s:
                if item['type_code'] in validate_type_code:
                    return custom_response(Code.INVALID_BODY,
                                           'type_code is duplicate')
                else:
                    validate_type_code.append(item['type_code'])
                if item['type_code'] not in type_code_list:
                    return custom_response(Code.INVALID_BODY,
                                           'type_code Invalid')
                if not isinstance(item['point'], float) and not isinstance(
                        item['point'], int):
                    return custom_response(Code.INVALID_BODY, 'point Invalid')

            for update_item in exchange_point_pos365s:
                ExchangePointPos365.objects.get_or_create(
                    type=update_item['type_code'])
                ExchangePointPos365.objects.filter(
                    type=update_item['type_code']).update(
                        point=update_item['point'])

            return successful_response(
                'Update or create ExchangePointPos365 success')

        except Exception as e:
            logging.error('Create ExchangePointPos365 exception: %s', e)
            return custom_response(Code.INTERNAL_SERVER_ERROR)
예제 #2
0
    def retrieve(self, request, pk):
        """
            API get detail user
        """
        user = User.objects.filter(pk=pk).first()
        if user is None:
            return custom_response(Code.USER_NOT_FOUND)

        user_permissions = user.user_permissions.all()
        group_permissions = Permission.objects.filter(group__user=user).all()

        areas, teams = [], []

        for item in user.area_set.all():
            area = {'id': item.id, 'name': item.name, 'code': item.code}
            areas.append(area)

        for item in user.team_set.all():
            team = {'id': item.id, 'name': item.name, 'code': item.code}
            teams.append(team)

        data = {
            'user':
            AccountSerializer(user).data,
            'areas':
            areas,
            'teams':
            teams,
            'user_permissions':
            PermissionSerializer(user_permissions, many=True).data,
            'group_permissions':
            PermissionSerializer(group_permissions, many=True).data,
        }

        return successful_response(data)
예제 #3
0
    def create(self, request):
        assign_terminal_id = request.POST.get('assign_terminal_id', None)
        merchant_id = request.POST.get('merchant_id', None)
        team_id = request.POST.get('team_id', None)
        staff_id = request.POST.get('staff_id', None)
        name = request.POST.get('name', None)
        address = request.POST.get('address', None)
        province_id = request.POST.get('province_id', None)
        district_id = request.POST.get('district_id', None)
        wards_id = request.POST.get('wards_id', None)
        street = request.POST.get('street', None)
        description = request.POST.get('description', None)

        province = QrProvince.objects.filter(id=province_id).first()
        district = QrDistrict.objects.filter(id=district_id).first()
        wards = QrWards.objects.filter(id=wards_id).first()
        merchant = Merchant.objects.filter(id=merchant_id).first()
        staff = Staff.objects.filter(id=staff_id).first()

        code = Shop.objects.all().order_by("-id")[0].id + 1

        shop = Shop(merchant=merchant,
                    name=conditional_escape(name),
                    code=conditional_escape(code),
                    address=conditional_escape(address),
                    province=province,
                    district=district,
                    wards=wards,
                    street=conditional_escape(street),
                    description=conditional_escape(description),
                    created_by=request.user)
        shop.save()

        if staff is not None:
            shop.staff_create(staff.id)

        if int(assign_terminal_id) != 0:
            terminal = Terminal.objects.get(pk=assign_terminal_id)
            if terminal is None:
                return custom_response('404.006')
            if shop.merchant == terminal.merchant:
                terminal.shop = shop
                terminal.save()
            else:
                return custom_response('400', 'Merchant is invalid')
        refresh_shop_full_data()
        return successful_response('created')
예제 #4
0
def create_from_terminal(request):
    if request.method == 'POST':
        terminal_id = request.POST.get('terminal_id', None)
        address = request.POST.get('address', None)
        street = request.POST.get('street', None)
        auto_create = request.POST.get('auto_create', None)

        terminal = Terminal.objects.get(pk=int(terminal_id))

    elif request.method == 'OTHER':
        terminal = request.terminal
        address = request.address
        street = request.street

    else:
        return custom_response(Code.NOT_IMPLEMENTED)

    staff = None
    staff_of_chain = None
    merchant = terminal.merchant
    if merchant is not None:
        staff = merchant.get_staff()
        if staff is not None:
            team = staff.team
            if team is not None and team.type != TeamType.TEAM_SALE:
                staff_of_chain = merchant.get_staff()

    shop = Shop(merchant=terminal.merchant,
                name=conditional_escape(terminal.terminal_name),
                address=conditional_escape(address),
                province_id=terminal.get_province().id if
                (terminal.get_province() is not None) else None,
                district_id=terminal.get_district().id if
                (terminal.get_district() is not None) else None,
                wards_id=terminal.get_wards().id if
                (terminal.get_wards() is not None) else None,
                street=conditional_escape(street),
                created_by=request.user)
    shop.save()

    terminal.shop = shop
    terminal.save()

    if staff is not None:
        shop.staff_create(staff.id)

    if staff_of_chain is not None:
        shop.staff_of_chain_create(staff.id)

    if request.method == 'OTHER':
        return True

    data = {'shop_id': shop.pk}
    return successful_response(data)
예제 #5
0
def user_info(request):
    """
        API get user information \n
    """

    user = request.user

    if user is None:
        return custom_response(Code.PERMISSION_DENIED)

    return successful_response(UserSerializer(user).data)
예제 #6
0
def reset_data(request, pk):
    """
        API delete SalePromotion by title_id
    """
    if SalePromotionTitle.objects.filter(id=pk).first() is None:
        return custom_response(Code.PROMOTION_NOT_FOUND)

    SalePromotion.objects.filter(title_id=pk).delete()
    SalePromotionTitle.objects.filter(id=pk).update(
        reset_data_date=datetime.datetime.now(), updated_by=request.user)

    return successful_response()
예제 #7
0
    def retrieve(self, request, pk):
        """
            API get detail Area
        """
        try:
            area = Area.objects.filter(pk=pk).first()
            if area is None:
                return custom_response(Code.AREA_NOT_FOUND)

            province_lists, proportion_kpi_lists = [], []
            province_code_lists = area.provinces.split(',')
            for item in QrProvince.objects.filter(
                    province_code__in=province_code_lists).values(
                        'province_code', 'province_name'):
                province_lists.append({
                    'province_code': item['province_code'],
                    'province_name': item['province_name'],
                })

            for proportion_kpi in area.proportion_kpi.all().values(
                    'type', 'leader_coefficient'):
                proportion_kpi_lists.append({
                    'type':
                    proportion_kpi['type'],
                    'leader_coefficient':
                    proportion_kpi['leader_coefficient'],
                })

            data = {
                'name': area.name,
                'code': area.code,
                'proportion_kpi_s73': area.proportion_kpi_s73,
                'provinces': province_lists,
                'proportion_kpi_team': proportion_kpi_lists
            }
            return successful_response(data)
        except Exception as e:
            logging.error('Get detail area exception: %s', e)
            return custom_response(Code.INTERNAL_SERVER_ERROR)
예제 #8
0
def assign_ter_to_shop(request):
    ter_id = request.POST.get('ter_id')
    shop_id = request.POST.get('shop_id')
    terminal = get_object_or_404(Terminal, pk=ter_id)
    shop = get_object_or_404(Shop, pk=shop_id)

    if shop.merchant != terminal.merchant:
        return custom_response(Code.DATA_ERROR,
                               "Shop và terminal không cùng merchant")
    else:
        terminal.shop = shop
        terminal.save()
    return successful_response({'id': shop.id})
예제 #9
0
    def update(self, request, pk):
        """
            API update account_group_permission\n
            Request body for this api : Không được bỏ trống \n
                {
                    'status': true/false
                    'group_permissions' : [1,2,3,4,5,6..]
                }
        """
        try:
            custom_group = CustomGroup.objects.filter(pk=pk).first()
            if custom_group is None:
                return custom_response(Code.GROUP_NOT_FOUND)

            body = json.loads(request.body)
            status = None
            group_permissions = []
            if 'status' in body:
                status = body['status']
            if 'group_permissions' in body:
                group_permissions = body['group_permissions']

            if status is None or status == '':
                return custom_response(Code.INVALID_BODY, 'Status not valid')

            status = True if status == 'true' else False

            custom_group.status = status
            custom_group.updated_by = request.user
            custom_group.permissions.clear()
            custom_group.permissions.set(group_permissions)
            custom_group.save()

            return successful_response()
        except Exception as e:
            logging.error('Delete account_group_permission exception: %s', e)
            return custom_response(Code.INTERNAL_SERVER_ERROR)
예제 #10
0
    def create(self, request):
        """
            API create account_group_permission\n
            Request body for this api : Không được bỏ trống \n
                {
                    'group_name' : 'text',
                    'group_permissions' : [1,2,3,4,5,6..]
                }
        """
        try:
            body = json.loads(request.body)
            group_name = None
            group_permissions = []
            if 'group_name' in body:
                group_name = body['group_name']
            if 'group_permissions' in body:
                group_permissions = body['group_permissions']

            if group_name is None or group_name == '':
                return custom_response(Code.INVALID_BODY,
                                       'group_name not valid')

            if Group.objects.filter(name__iexact=group_name):
                return custom_response(Code.BAD_REQUEST,
                                       'Group_name have been used')

            custom_group = CustomGroup(name=group_name.upper(),
                                       created_by=request.user,
                                       updated_by=request.user)
            custom_group.save()
            custom_group.permissions.set(group_permissions)
            custom_group.save()

            return successful_response(custom_group.id)
        except Exception as e:
            logging.error('Create account_group_permission exception: %s', e)
            return custom_response(Code.INTERNAL_SERVER_ERROR)
예제 #11
0
def update_proportion_kpi_s73(request, pk):
    """
        API update proportion kpi s73 cho Area \n
        Request body for this api : Không được bỏ trống
        {
                "proportion_kpi_s73": 90  -- number {min: 0, max: 100}
        }
    """

    try:
        area = Area.objects.filter(pk=pk).first()
        if area is None:
            return custom_response(Code.AREA_NOT_FOUND)

        body = json.loads(request.body)
        proportion_kpi_s73 = body.get('proportion_kpi_s73')
        if isinstance(proportion_kpi_s73, int):
            area.proportion_kpi_s73 = proportion_kpi_s73
            area.save()
        return successful_response()

    except Exception as e:
        logging.error('Update area proportion_kpi_s73 exception: %s', e)
        return custom_response(Code.INTERNAL_SERVER_ERROR)
예제 #12
0
    def retrieve(self, request, pk):
        """
            API get detail account_group_permission
        """
        custom_group = CustomGroup.objects.filter(pk=pk).first()
        if custom_group is None:
            return custom_response(Code.GROUP_NOT_FOUND)

        permissions = []

        for permission in custom_group.permissions.all():
            element = {
                'id': permission.id,
                'name': permission.name,
                'codename': permission.codename,
                'content_type': {
                    'id': permission.content_type.id,
                    'model': permission.content_type.model
                }
            }
            permissions.append(element)

        data = {
            'id':
            custom_group.id,
            'name':
            custom_group.name,
            'status':
            custom_group.status,
            'created_date':
            formats.date_format(custom_group.created_date,
                                "SHORT_DATETIME_FORMAT")
            if custom_group.created_date else '',
            'created_by':
            custom_group.created_by.username
            if custom_group.created_by else '',
            'updated_date':
            formats.date_format(custom_group.updated_date,
                                "SHORT_DATETIME_FORMAT")
            if custom_group.updated_date else '',
            'updated_by':
            custom_group.updated_by.username
            if custom_group.updated_by else '',
            'permissions':
            permissions
        }

        return successful_response(data)
예제 #13
0
    def retrieve(self, request, pk):
        """
            API get detail SalePromotion
        """
        sale_promotion = SalePromotion.objects.filter(pk=pk).first()

        if sale_promotion is None:
            return custom_response(Code.PROMOTION_NOT_FOUND)

        data = {
            'merchant':
            sale_promotion.get_merchant(),
            'terminal':
            sale_promotion.get_terminal(),
            'shop':
            sale_promotion.get_shop(),
            'staff':
            sale_promotion.get_staff(),
            'title':
            sale_promotion.get_title(),
            'contact_person':
            sale_promotion.contact_person,
            'contact_phone_number':
            sale_promotion.contact_phone_number,
            'contact_email':
            sale_promotion.contact_email,
            'tentcard_ctkm':
            sale_promotion.tentcard_ctkm,
            'wobbler_ctkm':
            sale_promotion.wobbler_ctkm,
            'status':
            sale_promotion.get_status(),
            'image':
            sale_promotion.image if sale_promotion.image else '',
            'sub_image':
            sale_promotion.sub_image if sale_promotion.sub_image else '',
            'created_date':
            formats.date_format(sale_promotion.created_date,
                                "SHORT_DATETIME_FORMAT")
            if sale_promotion.created_date else '',
            'updated_date':
            formats.date_format(sale_promotion.updated_date,
                                "SHORT_DATETIME_FORMAT")
            if sale_promotion.updated_date else ''
        }

        return successful_response(data)
예제 #14
0
def update_proportion_kpi_team(request, pk):
    """
        API cập nhật tỷ trọng KPI Team \n
        Request body for this api : Không được bỏ trống \n
            {
                "data": [
                    {
                        "type": 0,
                        "leader_coefficient": 100
                    },
                    {
                        "type": 1,
                        "leader_coefficient": 90
                    },
                    {
                        "type": 2,
                        "leader_coefficient": 80
                    },
                    {
                        "type": 3,
                        "leader_coefficient": 70
                    },
                    {
                        "type": 4,
                        "leader_coefficient": 60
                    },
                    {
                        "type": 5,
                        "leader_coefficient": 50
                    },
                    {
                        "type": 6,
                        "leader_coefficient": 40
                    }
                ]
            }
    """
    try:
        area = Area.objects.filter(pk=pk).first()
        if area is None:
            return custom_response(Code.AREA_NOT_FOUND)

        body = json.loads(request.body)
        data = body.get('data')
        for i in data:
            if not isinstance(i['type'],
                              int) or i['type'] < 0 or i['type'] > 6:
                return custom_response(Code.INVALID_BODY, 'type Invalid')
            if not isinstance(
                    i['leader_coefficient'], int
            ) or i['leader_coefficient'] < 0 or i['leader_coefficient'] > 100:
                return custom_response(Code.INVALID_BODY,
                                       'leader_coefficient Invalid')

        for update_item in data:
            ProportionKpiTeam.objects.get_or_create(area=area,
                                                    type=update_item['type'])
            ProportionKpiTeam.objects.filter(
                area=area, type=update_item['type']).update(
                    leader_coefficient=update_item['leader_coefficient'])

        return successful_response()

    except Exception as e:
        logging.error('Update proportion kpi-team exception: %s', e)
        return custom_response(Code.INTERNAL_SERVER_ERROR)
예제 #15
0
def detail(request, pk):
    # API detail
    try:
        if request.user.is_superuser is False:
            shops = get_shops_viewable_queryset(request.user)
            merchant = Merchant.objects.filter(
                pk=pk, pk__in=shops.values('merchant')).first()
        else:
            merchant = Merchant.objects.filter(pk=pk).first()
        if merchant is None:
            return custom_response(Code.MERCHANT_NOT_FOUND)
        staff = merchant.get_staff()
        merchant_info = merchant.merchant_info
        data = {
            'merchant_id':
            merchant.id,
            'merchant_code':
            merchant.merchant_code,
            'merchant_brand':
            merchant.merchant_brand,
            'merchant_name':
            merchant.merchant_name,
            'address':
            merchant.address,
            'type':
            merchant.get_type().full_name if merchant.get_type() else '',
            'total_shop':
            merchant.shops.count(),
            'total_terminal':
            merchant.terminals.count(),
            'merchant_info': {
                'contact_name':
                merchant_info.contact_name if merchant_info else 'N/A'
            },
            'staff': {
                'full_name': staff.full_name if staff is not None else '',
                'email': staff.email if staff is not None else ''
            },
            'staff_care': {
                "full_name":
                merchant.staff_care.full_name
                if merchant.staff_care.full_name else 'N/A',
                "email":
                merchant.staff_care.email
                if merchant.staff_care.email else 'N/A',
                "team":
                merchant.staff_care.team.name
                if merchant.staff_care.team else 'N/A',
            } if merchant.staff_care else {
                "full_name": 'N/A',
                "email": 'N/A',
                "team": 'N/A',
            },
            'created_date':
            formats.date_format(merchant.created_date, "SHORT_DATETIME_FORMAT")
            if merchant.created_date else '',
            'status':
            int(merchant.get_status()) if merchant.get_status() else None,
            'merchant_cube':
            merchant.get_merchant_cube(),
        }
        return successful_response(data)
    except Exception as e:
        logging.error('Get detail merchant exception: %s', e)
        return custom_response(Code.INTERNAL_SERVER_ERROR)
예제 #16
0
    def update(self, request, pk):
        """
            API update Shop \n
            Request body for this api : Không được bỏ trống \n
                {
                    "name": "shop name" -- text,
                    "street": "Hoàng Cầu" -- text,
                    "address": "36 Hoàng Cầu, Đống Đa, Hà Nội" -- text,
                    "province_id": 57 -- number,
                    "district_id": 612 -- number,
                    "ward_id": 9464 -- number,
                    "description": "description" -- text,
                    "staff_id": 1016 -- number -- có thể để trống,

                }
        """
        try:
            shop = Shop.objects.filter(pk=pk).first()
            if shop is None:
                return custom_response(Code.SHOP_NOT_FOUND)
            body = json.loads(request.body)

            name = body.get('name')
            street = body.get('street')
            address = body.get('address')
            province_id = body.get('province_id')
            district_id = body.get('district_id')
            ward_id = body.get('ward_id')
            description = body.get('description')
            staff_id = body.get('staff_id')

            if name is None or name == '':
                return custom_response(Code.INVALID_BODY, 'name Invalid')

            if province_id is None or province_id == '' or not isinstance(
                    province_id, int):
                return custom_response(Code.INVALID_BODY,
                                       'province_id Invalid')
            if district_id is None or district_id == '' or not isinstance(
                    district_id, int):
                return custom_response(Code.INVALID_BODY,
                                       'district_id Invalid')
            if ward_id is None or ward_id == '' or not isinstance(
                    ward_id, int):
                return custom_response(Code.INVALID_BODY, 'ward_id Invalid')

            ward = QrWards.objects.get(pk=ward_id)
            if ward.get_district() is None or ward.get_province() is None:
                return custom_response(
                    Code.INVALID_BODY,
                    'can not find district or province from ward')
            if ward.get_district().id != district_id or ward.get_province(
            ).id != province_id:
                return custom_response(
                    Code.INVALID_BODY,
                    'ward, district or province do not mapping')

            if not isinstance(staff_id,
                              int) or staff_id is None or staff_id == '':
                if shop.staff is not None:
                    shop.staff_delete(request=request)
            else:
                staff = Staff.objects.get(pk=staff_id)
                if staff is None:
                    return custom_response(Code.INVALID_BODY,
                                           'staff_id Invalid')
                if shop.staff != staff:
                    if shop.staff is not None:
                        shop.staff_delete(request=request)
                    shop.staff_create(staff_id=staff_id, request=request)

            shop.name = name
            shop.street = street
            shop.address = address
            shop.province_id = province_id
            shop.district_id = district_id
            shop.ward_id = ward_id
            shop.description = description
            shop.save()

            refresh_shop_full_data()
            return successful_response()

        except Exception as e:
            logging.error('Update shop exception: %s', e)
            return custom_response(Code.INTERNAL_SERVER_ERROR)
예제 #17
0
def import_sale_merchant(request):
    """
        API import sale chăm sóc merchant bằng file excel \n
        Request body for this api : Định dạng form-data \n
            "merchant_file": file_excel_upload,
            "submit_total_row": 10,
            "submit_total_row_not_change": 2,
            "submit_total_row_update": 7,
            "submit_total_row_error": 1,
            "is_submit": true/false \n
    """
    dataset = Dataset()

    total_row, row_no_change, row_update, row_error = 0, 0, 0, 0

    merchant_file = request.FILES['merchant_file']
    data = json.loads(request.POST.get('data', None))

    is_submit = data.get('is_submit', None)
    submit_total_row = data.get('submit_total_row', None)
    submit_total_row_not_change = data.get('submit_total_row_not_change', None)
    submit_total_row_update = data.get('submit_total_row_update', None)
    submit_total_row_error = data.get('submit_total_row_error', None)

    is_submit = True if is_submit == 'true' else False

    try:
        imported_data = dataset.load(merchant_file.read())
    except Exception as e:
        return custom_response(Code.FILE_TYPE_ERROR)

    data_error = []

    for item in imported_data:
        data = {
            'merchant_code': str(item[0]).strip(),
            'staff_email': str(item[1]).strip(),
        }
        total_row += 1
        result = update_sale_merchant(request, data, is_submit)

        if result == 'Thành công':
            row_update += 1
        elif result == 'No change':
            row_no_change += 1
        else:
            row_error += 1
            data['update_status'] = result
            data_error.append(data)

    if is_submit:
        check_or_create_excel_folder()
        description = json.dumps(
            dict(total_row=submit_total_row,
                 row_no_change=submit_total_row_not_change,
                 row_update=submit_total_row_update,
                 row_error=submit_total_row_error))
        StaffCareImportLog(file_url=merchant_file,
                           description=description,
                           type=StaffCareType.STAFF_MERCHANT,
                           created_by=request.user).save()
        data = f'Cập nhật thành công {row_update}/{total_row} bản ghi'
    else:
        data = {
            'total_row':
            total_row,
            'row_no_change':
            row_no_change,
            'row_update':
            row_update,
            'row_error':
            row_error,
            'path_data_error':
            sale_merchant_render_excel_import_error(
                username=request.user.username, data=data_error)
        }

    return successful_response(data)
예제 #18
0
def import_view(request):
    """
        API import SalePromotion \n
        Request body for this api : Định dạng form-data \n
            "promotion_file": file_excel_upload,
            "title_id": 2,
            "title_code": "title_code",
            "title_description": "title_description",
            "is_submit": true/false \n
    """
    dataset = Dataset()

    promotion_file = request.FILES['promotion_file']
    data = request.POST.get('data', None)
    if data is None:
        return custom_response(Code.CANNOT_READ_DATA_BODY)
    try:
        data_json = json.loads(data)
    except Exception as e:
        logging.error(e)
        return custom_response(Code.CANNOT_CONVERT_DATA_BODY)

    title_id = data_json['title_id'] if 'title_id' in data_json else None
    title_code = data_json['title_code'] if 'title_code' in data_json else None
    title_description = data_json[
        'title_description'] if 'title_description' in data_json else None
    is_submit = data_json['is_submit'] if 'is_submit' in data_json else None

    is_submit = True if is_submit == 'true' else False

    if title_id is not None and title_id != '':
        promotion_title = SalePromotionTitle.objects.filter(
            pk=title_id).first()
        if promotion_title is None:
            return custom_response(Code.PROMOTION_TITLE_NOT_FOUND)
    else:
        if title_code is None or title_code == '':
            return custom_response(Code.INVALID_BODY, 'title_code invalid')
        promotion_title = SalePromotionTitle.objects.filter(
            code__iexact=title_code).first()
        if promotion_title is not None:
            return custom_response(
                Code.BAD_REQUEST, 'title_code be used by other PromotionTitle')
        promotion_title = SalePromotionTitle(code=title_code.upper(),
                                             description=title_description)
        if is_submit:
            promotion_title.save()

    try:
        promotion_rows = dataset.load(promotion_file.read())
    except Exception as e:
        logging.error('Promotion import file exception: %s', e)
        return custom_response(
            Code.INVALID_BODY,
            'Nội dung file sai định dạng, vui lòng tải file mẫu và làm theo.')

    total_row = 0
    row_create = 0
    row_no_change = 0
    row_update = 0
    row_error = 0
    data_error = []

    for item in promotion_rows:
        data = {
            'terminal_id': item[0],
            'merchant_code': item[1],
            'shop_code': item[2],
            'staff_email': item[3],
            'contact_person': item[4],
            'contact_phone_number': item[5],
            'contact_email': item[6],
            'update_status': ''
        }
        total_row += 1
        result = import_view_update_action(data, request, is_submit,
                                           promotion_title)
        if result == 'Tạo mới':
            row_create += 1
        elif result == 'Update staff' or result == 'Update contact info':
            row_update += 1
        elif result == 'No change':
            row_no_change += 1
        else:
            row_error += 1
            data['update_status'] = result
            data_error.append(data)

    if is_submit:
        data = "Cập nhật thành công " + str(
            row_create + row_update) + "/" + str(total_row) + " bản ghi"
    else:
        data = {
            'total_row': total_row,
            'row_create': row_create,
            'row_no_change': row_no_change,
            'row_update': row_update,
            'row_error': row_error,
            'path_data_error':
            render_excel_import_error(request.user, data_error)
        }
    return successful_response(data)
예제 #19
0
    def update(self, request, pk):
        """
            API update user info \n
            Request body for this api : Không được bỏ trống \n
                {
                    "is_active": boolean true/false,
                    "role_name": text,
                    "area_ids": [1,2..],
                    "user_permissions": [1,2,3,4,5,6...],
                }
        """
        user = User.objects.filter(pk=pk).first()
        if user is None:
            return custom_response(Code.USER_NOT_FOUND)

        try:
            body = json.loads(request.body)

            is_active = body.get('is_active')
            is_manager_outside_vnpay = body.get('is_manager_outside_vnpay')
            role_name = body.get('role_name')
            area_ids = body.get('area_ids')
            team_ids = body.get('team_ids')
            user_permissions = body.get('user_permissions')

            if is_active is None or is_active not in ['true', 'false']:
                return custom_response(Code.INVALID_BODY,
                                       'Field is_active not valid')

            if is_manager_outside_vnpay is None or is_manager_outside_vnpay not in [
                    'true', 'false'
            ]:
                return custom_response(
                    Code.INVALID_BODY,
                    'Field is_manager_outside_vnpay not valid')

            if role_name is None or role_name == '' or not isinstance(
                    role_name, str):
                return custom_response(Code.INVALID_BODY,
                                       'Field role_name not valid')

            role_name = role_name.upper()

            # Admin
            if role_name == ROLE_ADMIN:
                user.groups.clear()
                user.area_set.clear()
                user.user_permissions.clear()
                user.is_superuser = True
                user.is_area_manager = False
                user.is_sale_admin = False
                user.is_active = (is_active == 'true')
                user.save()
                return successful_response()

            # validate list permission
            if user_permissions is None or not isinstance(
                    user_permissions, list):
                return custom_response(Code.INVALID_BODY,
                                       'List user-permission not valid')
            if Permission.objects.filter(
                    pk__in=user_permissions).count() != len(user_permissions):
                return custom_response(Code.PERMISSION_NOT_FOUND)

            group = Group.objects.filter(name=role_name)
            if not group:
                return custom_response(Code.GROUP_NOT_FOUND)

            if role_name == ROLE_SALE_MANAGER or role_name == ROLE_SALE_ADMIN:
                if user.is_manager_outside_vnpay or (is_manager_outside_vnpay
                                                     == 'true'):
                    # Check định dạng team_ids nếu role là ROLE_SALE_MANAGER / ROLE_SALE_ADMIN và là người Tripi, Teko
                    if not isinstance(team_ids, list):
                        return custom_response(Code.INVALID_BODY,
                                               'List Team not valid')
                    if Team.objects.filter(
                            pk__in=team_ids).count() != len(team_ids):
                        return custom_response(Code.TEAM_NOT_FOUND)
                    user.team_set.set(team_ids)
                else:
                    # Check định dạng area_ids nếu role là ROLE_SALE_MANAGER / ROLE_SALE_ADMIN và là người VNpay
                    if not isinstance(area_ids, list):
                        return custom_response(Code.INVALID_BODY,
                                               'List Area not valid')
                    if Area.objects.filter(
                            pk__in=area_ids).count() != len(area_ids):
                        return custom_response(Code.AREA_NOT_FOUND)
                    user.area_set.set(area_ids)

                user.groups.set(group)
                user.is_superuser = False
                user.is_area_manager = True if role_name == ROLE_SALE_MANAGER else False
                user.is_sale_admin = True if role_name == ROLE_SALE_ADMIN else False

            if role_name == ROLE_SALE_LEADER or role_name == ROLE_SALE:
                user.groups.set(group)
                user.area_set.clear()
                user.is_superuser = False
                user.is_area_manager = False
                user.is_sale_admin = False

            user.is_manager_outside_vnpay = (
                is_manager_outside_vnpay == 'true')
            user.is_active = (is_active == 'true')
            user.save()
            user.user_permissions.set(user_permissions)

            return successful_response()

        except Exception as e:
            logging.error('Update team exception: %s', e)
            print(e)
            return custom_response(Code.INTERNAL_SERVER_ERROR)
예제 #20
0
    def update(self, request, pk):
        """
            API update SalePromotion \n
            Request body for this api : Định dạng json \n
                {
                    "tentcard_ctkm": true/false,
                    "wobbler_ctkm": true/false,
                    "status": 2 (status in {0,1,2,3} ),
                    "image": "text",
                    "sub_image": "text"
                }
        """
        sale_promotion = SalePromotion.objects.filter(pk=pk).first()
        if sale_promotion is None:
            return custom_response(Code.PROMOTION_NOT_FOUND)

        body = json.loads(request.body)

        status = body.get('status')
        tentcard_ctkm = body.get('tentcard_ctkm')
        wobbler_ctkm = body.get('wobbler_ctkm')
        image = body.get('image')
        sub_image = body.get('sub_image')

        try:
            status = int(status) if status is not None else None
        except ValueError:
            return custom_response(Code.STATUS_NOT_VALID)

        if status is None or not 0 <= status <= 3:
            return custom_response(Code.STATUS_NOT_VALID)

        tentcard_ctkm = True if tentcard_ctkm is not None and tentcard_ctkm == 'true' else False
        wobbler_ctkm = True if wobbler_ctkm is not None and wobbler_ctkm == 'true' else False

        # Tao folder save image
        location = settings.FS_IMAGE_UPLOADS + datetime.date.today().isoformat(
        )
        base_url = settings.FS_IMAGE_URL + datetime.date.today().isoformat()
        if not os.path.exists(location):
            os.makedirs(location)

        if image is not None and image != '':
            promotion_image_filename = str(
                request.user.username) + '-promo_image' + str(
                    time_f()) + '.png'
            with open(location + '/' + promotion_image_filename, "wb") as f:
                f.write(base64.b64decode(image[23:]))
                f.close()
                sale_promotion.image = base_url + '/' + promotion_image_filename

        elif status != 0 and (sale_promotion.image is None
                              or sale_promotion.image == ''):
            return custom_response(
                Code.BAD_REQUEST,
                'Cần upload ảnh nghiệm thu với trạng thái hiện tại của shop')

        if sub_image is not None and sub_image != '':
            sale_promotion.sub_image = sub_image
            promotion_sub_image_filename = str(
                request.user.username) + '-promo_sub_image' + str(
                    time_f()) + '.png'
            with open(location + '/' + promotion_sub_image_filename,
                      "wb") as f:
                f.write(base64.b64decode(sub_image[23:]))
                f.close()
                sale_promotion.sub_image = base_url + '/' + promotion_sub_image_filename

        sale_promotion.status = status
        sale_promotion.tentcard_ctkm = tentcard_ctkm
        sale_promotion.wobbler_ctkm = wobbler_ctkm
        sale_promotion.updated_by = request.user

        sale_promotion.save()
        return successful_response()
예제 #21
0
def detail(request, pk):
    try:
        if request.user.is_superuser is False:
            if request.user.is_area_manager or request.user.is_sale_admin:
                provinces = get_provinces_viewable_queryset(request.user)
                terminal = Terminal.objects.filter(pk=pk, province_code__in=provinces.values('province_code')).first()
            else:
                shops = get_shops_viewable_queryset(request.user)
                terminal = Terminal.objects.filter(pk=pk, shop__in=shops).first()
        else:
            terminal = Terminal.objects.filter(pk=pk).first()

        if terminal is None:
            return custom_response(Code.TERMINAL_NOT_FOUND)

        merchant = terminal.merchant
        shop = terminal.shop
        staff = shop.staff if shop else None
        team = staff.team if staff else None
        staff_chain = shop.staff_of_chain if shop else None
        team_chain = staff_chain.team if staff_chain else None

        data = {
            'id': terminal.id,
            'terminal_id': terminal.terminal_id,
            'terminal_name': terminal.terminal_name,
            'terminal_address': terminal.terminal_address,
            'province': {'id': terminal.get_province().id,
                         'name': terminal.get_province().province_name,
                         'code': terminal.get_province().province_code} if terminal.get_province() else None,
            'district': {'id': terminal.get_district().id,
                         'name': terminal.get_district().district_name,
                         'code': terminal.get_district().district_code} if terminal.get_district() else None,
            'wards': {'id': terminal.get_wards().id,
                      'name': terminal.get_wards().wards_name,
                      'code': terminal.get_wards().wards_code} if terminal.get_wards() else None,
            'business_address': terminal.business_address,
            'merchant': {
                'id': merchant.id if merchant else '',
                'name': merchant.merchant_name if merchant else '',
                'code': merchant.merchant_code if merchant else '',
                'brand': merchant.merchant_brand if merchant else '',
            },
            'shop': {
                'id': shop.id if shop else '',
                'name': shop.name if shop else '',
                'code': shop.code if shop else '',
                'address': shop.address if shop else '',
                'street': shop.street if shop else '',
                'take_care_status': shop.take_care_status if shop else '',
                'activated': shop.activated if shop else '',
                'province_name': shop.province.province_name if (shop and shop.province) else '',
                'district_name': shop.district.district_name if (shop and shop.district) else '',
                'wards_name': shop.wards.wards_name if (shop and shop.wards) else '',
                'staff': {
                    'id': staff.id if staff else None,
                    'full_name': staff.full_name if staff else '',
                    'email': staff.email if staff else ''
                },
                'team': {
                    'id': team.id if team else None,
                    'code': team.code if team else '',
                    'name': team.name if team else ''
                },
                'staff_chain': {
                    'id': staff_chain.id if staff_chain else None,
                    'full_name': staff_chain.full_name if staff_chain else '',
                    'email': staff_chain.email if staff_chain else ''
                },
                'team_chain': {
                    'id': team_chain.id if team_chain else None,
                    'code': team_chain.code if team_chain else '',
                    'name': team_chain.name if team_chain else ''
                }
            },
            'created_date': formats.date_format(terminal.created_date,
                                                "SHORT_DATETIME_FORMAT") if terminal.created_date else '',
            'status': int(terminal.get_status()) if terminal.get_status() else None,
        }
        return successful_response(data)
    except Exception as e:
        logging.error('Get detail terminal exception: %s', e)
        return custom_response(Code.INTERNAL_SERVER_ERROR)
예제 #22
0
 def update(self, request, pk):
     """
         API update Terminal
     """
     return custom_response(Code.SUCCESS, "update method")
예제 #23
0
    def retrieve(self, request, pk):
        """
            API get detail Shop
        """
        if request.user.is_superuser is False:
            if request.user.is_area_manager or request.user.is_sale_admin:
                provinces = get_provinces_viewable_queryset(request.user)
                shop = Shop.objects.filter(pk=pk,
                                           province__in=provinces).first()
            else:
                shops = get_shops_viewable_queryset(request.user)
                shop = Shop.objects.filter(pk=pk, pk__in=shops).first()
        else:
            shop = Shop.objects.filter(pk=pk).first()

        if shop is None:
            return custom_response(Code.SHOP_NOT_FOUND)

        first_terminal = shop.terminals.order_by('created_date').first()

        if shop.shop_cube and shop.shop_cube.voucher_code_list is not None and shop.shop_cube.voucher_code_list != '[]':
            if '[' not in shop.shop_cube.voucher_code_list:
                voucher_code_list = shop.shop_cube.voucher_code_list
            else:
                voucher_code_list = ast.literal_eval(
                    shop.shop_cube.voucher_code_list)
        else:
            voucher_code_list = ''

        data = {
            'name':
            shop.name,
            'code':
            shop.code,
            'address':
            shop.address,
            'street':
            shop.street,
            'phone':
            first_terminal.qr_terminal_contact.terminal_phone if
            (first_terminal and first_terminal.qr_terminal_contact) else None,
            'created_date':
            formats.date_format(shop.created_date, "SHORT_DATETIME_FORMAT")
            if shop.created_date else '',
            'first_terminal_created_date':
            formats.date_format(first_terminal.created_date,
                                "SHORT_DATETIME_FORMAT")
            if first_terminal and first_terminal.created_date else None,
            'merchant': {
                'id':
                shop.merchant.id if shop.merchant else None,
                'merchant_code':
                shop.merchant.merchant_code if shop.merchant else None,
                'merchant_name':
                shop.merchant.merchant_name if shop.merchant else None,
                'merchant_brand':
                shop.merchant.merchant_brand if shop.merchant else None
            },
            'staff': {
                'id': shop.staff.id if shop.staff else None,
                'full_name': shop.staff.full_name if shop.staff else None,
                'email': shop.staff.email if shop.staff else None,
                'phone': shop.staff.mobile if shop.staff else None,
            },
            'team': {
                'id': shop.team.id if shop.team else None,
                'name': shop.team.name if shop.team else None,
                'code': shop.team.code if shop.team else None
            },
            'staff_of_chain': {
                'id':
                shop.staff_of_chain.id if shop.staff_of_chain else None,
                'full_name':
                shop.staff_of_chain.full_name if shop.staff_of_chain else None,
                'email':
                shop.staff_of_chain.email if shop.staff_of_chain else None,
                'phone':
                shop.staff_of_chain.mobile if shop.staff_of_chain else None,
            },
            'team_of_chain': {
                'id': shop.team_of_chain.id if shop.team_of_chain else None,
                'name':
                shop.team_of_chain.name if shop.team_of_chain else None,
                'code': shop.team_of_chain.code if shop.team_of_chain else None
            },
            'shop_cube': {
                'report_date': shop.shop_cube.report_date,
                'number_of_tran_acm': shop.shop_cube.number_of_tran_acm,
                'number_of_tran_last_m': shop.shop_cube.number_of_tran_last_m,
                'number_of_tran': shop.shop_cube.number_of_tran,
                'number_of_tran_w_1_7': shop.shop_cube.number_of_tran_w_1_7,
                'number_of_tran_w_8_14': shop.shop_cube.number_of_tran_w_8_14,
                'number_of_tran_w_15_21':
                shop.shop_cube.number_of_tran_w_15_21,
                'number_of_tran_w_22_end':
                shop.shop_cube.number_of_tran_w_22_end,
                'voucher_code_list': voucher_code_list,
            } if shop.shop_cube else None,
            'province': {
                'id': shop.province.id,
                'name': shop.province.province_name,
                'code': shop.province.province_code
            } if shop.province else None,
            'district': {
                'id': shop.district.id,
                'name': shop.district.district_name,
                'code': shop.district.district_code
            } if shop.district else None,
            'wards': {
                'id': shop.wards.id,
                'name': shop.wards.wards_name,
                'code': shop.wards.wards_code
            } if shop.wards else None,
        }

        return successful_response(data)
예제 #24
0
def import_sale_shop(request):
    """
        API import sale chăm sóc shop bằng file excel \n
        Request body for this api : Định dạng form-data \n
            "shop_file": file_excel_upload,
            "submit_total_row": 10,
            "submit_total_row_not_change": 2,
            "submit_total_row_update": 7,
            "submit_total_row_error": 1,
            "is_submit": true/false \n
    """
    dataset = Dataset()

    total_row, row_no_change, row_update, row_error = 0, 0, 0, 0

    shop_file = request.FILES['shop_file']
    data = json.loads(request.POST.get('data', None))

    is_submit = data.get('is_submit', None)
    submit_total_row = data.get('submit_total_row', None)
    submit_total_row_not_change = data.get('submit_total_row_not_change', None)
    submit_total_row_update = data.get('submit_total_row_update', None)
    submit_total_row_error = data.get('submit_total_row_error', None)

    is_submit = True if is_submit == 'true' else False

    try:
        imported_data = dataset.load(shop_file.read())
    except Exception as e:
        return custom_response(Code.FILE_TYPE_ERROR)

    data_error = []

    ocg_staff_ids = QrStaff.objects.filter(
        email__in=settings.LIST_OCG_EMAIL).values('staff_id')
    ocg_merchants = Merchant.objects.filter(staff__in=ocg_staff_ids)
    ocg_shops = Shop.objects.filter(merchant__in=ocg_merchants).values('id')

    ocg_shop_ids = []
    for ocg_shop in ocg_shops:
        ocg_shop_ids.append(ocg_shop['id'])

    for item in imported_data:
        data = {
            'code':
            int(item[0]) if
            (isinstance(item[0], int) and item[0] != '') else '',
            'street':
            item[1],
            'staff_email':
            str(item[2]).strip() if item[2] else '',
        }
        total_row += 1
        if isinstance(item[0], int) and int(item[0]) in ocg_shop_ids:
            result = 'Shop này do OCG khai thác'
        else:
            result = update_sale_shop(request, data, is_submit)

        if result == 'Thành công':
            row_update += 1
        elif result == 'No change':
            row_no_change += 1
        else:
            row_error += 1
            data['update_status'] = result
            data_error.append(data)

    if is_submit:
        check_or_create_excel_folder()
        description = json.dumps(
            dict(total_row=submit_total_row,
                 row_no_change=submit_total_row_not_change,
                 row_update=submit_total_row_update,
                 row_error=submit_total_row_error))
        StaffCareImportLog(file_url=shop_file,
                           description=description,
                           type=StaffCareType.STAFF_SHOP,
                           created_by=request.user).save()
        data = f'Cập nhật thành công {row_update}/{total_row} bản ghi'

        refresh_shop_full_data()
    else:
        data = {
            'total_row':
            total_row,
            'row_no_change':
            row_no_change,
            'row_update':
            row_update,
            'row_error':
            row_error,
            'path_data_error':
            sale_shop_render_excel_import_error(username=request.user.username,
                                                data=data_error)
        }

    return successful_response(data)
예제 #25
0
    def create(self, request):
        """
            API create Pos365 \n
            Request body for this api : Định dạng form-data \n
                "code": "IRNARF",
                "contract_duration": 1, (type in {0,1,2,3,4,5,6,...} )
                "contract_coefficient": 100,
                "staff_id": 1210,
                "contract_team": 1210,
                "contract_start_date": "25/01/2020" (format date in %d/%m/%Y),
                "contract_url": "https://canifa.vn",
                "contract_product_quantity": 1,
                "contract_product_series": "JX-13231; YG-14r638",
                "contract_revenue": 150000,
                "contract_note": "Đây là ghi chú mẫu",
                "contract_file": "",
                "customer_merchant": "Canifa",
                "customer_name": "Đào Hải Long",
                "customer_phone": "038123456",
                "customer_address": "36 Hoàng Cầu, Q Đống Đa, Hà Nội"
                "customer_province": 1 -- number,
        """
        try:
            data = json.loads(request.POST.get('data'))

            code = data.get('code', None)
            contract_duration = data.get('contract_duration', None)
            contract_coefficient = data.get('contract_coefficient', None)
            staff_id = data.get('staff_id', None)
            is_collaborators = data.get('is_collaborators', None)
            contract_team = data.get('contract_team', None)
            contract_url = data.get('contract_url', None)
            contract_product_quantity = data.get('contract_product_quantity',
                                                 None)
            contract_product_series = data.get('contract_product_series', None)
            contract_revenue = data.get('contract_revenue', None)
            contract_note = data.get('contract_note', None)
            contract_start_date = data.get('contract_start_date', None)
            contract_file = request.FILES[
                'contract_file'] if 'contract_file' in request.FILES else None
            customer_merchant = data.get('customer_merchant', None)
            customer_name = data.get('customer_name', None)
            customer_phone = data.get('customer_phone', None)
            customer_address = data.get('customer_address', None)
            customer_province = data.get('customer_province', None)

            if contract_duration is not None and contract_duration != '':
                if not (isinstance(contract_duration, int) or
                        (ExchangePointPos365.objects.filter(
                            pk=contract_duration).count() != 1)):
                    return custom_response(Code.INVALID_BODY,
                                           'contract_duration Invalid')

            if contract_coefficient is not None and contract_coefficient != '':
                if not (isinstance(contract_coefficient, int)
                        and 0 <= contract_coefficient <= 100):
                    return custom_response(Code.INVALID_BODY,
                                           'contract_coefficient Invalid')

            if code is None or code == '':
                return custom_response(Code.INVALID_BODY, 'code Invalid')
            code = format_string(code)

            if Pos365.objects.filter(code__iexact=code):
                return custom_response(Code.BAD_REQUEST,
                                       'code be used by other Pos365')

            if is_collaborators:
                if (not isinstance(contract_team, int)) or (
                        Team.objects.filter(pk=contract_team).count() != 1):
                    return custom_response(Code.TEAM_NOT_FOUND)
                else:
                    contract_team = Team.objects.get(pk=contract_team)
            else:
                if (not isinstance(staff_id, int)) or (
                        Staff.objects.filter(pk=staff_id).count() != 1):
                    return custom_response(Code.STAFF_NOT_FOUND)

            if not isinstance(contract_product_quantity, int):
                return custom_response(Code.BAD_REQUEST,
                                       'Số lượng sản phẩm phải số nguyên')

            if contract_file is not None:
                fs = FileSystemStorage(location=settings.FS_DOCUMENT_UPLOADS +
                                       datetime.date.today().isoformat(),
                                       base_url=settings.FS_DOCUMENT_URL +
                                       datetime.date.today().isoformat())
                file_type = os.path.splitext(contract_file.name)[1]
                filename = fs.save(
                    str(request.user.username) + str(time()) + file_type,
                    contract_file)
                uploaded_file_url = fs.url(filename)
            else:
                uploaded_file_url = None

            contract_url = format_string(contract_url)
            contract_product_quantity = int(contract_product_quantity)
            contract_product_series = format_string(contract_product_series)
            contract_note = format_string(contract_note)
            contract_start_date = dt_datetime.strptime(
                contract_start_date[:10], '%Y-%m-%d')

            customer_merchant = format_string(customer_merchant)
            customer_name = format_string(customer_name)
            customer_phone = format_string(customer_phone)
            customer_address = format_string(customer_address)
            province = QrProvince.objects.filter(
                pk=int(customer_province)).first()
            if not province:
                return custom_response(Code.BAD_REQUEST, 'Wrong Province')

            pos365 = Pos365(
                code=code,
                contract_duration=contract_duration,
                contract_coefficient=contract_coefficient,
                staff_id=staff_id,
                contract_team=contract_team,
                contract_url=contract_url,
                contract_product_quantity=contract_product_quantity,
                contract_product_series=contract_product_series,
                contract_revenue=contract_revenue,
                contract_note=contract_note,
                contract_start_date=contract_start_date,
                contract_file=uploaded_file_url,
                customer_merchant=customer_merchant,
                customer_name=customer_name,
                customer_phone=customer_phone,
                customer_address=customer_address,
                customer_province=province,
                created_by=request.user,
                updated_by=request.user)
            pos365.save()

            return successful_response(pos365.id)

        except Exception as e:
            logging.error('Create pos365 exception: %s', e)
            return custom_response(Code.INTERNAL_SERVER_ERROR)