Exemple #1
0
    def match_item(self, item):
        assert isinstance(item, VerificationItemData)
        from lib.utils import get_intersection_of_lists
        found_matching = False

        if self.categories['in'] or self.categories['not_in']:
            if (self.categories['in'] and get_intersection_of_lists(self.categories['in'], item.category)) \
                    or (self.categories['not_in']
                        and not get_intersection_of_lists(self.categories['not_in'], item.category)):
                found_matching = True
            else:
                return MatchStatus.found_not_matching

        if self.products['in'] or self.products['not_in']:
            if (self.products['in'] and get_intersection_of_lists(self.products['in'], item.product)) \
                    or (self.products['not_in']
                        and not get_intersection_of_lists(self.products['not_in'], item.product)):
                found_matching = True
            else:
                return MatchStatus.found_not_matching

        if self.sellers:
            if item.seller in self.sellers:
                found_matching = True
            else:
                return MatchStatus.found_not_matching

        if found_matching:
            return MatchStatus.found_matching
        else:
            return MatchStatus.not_found
Exemple #2
0
def cleanup_rules():
    rule_criteria_class = getattr(
            importlib.import_module(
                method_dict.get('criteria_class')['package']),
            method_dict.get('criteria_class')['attribute'])
    db = CouponsAlchemyDB()
    rule_dict_list = db.find("rule")
    for rule_dict in rule_dict_list:
        rule_dict['id'] = binascii.b2a_hex(rule_dict['id'])
        rule = Rule(**rule_dict)
        criteria_dict = canonicaljson.json.loads(rule.criteria_json)
        if rule.blacklist_criteria_json:
            blacklist_dict = canonicaljson.json.loads(rule.blacklist_criteria_json)
        else:
            blacklist_dict = dict()

        all_list = ['all']

        criteria_payment_modes = criteria_dict.get('payment_modes')
        if criteria_payment_modes:
            criteria_payment_modes = [criteria_payment_mode.lower() for criteria_payment_mode in criteria_payment_modes]

        if criteria_payment_modes and get_intersection_of_lists(criteria_payment_modes, all_list):
            del criteria_dict['payment_modes']

        blacklist_criteria_payment_modes = blacklist_dict.get('payment_modes')
        if blacklist_criteria_payment_modes:
            blacklist_criteria_payment_modes = [blacklist_criteria_payment_mode.lower() for blacklist_criteria_payment_mode in blacklist_criteria_payment_modes]

        if blacklist_criteria_payment_modes and get_intersection_of_lists(blacklist_criteria_payment_modes, all_list):
            del blacklist_dict['payment_modes']
        try:
            criteria_dict['valid_on_order_no'] = fix_order_no(criteria_dict.get('valid_on_order_no'))
        except ValueError:
            success = False
            # error.append(u'Invalid value in valid_on_order_no in rule criteria')

        try:
            blacklist_dict['valid_on_order_no'] = fix_order_no(blacklist_dict.get('valid_on_order_no'))
        except ValueError:
            success = False
            # error.append(u'Invalid value in valid_on_order_no in rule blacklist criteria')
        benefit_dict = canonicaljson.json.loads(rule.benefits_json)
        rule_criteria = rule_criteria_class(**criteria_dict)
        rule_blacklist_criteria = rule_criteria_class(**blacklist_dict)
        benefits = Benefits(**benefit_dict)
        values = dict()
        values['id'] = rule.id_bin
        values['criteria_json'] = rule_criteria.canonical_json()
        values['blacklist_criteria_json'] = rule_blacklist_criteria.canonical_json()
        values['benefits_json'] = benefits.canonical_json()
        un_hashed_string = unicode(values['criteria_json']) + \
            unicode(values['criteria_json']) + unicode(values['criteria_json'])
        values['sha2hash'] = hashlib.sha256(un_hashed_string).hexdigest()
        db.update_row("rule", "id", **values)
