def do_iocl_date_correction(): to = '2016-06-14' db = CouponsAlchemyDB() get_voucher_query = "select code, `from`, `to` from all_vouchers where `to`> :to and ( code rlike '20[1-5][0-9][0-9]{6}NEW' or code rlike '20[1-5][0-9][0-9]{6}TWO' or code rlike '20[1-5][0-9][0-9]{6}REP')" code_from_list = db.execute_raw_sql(get_voucher_query, {'to': to}) code_from_list = [{'to': code_from_dict['to'].isoformat(), 'from': code_from_dict['from'].isoformat(), 'code': code_from_dict['code']} for code_from_dict in code_from_list] lists = list(chunks(code_from_list, 2000)) for a_list in lists: body = list() for coupon in a_list: if coupon['code'] == '2016006271REP': continue body_dict = { "coupons": [{ 'code': coupon['code'], 'from': coupon['from'] }], "update": { "to": '2016-01-01' } } body.append(body_dict) r = do_it_now(body=body) with open('/Users/abhi/Documents/output_ibl_expire.log', 'a+') as f: f.write(r.text) f.close()
def save_auto_freebie_from_voucher(voucher, db=None): voucher.get_rule(db) if voucher.type is not VoucherType.regular_coupon.value: auto_freebie_values = dict() auto_freebie_values['type'] = voucher.type auto_freebie_values['zone'] = voucher.rules_list[0].criteria_obj.zone[ 0], auto_freebie_values['range_min'] = voucher.rules_list[ 0].criteria_obj.range_min auto_freebie_values['range_max'] = voucher.rules_list[ 0].criteria_obj.range_max auto_freebie_values['cart_range_min'] = voucher.rules_list[ 0].criteria_obj.cart_range_min auto_freebie_values['cart_range_max'] = voucher.rules_list[ 0].criteria_obj.cart_range_max auto_freebie_values['voucher_id'] = binascii.a2b_hex(voucher.id) if voucher.type is VoucherType.auto_freebie.value: auto_freebie_values['variants'] = voucher.rules_list[ 0].criteria_obj.variants[0] else: auto_freebie_values['variants'] = None auto_freebie_values['from'] = voucher.from_date auto_freebie_values['to'] = voucher.to_date if not db: db = CouponsAlchemyDB() db.insert_row("auto_benefits", **auto_freebie_values)
def do_date_correction(): db = CouponsAlchemyDB() query = 'select count(1) c, `to` from vouchers group by `to` order by c desc' count_date_list = db.execute_raw_sql(query, dict()) done_date = parser.parse("2016-08-30 18:30:00.000000") for count_date_map in count_date_list: date_value = count_date_map['to'] if date_value == done_date: continue get_voucher_query = 'select `code`, `from` from vouchers where `to` = :to' code_from_list = db.execute_raw_sql(get_voucher_query, {'to': date_value}) code_from_list = [{'from': code_from_dict['from'].isoformat(), 'code': code_from_dict['code']} for code_from_dict in code_from_list] lists = list(chunks(code_from_list, 5000)) for a_list in lists: body = [ { "coupons": a_list, "update": { "to": date_value.isoformat() } } ] r = do_it_now(body=body, params={'force': u'true'}) with open('/var/log/couponlogs/grocery/output_date_correction.log', 'a+') as f: f.write(r.text) f.close()
def find_one_by_id(id): db = CouponsAlchemyDB() voucher_dict = db.find_one("vouchers", **{'id': id}) if voucher_dict: voucher = Vouchers.from_dict(voucher_dict) return voucher return False
def is_voucher_exhausted_for_this_user(self, user_id, voucher_id, order_id, db=None): if not db: db = CouponsAlchemyDB() session_id = request.headers.get('X-ASKME-SESSIONID', None) user_uuid = request.headers.get('X-ASKME-USERID', None) if session_id: is_logged_in, phone_no = fetch_phone_no_from_session_id(session_id) elif user_uuid: is_logged_in, phone_no = fetch_phone_no(user_uuid) else: is_logged_in, phone_no = fetch_phone_no(user_id) if not phone_no: return True if u'{}'.format(request.url_rule) == u'/vouchers/grocery/v1/apply': if not is_logged_in: return True else: # check api case pass setattr(request, 'phone_no', phone_no) total_per_user_allowed_uses = self.usage['no_of_uses_allowed_per_user'] count = db.count("voucher_use_tracker", **{'voucher_id': voucher_id, 'user_id': phone_no, 'not_args': {'order_id': order_id}}) if count >= total_per_user_allowed_uses: return True return False
def is_voucher_exhausted(self, voucher_id, db=None): if not db: db = CouponsAlchemyDB() total_allowed_uses = self.usage['no_of_total_uses_allowed'] count = db.count("voucher_use_tracker", **{'voucher_id': voucher_id}) if count >= total_allowed_uses: return True return False
def find_one(code, db=None): if not db: db = CouponsAlchemyDB() voucher_dict = db.find_one("vouchers", **{'code': code}) if voucher_dict: voucher = Vouchers.from_dict(voucher_dict) return voucher return False
def validate_permission(permission): if not permission or not permission.value: return True agent_id = get_agent_id() db = CouponsAlchemyDB() agent_permission_dict = db.find_one("agent_permission", **{'agent_id': agent_id, 'permission_id': permission.value}) if not agent_permission_dict: return False return True
def find_all_by_code(code, db=None): if not db: db = CouponsAlchemyDB() voucher_list = list() voucher_dict_list = db.find("all_vouchers", **{'code': code}) for voucher_dict in voucher_dict_list: voucher = Vouchers.from_dict(voucher_dict) voucher_list.append(voucher) return voucher_list
def find_voucher_at_the_date(code, date, db=None): if not db: db = CouponsAlchemyDB() query = 'select * from all_vouchers where code=:code and `from` <= :date and `to >= :date`' args = {'code': code, 'date': date} voucher_dict = db.execute_raw_sql(query, args) if voucher_dict: voucher = Vouchers.from_dict(voucher_dict[0]) return voucher return False
def find_one(id, db=None): id = binascii.a2b_hex(id) if not db: db = CouponsAlchemyDB() rule_dict = db.find_one("rule", **{'id': id}) if rule_dict: rule_dict['id'] = binascii.b2a_hex(rule_dict['id']) rule = Rule(**rule_dict) return rule return False
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 recreate_ibl(): to = '2016-06-14' db = CouponsAlchemyDB() get_voucher_query = "select code, `from`, `to` from all_vouchers where `to`> :to and ( code rlike '20[1-5][0-9][0-9]{6}NEW' or code rlike '20[1-5][0-9][0-9]{6}TWO' or code rlike '20[1-5][0-9][0-9]{6}REP')" code_from_list = db.execute_raw_sql(get_voucher_query, {'to': to}) code_from_list = [{'to': code_from_dict['to'].isoformat(), 'from': code_from_dict['from'].isoformat(), 'code': code_from_dict['code']} for code_from_dict in code_from_list] print code_from_list.__len__() lists = list(chunks(code_from_list, 200)) # process_one_list(lists[0]) threads = [gevent.spawn(process_one_list, a_list) for a_list in lists] gevent.joinall(threads)
def is_validity_period_exclusive_for_freebie_voucher_code( existing_voucher_dict, db=None): sql = 'select * from `auto_benefits` where type=:type and zone=:zone and (' if existing_voucher_dict.get('cart_range_min'): where_clause1 = '( ((cart_range_min is null or (:cart_range_min >= cart_range_min)) && (cart_range_max is null or (:cart_range_min <= cart_range_max))) or ( (:cart_range_min is null or (cart_range_min >= :cart_range_min)) && (:cart_range_max is null or (cart_range_min <= :cart_range_max))) ) ' else: where_clause1 = '(cart_range_min is null)' if existing_voucher_dict.get('cart_range_max'): where_clause2 = '( ((cart_range_min is null or (:cart_range_max >= cart_range_min)) && (cart_range_max is null or (:cart_range_max <= cart_range_max)) ) or ( (:cart_range_min is null or (cart_range_max >= :cart_range_min)) && (:cart_range_max is null or (cart_range_max <= :cart_range_max))) )' else: where_clause2 = '(cart_range_max is null)' date_overlapping_caluse = '(((:from >= `from` && :from <= `to`) or (:to >= `from` && :to <= `to`)) or ((`from` >= :from && `from` <= :to) or (`to` >= :from && `to` <= :to) ))' if existing_voucher_dict.get('type') is VoucherType.auto_freebie.value: if existing_voucher_dict.get('range_min'): where_clause3 = '( ((range_min is null or (:range_min >= range_min)) && (range_max is null or (:range_min <= range_max))) or ( (:range_min is null or (range_min >= :range_min)) && (:range_max is null or (range_min <= :range_max))) )' else: where_clause3 = '(range_min is null)' if existing_voucher_dict.get('range_max'): where_clause4 = '( ((range_min is null or (:range_max >= range_min)) && (range_max is null or (:range_max <= range_max)) ) or ( (:range_min is null or (range_max >= :range_min)) && (:range_max is null or (range_max <= :range_max))) )' else: where_clause4 = '(range_max is null)' sql += '(' + where_clause1 + ' or ' + where_clause2 + ' or ' + where_clause3 +\ ' or ' + where_clause4 + ') && ('+date_overlapping_caluse+')' + ') and variants=:variants' else: sql += '(' + where_clause1 + ' or ' + where_clause2 + ') && (' + date_overlapping_caluse + ')' + ')' if not db: db = CouponsAlchemyDB() existing_voucher_list = db.execute_raw_sql(sql, existing_voucher_dict) if existing_voucher_list: error_list = list() for existing_voucher in existing_voucher_list: voucher = Vouchers.find_one_by_id(existing_voucher['voucher_id']) if voucher.code != existing_voucher_dict.get('code'): msg = u'Voucher {} overlaps ranges with this voucher with values cart_range_min: {}, cart_range_max: {}'.format( voucher.code, existing_voucher['cart_range_min'], existing_voucher['cart_range_max']) if existing_voucher_dict.get('type'): msg += u', range_min: {}, range_max: {}'.format( existing_voucher['range_min'], existing_voucher['range_max']) error_list.append(msg) continue error_list.append(u'Expire the voucher {} and recreate'.format( voucher.code)) if error_list: return False, error_list return True, None
def find_one_all_vouchers(code, from_date, db=None): # from_date must be a timezone unaware UTC datetime object if not db: db = CouponsAlchemyDB() voucher_dict = db.find_one("all_vouchers", **{ 'code': code, 'from': from_date }) if voucher_dict: voucher = Vouchers.from_dict(voucher_dict) return voucher return False
def fetch_order_response(args): order_id = args.get('order_id') user_id = args.get('customer_id') db = CouponsAlchemyDB() result = db.find("voucher_use_tracker", **{ 'order_id': order_id, 'user_id': user_id }) if result: # result may have one entry per voucher, # but all entries will have same json for an order id, # Hence its safe accessing the list's 0th element return True, json.loads(result[0]['response']) return False, None
def create_app(): app = Flask(__name__) app.url_map.converters['hex'] = HexConverter app.url_map.converters['list'] = ListConverter if client == 'new_grocery': app.register_blueprint(grocery_voucher_api, url_prefix='/vouchers/grocery/v1') else: app.register_blueprint(rule_api, url_prefix='/rules') app.register_blueprint(voucher_api, url_prefix='/vouchers/v1') app.register_blueprint(voucher_api_v_1_1, url_prefix='/vouchers/v1.1') log.setup_logging() CouponsAlchemyDB.init() return app
def is_validity_period_exclusive_for_voucher_code(voucher, db=None): if not db: db = CouponsAlchemyDB() date_overlapping_caluse = '(((:from >= `from` && :from <= `to`) or (:to >= `from` && :to <= `to`)) or ((`from` >= :from && `from` <= :to) or (`to` >= :from && `to` <= :to) ))' date_overlap_params = { 'from': voucher.from_date, 'to': voucher.to_date, 'code': voucher.code } sql = "select * from all_vouchers where code=:code && (" + date_overlapping_caluse + ")" voucher_list = db.execute_raw_sql(sql, date_overlap_params) if voucher_list: return False, u'Vouchers with overlapping dates found for code {}'.format( voucher.code) return True, None
def fetch_auto_benefits(order, freebie_type=VoucherType.regular_freebie): assert isinstance(order, OrderData) variant_total_map = dict() item_list = list() item_variant_map = dict() if freebie_type is VoucherType.auto_freebie: for item in order.items: variant_total_map[item.variant] = variant_total_map.get( item.variant, 0.0) + (item.price * item.quantity) list_of_item_id = item_variant_map.get(item.variant, list()) list_of_item_id.append(item.item_id) item_variant_map[item.variant] = list_of_item_id where_clause, params = get_where_clauses(variant_total_map) sql = 'select v.*,a.`type`, a.`variants`, a.`zone` from `vouchers` v join (select * from `auto_benefits` where (type = :type and zone in :zone and (' + where_clause + ') and (cart_range_min is null or cart_range_min <= :ordertotal) and (cart_range_max is null or cart_range_max >= :ordertotal) and :now > `from` and :now < `to`)) a on v.id=a.`voucher_id`' else: for item in order.items: item_list.append(item.item_id) params = dict() sql = 'select v.*,a.`type`, a.`variants`, a.`zone` from `vouchers` v join (select * from `auto_benefits` where (type = :type and zone in :zone and (cart_range_min is null or cart_range_min <= :ordertotal) and (cart_range_max is null or cart_range_max >= :ordertotal) and :now > `from` and :now < `to`)) a on v.id=a.`voucher_id`' params['ordertotal'] = order.total_price params['type'] = freebie_type.value params['zone'] = order.zone params['now'] = datetime.datetime.utcnow() db = CouponsAlchemyDB() l = db.execute_raw_sql(sql, params) if not l: return for voucher_dict in l: effective_voucher = Vouchers.from_dict(voucher_dict) effective_voucher.get_rule() success_dict = { 'voucher': effective_voucher, } if freebie_type is VoucherType.auto_freebie: success_dict['total'] = variant_total_map[voucher_dict['variants']] success_dict['item_id_list'] = item_variant_map[ voucher_dict['variants']] else: success_dict['total'] = order.total_price success_dict['item_id_list'] = item_list order.existing_vouchers.append(success_dict)
def fetch_active_voucher(code, db=None): if not db: db = CouponsAlchemyDB() db.begin() try: active_voucher = Vouchers.get_active_voucher(code, db) db.commit() return active_voucher except Exception as e: logger.exception(e) db.rollback() return False else: return Vouchers.get_active_voucher(code, db)
def delete(self, db=None): if not db: db = CouponsAlchemyDB() db.delete_row_in_transaction("vouchers", **{'id': self.id_bin}) if self.type is not VoucherType.regular_coupon.value: db.delete_row_in_transaction("auto_benefits", **{'voucher_id': self.id_bin})
def login(): # return True agent_name = request.headers.get('X-API-USER', None) authorization = request.headers.get('X-API-TOKEN', None) authenticated = False if agent_name and authorization: db = CouponsAlchemyDB() token = db.find_one("tokens", **{'token': authorization, 'agent_name': agent_name}) if token: user_dict = dict() user_dict['agent_id'] = token['agent_id'] user_dict['agent_name'] = token['agent_name'] user = User(**user_dict) setattr(request, 'user', user) authenticated = True if not authenticated: user_dict = dict() user_dict['agent_id'] = 0 user_dict['agent_name'] = u'anonymous' user = User(**user_dict) setattr(request, 'user', user) return authenticated
def make_transaction_log_entry(args): db = CouponsAlchemyDB() db.begin() success = True error = None try: voucher_use_list_of_dict = db.find( "user_voucher_transaction_log", order_by="_updated_on", **{'order_id': args.get('order_id')}) if not voucher_use_list_of_dict: success = False error = u'No Order found for the given order id' else: last_log = VoucherTransactionLog.dict_to_obj( voucher_use_list_of_dict[0]) if args.get('payment_status'): status = VoucherTransactionStatus.success.value else: status = VoucherTransactionStatus.failure.value id = uuid.uuid1().hex log = VoucherTransactionLog( **{ 'id': id, 'user_id': last_log.user_id, 'voucher_id': last_log.voucher_id, 'order_id': last_log.order_id, 'status': status }) log.save(db) success = True error = None db.commit() except Exception as e: logger.exception(e) db.rollback() success = False error = u'Unknown error' return success, error
def save(self, db=None): values = self.get_value_dict_for_log() if not db: db = CouponsAlchemyDB() db.begin() try: function = self.save_function().get(self.status_enum) function(db, values) db.commit() except Exception as e: logger.exception(e) db.rollback() return False # else: # db.commit() return True else: function = self.save_function().get(self.status_enum) function(db, values)
def replay_test(group_no): try: client = KafkaClient(hosts=KAFKAHOST) except Exception as e: return group_id = TEST_TOPIC_KAFKA + u'{}'.format(group_no) try: topic = client.topics[TEST_TOPIC_KAFKA] balanced_consumer = topic.get_balanced_consumer( consumer_group=str(group_id), auto_commit_enable=True, reset_offset_on_start=True, auto_offset_reset=common.OffsetType.LATEST, use_rdkafka=False, zookeeper_connect=ZOOKEEPER) for message in balanced_consumer: if message is not None: data = json.loads(message.value) end_point = data['url'] body = data['body'] if end_point.endswith(('check', 'apply')): body_data = json.loads(body) for product in body_data.get('products', list()): product['subscription_id'] = product.get('item_id') body = json.dumps(body_data) params = data['query'] response = data['response'] url = HOST + end_point headers = { 'X-API-USER': TEST_USER, 'X-API-TOKEN': TEST_TOKEN, 'Content-Type': 'Application/Json' } response_on_staging_obj = make_api_call(url=url, body=json.loads(body), method='POST', headers=headers, params=params) response_on_staging = response_on_staging_obj.text data = { 'url': end_point, 'body': body, 'params': json.dumps(params), 'prod_response': response, 'staging_response': response_on_staging, 'body_varchar': body, 'prod_response_varchar': response, 'staging_response_varchar': response_on_staging, 'match': response_on_staging == response } db = CouponsAlchemyDB() db.begin() try: try: db.insert_row("auto_tester", **data) except DataError: del data['body_varchar'] del data['prod_response_varchar'] del data['staging_response_varchar'] db.insert_row("auto_tester", **data) db.commit() except Exception as e: logger.exception(e) db.rollback() except Exception as e: logger.exception(e)
from flask_script import Server import config from flask_migrate import Migrate, MigrateCommand from src.sqlalchemydb import CouponsAlchemyDB from kafka_apps.new_grocery.consumer import KafkaTestingConsumerCommand as new_grocery_replay_test_consumer from kafka_apps.grocery.consumer import KafkaTestingConsumerCommand as grocery_replay_test_consumer if config.env and config.env in ['production', 'staging']: newrelic_cfg_file = os.path.join( os.getcwd(), "conf", u'newrelic-{}-{}.ini'.format(config.env, config.client)) newrelic.agent.initialize(newrelic_cfg_file) app = create_app() app.config['SQLALCHEMY_DATABASE_URI'] = config.DATABASE_URL db = CouponsAlchemyDB() migrate = Migrate(app, db, directory=config.MIGRATIONS_DIRECTORY) manager = Manager(app) manager.add_command("runserver", Server(host="localhost", port=config.CONFIG["port"])) manager.add_command("db", MigrateCommand) if config.client == 'new_grocery': manager.add_command("kafka", new_grocery_replay_test_consumer) elif config.client == 'grocery': manager.add_command("kafka", grocery_replay_test_consumer) @manager.command def test(coverage=False): """Run the unit tests.""" import unittest
def save(self): values = self.get_value_dict() db = CouponsAlchemyDB() db.begin() try: from src.rules.utils import is_validity_period_exclusive_for_voucher_code success, error = is_validity_period_exclusive_for_voucher_code( self, db) if not success: db.rollback() return False, None, error db.insert_row("all_vouchers", **values) Vouchers.fetch_active_voucher(self.code, db) db.commit() except sqlalchemy.exc.IntegrityError as e: db.rollback() # should not happen return False, None, u'Voucher code already exists' except Exception as e: logger.exception(e) db.rollback() return False, None, u'Unknown Error' # else: # db.commit() return True, {'id': self.id, 'code': self.code}, None
def apply_benefits(args, order, benefits): order_id = args.get('order_id') user_id = args.get('customer_id') voucher_id_list = list() db = CouponsAlchemyDB() db.begin() try: rows_with_order_id = db.find("voucher_use_tracker", **{'order_id': order_id}) if rows_with_order_id: db.delete_row_in_transaction("voucher_use_tracker", **{'order_id': order_id}) for existing_voucher in order.existing_vouchers: voucher_id = existing_voucher['voucher'].id if voucher_id in voucher_id_list: continue voucher_id_list.append(voucher_id) rule = existing_voucher['voucher'].rules_list[0] if hasattr(order, 'validate') and not order.validate: pass else: success, error = rule.criteria_obj.check_usage( order.customer_id, existing_voucher['voucher'].id_bin, order_id, db) if not success: db.rollback() return False, 400, default_error_message if config.client == 'new_grocery': customer_id = getattr(request, "phone_no", "-") else: customer_id = user_id session_id = request.headers.get('X-ASKME-SESSIONID', None) user_uuid = request.headers.get('X-ASKME-USERID', None) transaction_log = VoucherTransactionLog( **{ 'id': uuid.uuid1().hex, 'user_id': customer_id, 'session_id': session_id, 'user_uuid': user_uuid, 'voucher_id': voucher_id, 'order_id': order_id, 'status': VoucherTransactionStatus.in_progress.value, 'response': json.dumps(benefits) }) transaction_log.save(db) db.commit() except Exception as e: logger.exception(e) db.rollback() return False, 500, u'Unknown Error. Please try after some time' # else: # db.commit() return True, 200, None
def generate_auto_freebie(): db = CouponsAlchemyDB() db.delete_row("auto_benefits") voucher_list = db.find("vouchers") for voucher in voucher_list: save_auto_freebie_from_voucher_dict(voucher)
def create_freebie_coupon(args): # code must have only 1 element and it has been validated before # hence safe in accessing directly 0th element # in case of update, delete the voucher, delete entry from auto_benefits # create a new rule and create a new voucher on the created rule, and an entry in auto_benefits # Also it is ensured that at a time only one entry per zone, spending range and category can be there. # Currently Scheduling is not supported in Freebies if args.get('schedule'): return False, None, [u'Scheduling is not supported in Freebie Coupons'] code = args.get('code')[0] rule = args.get('rules')[0] criteria = rule.get('criteria') existing_voucher_dict = { 'type': args.get('type'), 'zone': criteria.get('location').get('zone')[0], 'range_min': criteria.get('range_min'), 'range_max': criteria.get('range_max'), 'cart_range_min': criteria.get('cart_range_min'), 'cart_range_max': criteria.get('cart_range_max'), 'from': args.get('from'), 'to': args.get('to'), 'code': code } data = { 'criteria': { 'categories': { 'in': [], 'not_in': [] }, 'no_of_uses_allowed_per_user': criteria.get('no_of_uses_allowed_per_user'), 'no_of_total_uses_allowed': criteria.get('no_of_total_uses_allowed'), 'valid_on_order_no': criteria.get('valid_on_order_no'), 'location': { 'country': [], 'state': [], 'area': [], 'city': [], 'zone': criteria.get('location').get('zone') }, 'range_min': criteria.get('range_min'), 'range_max': criteria.get('range_max'), 'cart_range_min': criteria.get('cart_range_min'), 'cart_range_max': criteria.get('cart_range_max'), 'channels': [], 'brands': [], 'products': { 'in': [], 'not_in': [] }, 'storefronts': [], 'sellers': [], 'payment_modes': [] }, 'benefits': [{ 'type': 2, 'freebies': rule.get('benefits')[0].get('freebies'), }], 'description': rule.get('description') } if args.get('type') is VoucherType.auto_freebie.value: existing_voucher_dict['variants'] = criteria.get('variants')[0] data['criteria']['variants'] = criteria.get('variants') else: existing_voucher_dict['variants'] = None data['criteria']['variants'] = [] success, error_list = is_validity_period_exclusive_for_freebie_voucher_code( existing_voucher_dict) if not success: return False, None, error_list rule_obj = create_rule_object(data, args.get('user_id'), get_criteria_kwargs) rule_obj.save() success_list, error_list = save_vouchers(args, [rule_obj.id]) if not error_list: voucher_id = success_list[0]['id'] auto_freebie_values = dict() auto_freebie_values['type'] = args.get('type') auto_freebie_values['zone'] = criteria.get('location').get('zone')[0], auto_freebie_values['range_min'] = criteria.get('range_min') auto_freebie_values['range_max'] = criteria.get('range_max') auto_freebie_values['cart_range_min'] = criteria.get('cart_range_min') auto_freebie_values['cart_range_max'] = criteria.get('cart_range_max') auto_freebie_values['voucher_id'] = binascii.a2b_hex(voucher_id) auto_freebie_values['variants'] = existing_voucher_dict['variants'] auto_freebie_values['from'] = args.get('from') auto_freebie_values['to'] = args.get('to') db = CouponsAlchemyDB() db.insert_row("auto_benefits", **auto_freebie_values) for s in success_list: del s['id'] return True, success_list, error_list