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
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
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
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
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