def match_in_not_in(criteria, value):
    found_matching = MatchStatus.not_found

    if criteria and 'in' in criteria and criteria['in'] is not None:
        if get_intersection_of_lists(criteria['in'], value):
            found_matching = MatchStatus.found_matching
        else:
            return MatchStatus.found_not_matching
    if criteria and 'not_in' in criteria and criteria['not_in'] is not None:
        if get_intersection_of_lists(criteria['not_in'], value):
            return MatchStatus.found_not_matching
        else:
            found_matching = MatchStatus.found_matching

    return found_matching
def validate_for_create_coupon(data):
    error = list()
    success = True

    rules = data.get('rules')

    for rule in rules:
        criteria = rule.get('criteria')

        if criteria.get('range_max') and criteria.get('range_min') and \
                        criteria.get('range_max') < criteria.get('range_min'):
            success = False
            error.append(u'range_max must not be less than range_min')

        if criteria.get('cart_range_max') and criteria.get('cart_range_min') and \
                        criteria.get('cart_range_max') < criteria.get('cart_range_min'):
            success = False
            error.append(u'cart_range_max must not be less than cart_range_min')

        in_categories = criteria.get('categories', dict()).get('in')

        not_in_categories = criteria.get('categories', dict()).get('not_in')

        if in_categories and not_in_categories:
            intersection = get_intersection_of_lists(in_categories, not_in_categories)
            if intersection:
                success = False
                error.append(
                    u'Categories[in] and Categories[not_in] must not have any category in common in a rule {}'.format(
                        intersection))

        in_products = criteria.get('products', dict()).get('in')

        not_in_products = criteria.get('products', dict()).get('not_in')

        if in_products and not_in_products:
            intersection = get_intersection_of_lists(in_products, not_in_products)
            if intersection:
                success = False
                error.append(
                    u'Products[in] and products[not_in] must not have any product in common in a rule {}'.format(
                        intersection))

    return success, error
Exemple #5
0
    def match_criteria(self, order, code):
        from lib.utils import get_intersection_of_lists
        found_matching = False

        if self.valid_on_order_no:
            exact_order_no_list = list()
            min_order_no = None
            for an_order_no in self.valid_on_order_no:
                try:
                    # to convert order nos which are exact integers
                    exact_order_no_list.append(int(an_order_no))
                except ValueError:
                    # to convert order nos which are like 4+ means minimum order no 4
                    if not min_order_no:
                        min_order_no = int(an_order_no[:-1])

            if exact_order_no_list or min_order_no:
                # if minimum order no is given 1 (1+), than the condition is true always.
                # else fetch order details and check if the coupon is valid on
                # that particular order no
                if min_order_no and min_order_no is 1:
                    found_matching = True
                else:
                    from api.v1.utils import fetch_user_details
                    success, order_no, error = fetch_user_details(
                        order.customer_id)
                    if not success:
                        raise UserNotFoundException()
                    order_no += 1
                    order.order_no = order_no
                    if (exact_order_no_list and order.order_no in exact_order_no_list) \
                            or (min_order_no and order.order_no >= min_order_no):
                        found_matching = True
                    else:
                        return MatchStatus.found_not_matching, u'This coupon {} is not applicable on this order'.format(
                            code)

        if self.channels:
            if order.channel in self.channels:
                found_matching = True
            else:
                return MatchStatus.found_not_matching, u'This coupon {} is only valid on orders from {}'.format(
                    code, ','.join([Channels(c).name for c in self.channels]))

        if self.country:
            if get_intersection_of_lists(self.country, order.country):
                found_matching = True
            else:
                return MatchStatus.found_not_matching, u'This coupon {} is not valid in your country'.format(
                    code)

        if self.state:
            if get_intersection_of_lists(self.state, order.state):
                found_matching = True
            else:
                return MatchStatus.found_not_matching, u'This coupon {} is not valid in your state'.format(
                    code)

        if self.city:
            if get_intersection_of_lists(self.city, order.city):
                found_matching = True
            else:
                return MatchStatus.found_not_matching, u'This coupon {} is not valid in your city'.format(
                    code)

        if self.zone:
            if get_intersection_of_lists(self.zone, order.zone):
                found_matching = True
            else:
                return MatchStatus.found_not_matching, u'This coupon {} is not valid in your zone'.format(
                    code)

        if self.area:
            if order.area in self.area:
                found_matching = True
            else:
                return MatchStatus.found_not_matching, u'This coupon {} is not valid in your area'.format(
                    code)

        if self.source:
            if order.source in self.source:
                found_matching = True
            else:
                return MatchStatus.found_not_matching, u'This coupon {} is not valid on this order'.format(
                    code)

        if found_matching:
            return MatchStatus.found_matching, None
        else:
            return MatchStatus.not_found, None
def match_list_intersection_atleast_one_common(criteria_list, value_list):
    if get_intersection_of_lists(criteria_list, value_list):
        return True
    return False
Exemple #7
0
def validate_for_create_coupon(data):
    error = list()
    success = True

    rules = data.get('rules')

    for rule in rules:
        criteria = rule.get('criteria')
        blacklist_criteria = rule.get('blacklist_criteria')

        if criteria.get('range_max') and criteria.get('range_min') and \
                        criteria.get('range_max') < criteria.get('range_min'):
            success = False
            error.append(u'range_max must not be less than range_min')

        if criteria.get('cart_range_max') and criteria.get('cart_range_min') and \
                        criteria.get('cart_range_max') < criteria.get('cart_range_min'):
            success = False
            error.append(
                u'cart_range_max must not be less than cart_range_min')

        in_categories = criteria.get('categories').get('in')

        not_in_categories = criteria.get('categories').get('not_in')

        if in_categories and not_in_categories:
            intersection = get_intersection_of_lists(in_categories,
                                                     not_in_categories)
            if intersection:
                success = False
                error.append(
                    u'Categories[in] and Categories[not_in] must not have any category in common in a rule {}'
                    .format(intersection))

        in_products = criteria.get('products', dict()).get('in')

        not_in_products = criteria.get('products', dict()).get('not_in')

        if in_products and not_in_products:
            intersection = get_intersection_of_lists(in_products,
                                                     not_in_products)
            if intersection:
                success = False
                error.append(
                    u'Products[in] and products[not_in] must not have any product in common in a rule {}'
                    .format(intersection))

        all_list = ['all']

        criteria_payment_modes = criteria.get('payment_modes')
        if criteria_payment_modes:
            criteria_payment_modes = [
                criteria_payment_mode.lower()
                for criteria_payment_mode in criteria_payment_modes
            ]

        if criteria_payment_modes and get_intersection_of_lists(
                criteria_payment_modes, all_list):
            del criteria['payment_modes']

        blacklist_criteria_payment_modes = blacklist_criteria.get(
            'payment_modes')
        if blacklist_criteria_payment_modes:
            blacklist_criteria_payment_modes = [
                blacklist_criteria_payment_mode.lower()
                for blacklist_criteria_payment_mode in
                blacklist_criteria_payment_modes
            ]

        if blacklist_criteria_payment_modes and get_intersection_of_lists(
                blacklist_criteria_payment_modes, all_list):
            del blacklist_criteria['payment_modes']

        try:
            criteria['valid_on_order_no'] = fix_order_no(
                criteria.get('valid_on_order_no'))
        except ValueError:
            success = False
            error.append(
                u'Invalid value in valid_on_order_no in rule criteria')

        try:
            blacklist_criteria['valid_on_order_no'] = fix_order_no(
                blacklist_criteria.get('valid_on_order_no'))
        except ValueError:
            success = False
            error.append(
                u'Invalid value in valid_on_order_no in rule blacklist criteria'
            )

    return success, error
Exemple #8
0
def get_benefits_new(order):
    products_dict = dict()
    benefits_list = list()
    payment_modes_list = list()
    channels_list = list()
    for item in order.items:
        product_dict = dict()
        product_dict['itemid'] = item.item_id
        product_dict['quantity'] = item.quantity
        product_dict['discount'] = 0.0
        product_dict['agent_discount'] = 0.0
        product_dict['cashback'] = 0.0
        product_dict['agent_cashback'] = 0.0
        products_dict[item.item_id] = product_dict
    for existing_voucher in order.existing_vouchers:
        rules = existing_voucher['voucher'].rules_list
        for rule in rules:
            benefits = rule.benefits_obj
            benefit_list = benefits.data
            total = existing_voucher['total']
            item_id_list = existing_voucher['item_id_list']
            custom_dict = None
            if not benefit_list and existing_voucher['voucher'].custom:
                try:
                    custom_dict = json.loads(
                        existing_voucher['voucher'].custom)
                except:
                    pass
                if custom_dict and custom_dict.get('Param'):
                    cashback = {
                        'type': BenefitType.cashback_amount.value,
                        'value': '?'
                    }
                    benefit_list.append(cashback)
            for benefit in benefit_list:
                benefit_dict = dict()
                benefit_dict['max_cap'] = None
                amount = 0.0
                amount_actual = 0.0
                max_cap = 0.0
                freebie_list = list()
                benefit_type = BenefitType(benefit['type'])
                if benefit_type is BenefitType.freebie:
                    freebie_list.append(benefit['value'])
                else:
                    if benefit['value'] is None:
                        continue
                    if benefit_type in [
                            BenefitType.amount,
                            BenefitType.cashback_amount,
                            BenefitType.agent_amount,
                            BenefitType.agent_cashback_amount,
                    ]:
                        amount = benefit['value']

                    elif benefit_type in [
                            BenefitType.percentage,
                            BenefitType.cashback_percentage,
                            BenefitType.agent_percentage,
                            BenefitType.agent_cashback_percentage
                    ]:
                        percentage = benefit['value']
                        amount = percentage * total / 100
                        amount_actual = amount
                        max_cap = benefit.get('max_cap')
                        benefit_dict['max_cap'] = max_cap
                        if max_cap and amount > max_cap:
                            amount = max_cap

                    if benefit_type is BenefitType.cashback_amount and benefit[
                            'value']:
                        amount = 0 if benefit['value'] == '?' else benefit[
                            'value']

                    for item in order.items:

                        if item.item_id in item_id_list:

                            item_amount = (item.quantity * item.price *
                                           amount) / total

                            if benefit_type in [
                                    BenefitType.amount, BenefitType.percentage
                            ]:
                                products_dict[item.item_id]['discount'] = max(
                                    products_dict[item.item_id]['discount'],
                                    item_amount)

                            if benefit_type in [
                                    BenefitType.cashback_amount,
                                    BenefitType.cashback_percentage
                            ]:
                                products_dict[item.item_id]['cashback'] = max(
                                    products_dict[item.item_id]['cashback'],
                                    item_amount)

                            if benefit_type in [
                                    BenefitType.agent_amount,
                                    BenefitType.agent_percentage
                            ]:
                                products_dict[
                                    item.item_id]['agent_discount'] = max(
                                        products_dict[item.item_id]
                                        ['agent_discount'], item_amount)

                            if benefit_type in [
                                    BenefitType.agent_cashback_amount,
                                    BenefitType.agent_cashback_percentage
                            ]:
                                products_dict[
                                    item.item_id]['agent_cashback'] = max(
                                        products_dict[item.item_id]
                                        ['agent_cashback'], item_amount)

                benefit_dict['couponCode'] = existing_voucher['voucher'].code
                benefit_dict['benefit_type'] = benefit_type.value
                if existing_voucher['voucher'].type in [
                        VoucherType.auto_freebie.value,
                        VoucherType.regular_freebie.value
                ]:
                    benefit_dict['freebies'] = freebie_list
                else:
                    benefit_dict['amount'] = amount
                    benefit_dict['amount_actual'] = amount_actual
                benefit_dict['items'] = item_id_list
                benefit_dict['type'] = existing_voucher['voucher'].type
                benefit_dict['custom'] = existing_voucher['voucher'].custom

                if rule.criteria_obj.payment_modes is not None:
                    benefit_dict[
                        'paymentMode'] = rule.criteria_obj.payment_modes

                    if not payment_modes_list:
                        payment_modes_list = benefit_dict['paymentMode']
                    else:
                        payment_modes_list = get_intersection_of_lists(
                            payment_modes_list, benefit_dict['paymentMode'])
                if rule.criteria_obj.channels is not None:
                    benefit_dict['channel'] = rule.criteria_obj.channels
                    if not channels_list:
                        channels_list = benefit_dict['channel']
                    else:
                        channels_list = get_intersection_of_lists(
                            channels_list, benefit_dict['channel'])
                benefits_list.append(benefit_dict)

            if not benefit_list:
                benefit_dict = dict()
                benefit_dict['couponCode'] = existing_voucher['voucher'].code
                benefit_dict['items'] = item_id_list
                benefit_dict['type'] = existing_voucher['voucher'].type
                benefit_dict['paymentMode'] = rule.criteria_obj.payment_modes
                benefit_dict['channel'] = [
                    Channels(c).value for c in rule.criteria_obj.channels
                ]
                benefit_dict['custom'] = existing_voucher['voucher'].custom
                if rule.criteria_obj.payment_modes is not None:
                    benefit_dict[
                        'paymentMode'] = rule.criteria_obj.payment_modes

                    if not payment_modes_list:
                        payment_modes_list = benefit_dict['paymentMode']
                    else:
                        payment_modes_list = get_intersection_of_lists(
                            payment_modes_list, benefit_dict['paymentMode'])
                if rule.criteria_obj.channels is not None:
                    benefit_dict['channel'] = rule.criteria_obj.channels
                    if not channels_list:
                        channels_list = benefit_dict['channel']
                    else:
                        channels_list = get_intersection_of_lists(
                            channels_list, benefit_dict['channel'])

                benefits_list.append(benefit_dict)

    total_discount = 0.0
    total_agent_discount = 0.0
    total_cashback = 0.0
    total_agent_cashback = 0.0
    products_list = list()
    for item in products_dict:
        product_dict = products_dict[item]
        products_list.append(product_dict)
        total_discount += product_dict['discount']
        total_agent_discount += product_dict['agent_discount']
        total_cashback += product_dict['cashback']
        total_agent_cashback += product_dict['agent_cashback']
        product_dict['discount'] = round(product_dict['discount'], 2)
        product_dict['agent_discount'] = round(product_dict['agent_discount'],
                                               2)
        product_dict['cashback'] = round(product_dict['cashback'], 2)
        product_dict['agent_cashback'] = round(product_dict['agent_cashback'],
                                               2)

    for a_benefit in benefits_list:
        if a_benefit['type'] is VoucherType.regular_coupon.value\
                and a_benefit.get('amount_actual'):
            a_benefit['amount'] = a_benefit['amount_actual']
            del a_benefit['amount_actual']

    total_discount = round(total_discount, 2)
    total_agent_discount = round(total_agent_discount, 2)
    total_cashback = round(total_cashback, 2)
    total_agent_cashback = round(total_agent_cashback, 2)

    response_dict = dict()

    response_dict['products'] = products_list
    response_dict['benefits'] = benefits_list
    response_dict['totalDiscount'] = total_discount
    response_dict['totalCashback'] = total_cashback
    response_dict['totalAgentDiscount'] = total_agent_discount
    response_dict['totalAgentCashback'] = total_agent_cashback
    if hasattr(order, 'check_payment_mode') and order.check_payment_mode:
        response_dict['paymentMode'] = [order.payment_mode]
    else:
        response_dict['paymentMode'] = payment_modes_list
    response_dict['channel'] = channels_list
    response_dict['couponCodes'] = [
        existing_voucher['voucher'].code
        for existing_voucher in order.existing_vouchers
    ]
    return response_dict