from dspt_api.util.general.handle_float import f2 from dspt_api.util.general.handle_redis import get_data_from_redis, get_param_from_redis from dspt_api.util.general.handle_card import get_card_type import time def general_seat_params(pay_type, data): """ 说明: 支持现金、联名卡支付,电子券支付,扫码券支付 现金支付时,可以走电商渠道定价 联名卡支付时,价格取联名卡的优惠价,支付方式还是现金 电子券和扫码券都是走鼎新定价,然后通过券接口获取价格,剩余待支付的金额为现金支付 券只支持如下几种券: 先从seat_lock接口获取座位价格 如果seat_lock没有获取到座位价格就到 返回 结果, seat , ticket_cash, play_id, play_update_time, lock_flag, quan, timestamp """ redis_key_prefix = f'dspt_api_{data["ip"]}_{data["env"]}_{data["member_type"]}_{data["pid"]}_{data["cid"]}' # 获取 area_info和partner_price request_api_lock = {'name': '3.3.1 座位锁定', 'path': 'seat/lock'} redis_key_api_lock = f'{redis_key_prefix}_{request_api_lock["path"]}' result_lock, _format_lock, seat_price_from_lock, _timestamp_lock = get_data_from_redis(redis_key_api_lock) if not result_lock: print('result_lock False') return False, None, None, None, None, None, None, None area_info = seat_price_from_lock['areaInfo'] if len(seat_price_from_lock['areaInfo']) > 0 else False lock_flag = seat_price_from_lock['lockFlag'] # partner_price = seat_price_from_lock['partnerPrice'] if seat_price_from_lock['partnerPrice'] is not None else False # 获取market_price request_api_play = {'name': '3.1.5 获取放映计划列表', 'path': 'cinema/plays'} redis_key_api_play = f'{redis_key_prefix}_{request_api_play["path"]}' result_play, _format_play, seat_price_from_play, _timestamp_play = get_data_from_redis(redis_key_api_play) if not result_play: print('result_play False') return False, None, None, None, None, None, None, None market_price = seat_price_from_play['marketPrice'] play_id = seat_price_from_play['id'] play_update_time = seat_price_from_play['cineUpdateTime'] # 获取手续费 request_api_config = {'name': '3.1.2 获取单个影院配置信息', 'path': 'cinema/config'} redis_key_api_config = f'{redis_key_prefix}_{request_api_config["path"]}' result_config, _format_config, seat_price_from_config, _timestamp_config = get_data_from_redis(redis_key_api_config) if not result_config: print('result_config False') return False, None, None, None, None, None, None, None handle_fee = seat_price_from_config['handleFee'] partner_type = seat_price_from_config['partnerSubsidyType'] # 1:电商平台补贴;2:合作商补贴 # 获取座位信息 request_api_seat = {'name': '3.1.8 获取某场次座位状态', 'path': 'play/seat-status'} redis_key_api_seat = f'{redis_key_prefix}_{request_api_seat["path"]}' result_seat, _format_seat, seat_price_from_seat, _timestamp_seat = get_data_from_redis(redis_key_api_seat) if not result_seat: print('result_seat False') return False, None, None, None, None, None, None, None seat_id_list = [{'seat_id': seat['cineSeatId'], 'ticket_discount': seat.get('ticketDiscount', 0), 'service_discount': seat.get('serviceDiscount', 0)} for seat in seat_price_from_seat] # 计算最大时间戳 last_timestamp = max([_timestamp_lock, _timestamp_play, _timestamp_config, _timestamp_seat]) # 判断获取到了全部接口数据,就继续,否则报错 if not (result_lock and result_play and result_config and result_seat): return_str = '请手动输入参数,检查相关接口返回值:3.3.1 座位锁定、3.1.5 获取放映计划列表、3.1.8 获取某场次座位状态、3.1.2 获取单个影院配置信息' return False, return_str, 0, return_str, return_str, return_str, return_str, last_timestamp if pay_type == 'cash': """ -- 当影院合作商是电商平台定价时(partner_type = 1) price:不包含手续费,含服务费 user_real_pay_price:用户真实支付影票金额,不含手续费、服务费,该字段只做记录不参与计算 service_fee:影厅座位服务费(仅当锁座接口返回的服务费[areaServiceFee]不为零时,才传此参数) ticket_discount_price:影票优惠金额; service_fee_discount_price:服务费优惠金额, 注:如果是鼎新电商平台对合作商价格管控,使用以上两个优惠金额字段需要联系请联系鼎新杰盈公司商务打开开关即可使用,否则直接回传会产生掉单。 -- 当影院合作商是合作商自主定价时(partner_type = 2) price:真实的票价[不含服务费、不含手续费] user_real_pay_price:用户真实支付影票金额[不含手续费、服务费] 需要扣减 ticket_discount_price service_fee:真实的服务费 ticket_discount_price:影票优惠金额,仅做记录 service_fee_discount_price:服务费优惠金额,仅做记录 测试影院: 测试影院3.166 乐影网 电商平台补贴 是否允许传递优惠金额 否 影票价格控制 是 卖品价格控制 是 测试影院3.166 淘票票 电商平台补贴 是否允许传递优惠金额 是 影票价格控制 否 卖品价格控制 否 测试影院3.166 美团猫眼 电商平台补贴 是否允许传递优惠金额 是 影票价格控制 是 卖品价格控制 是 测试影院3.166 合作商补贴 合作商补贴 是否允许传递优惠金额 否 影票价格控制 否 卖品价格控制 否 """ quan = '' seat_list = [] ticket_cash = 0 # 统计cash字段用 for seat_info in seat_id_list: seat = [seat_info["seat_id"], handle_fee] ticket_discount = seat_info["ticket_discount"] service_discount = seat_info["service_discount"] if area_info is not False: # 查找座位对应的区域价格 for area_seat_info in area_info: if int(area_seat_info['seatId']) == int(seat_info['seat_id']): # 获取price字段值 price = f2(area_seat_info["areaPrice"]) seat.append(str(price)) seat.append('0') seat.append(area_seat_info["areaServiceFee"]) # if partner_type == '2': # 合作商定价 # price -= Decimal(area_seat_info["areaServiceFee"]).quantize(Decimal('0.00'), ROUND_HALF_UP) # 计算用户实际支付的值 real_pay = f2(area_seat_info["areaPrice"]) real_pay -= f2(area_seat_info["areaServiceFee"]) # 处理影票和服务费折扣 if ticket_discount != 0: real_pay -= f2(ticket_discount) seat.append(str(ticket_discount)) if service_discount != 0: if partner_type == '2': real_pay -= f2(service_discount) seat.append(str(service_discount)) else: seat.append(str(service_discount)) seat[3] = str(real_pay) # seat = f'{seat_info["seat_id"]}-{handle_fee}-{str(price)}-{str(real_pay)}-{area_seat_info["areaServiceFee"]}{f"-{str(ticket_discount)}" if ticket_discount != 0 else ""}{f"-{str(service_discount)}" if service_discount != 0 else ""}' seat_list.append('-'.join(seat)) ticket_cash += real_pay else: seat.append(market_price) seat.append('0') seat.append('0.00') real_pay = f2(market_price) if ticket_discount != 0: real_pay -= f2(ticket_discount) seat.append(str(ticket_discount)) if service_discount != 0: real_pay -= f2(service_discount) seat.append(str(service_discount)) seat[3] = str(real_pay) # seat = f'{seat_info["seat_id"]}-{handle_fee}-{market_price}-{str(real_pay)}-0{f"-{str(ticket_discount)}" if ticket_discount != 0 else ""}{f"-{str(service_discount)}" if service_discount != 0 else ""}' seat_list.append('-'.join(seat)) ticket_cash += real_pay return True, ','.join(seat_list), ticket_cash, play_id, play_update_time, lock_flag, quan, last_timestamp elif pay_type == 'ecard': quan = '' # 获取联名卡价格 request_api_ecard = {'name': '3.4.6 获取座位的联名卡价格', 'path': 'ecard/seat-price'} redis_key_api_ecard = f'{redis_key_prefix}_{request_api_ecard["path"]}' result_ecard, _format_ecard, seat_price_from_ecard, _timestamp_ecard = get_data_from_redis( redis_key_api_ecard) if not result_ecard: print('result_ecard False') return False, None, None, None, None, None, None, None ecard_info = seat_price_from_ecard['seatPrices'] if len(seat_price_from_ecard['seatPrices']) > 0 else False # 错误判断 if ecard_info is False: return_str = '请手动输入参数,检查相关接口返回值:3.4.6 获取座位的联名卡价格' return False, return_str, 0, return_str, return_str, return_str, last_timestamp # 处理价格 seat_list = [] ticket_cash = 0 # 统计cash字段用 for seat_info in seat_id_list: seat = [seat_info["seat_id"], handle_fee] ticket_discount = seat_info["ticket_discount"] service_discount = seat_info["service_discount"] for ecard_seat_info in ecard_info: if int(ecard_seat_info['seatId']) == int(seat_info['seat_id']): # 获取price字段值 price = f2(ecard_seat_info["price"]) seat.append(str(price)) seat.append('0') seat.append(ecard_seat_info["serviceFee"]) # if partner_type == '2': # 合作商定价 # price -= Decimal(area_seat_info["areaServiceFee"]).quantize(Decimal('0.00'), ROUND_HALF_UP) # 计算用户实际支付的值 real_pay = f2(ecard_seat_info["price"]) real_pay -= f2(ecard_seat_info["serviceFee"]) # 处理影票和服务费折扣 if ticket_discount != 0: real_pay -= f2(ticket_discount) seat.append(str(ticket_discount)) if service_discount != 0: if partner_type == '2': real_pay -= f2(service_discount) seat.append(str(service_discount)) else: seat.append(str(service_discount)) seat[3] = str(real_pay) # seat = f'{seat_info["seat_id"]}-{handle_fee}-{str(price)}-{str(real_pay)}-{area_seat_info["areaServiceFee"]}{f"-{str(ticket_discount)}" if ticket_discount != 0 else ""}{f"-{str(service_discount)}" if service_discount != 0 else ""}' seat_list.append('-'.join(seat)) ticket_cash += real_pay return True, ','.join(seat_list), ticket_cash, play_id, play_update_time, lock_flag, quan, last_timestamp elif pay_type in ['yushouquan', 'equan']: # 获取券价格 request_api_yushouquan = {'name': '3.6.1 添加券', 'path': 'seat/check-coupon'} redis_key_api_yushouquan = f'{redis_key_prefix}_{request_api_yushouquan["path"]}' result_yushouquan, _format_yushouquan, seat_price_from_yushouquan, _timestamp_yushouquan = get_data_from_redis( redis_key_api_yushouquan) if not result_yushouquan: print('result_yushouquan False') return False, None, None, None, None, None, None, None # 获取券码 req_params = get_param_from_redis(redis_key_api_yushouquan) if pay_type == 'yushouquan': quan = req_params['coupons'] if req_params.get('coupons', False) else '3.6.1添加券接口中选择的券类型为会员卡赠券,与当前设置不符合' elif pay_type == 'equan': quan = req_params['card_coupons'] if req_params.get('equan', False) else '3.6.1添加券接口中选择的券类型为扫码券,与当前设置不符合' else: quan = '请检查3.6.1添加券接口' # 获取座位参数 seat_list = [] ticket_cash = 0 # 统计cash字段用 for seat_info in seat_id_list: seat = [seat_info["seat_id"], handle_fee] ticket_discount = seat_info["ticket_discount"] service_discount = seat_info["service_discount"] seat.append(market_price) seat.append('0') seat.append('0.00') real_pay = f2(market_price) if ticket_discount != 0: real_pay -= f2(ticket_discount) seat.append(str(ticket_discount)) if service_discount != 0: real_pay -= f2(service_discount) seat.append(str(service_discount)) seat[3] = str(real_pay) # seat = f'{seat_info["seat_id"]}-{handle_fee}-{market_price}-{str(real_pay)}-0{f"-{str(ticket_discount)}" if ticket_discount != 0 else ""}{f"-{str(service_discount)}" if service_discount != 0 else ""}' seat_list.append('-'.join(seat)) ticket_cash += real_pay ticket_cash = seat_price_from_yushouquan['balance'] return True, ','.join(seat_list), ticket_cash, play_id, play_update_time, lock_flag, quan, last_timestamp else: pass def general_seat_params_member(pay_type, data, card): """ seat_id-handle_fee-price-ticket_type-is_discount-settlement_price-service_fee 组成的字符串,多个值(多个seat)组用半角逗号分隔。 seat_id: 要购买的座位号 handle_fee:手续费,如果下单传入了退票订单号,会将handle_fee字段视为改签手续费 price:(不包含手续费)会员卡支付金额,该字段值是否包含影厅座位服务费取决于字段is_split_service_fee ticket_type: 影票类型(《会员卡详细信息》接口的业务响应参数desc的值) is_discount: 0:普通票,1:会员票,2:全局会员票 settlement_price:座位结算价,用于计算座位补贴(补贴=结算价-支付价),该值不能低于场次最低票价。(只有当参数is_cinema_price=2时,该值才有效,平台请求影院购票接口时会将计算出的补贴金额传给影院,补贴金额会计入影城报表。 注:该字段值是否包含影厅座位服务费取决于字段is_split_service_fee) service_fee:影厅座位服务费(只有当参数is_cinema_price=2时,该值才有效) 返回 结果, seat, play_id, play_update_time, lock_flag, seat_coupons, is_cinema_price, is_split_service_fee, cash_pay, timestamp """ # 获取卡类型 card_type = get_card_type(data["env"], data["pid"], data["cid"], card) if card_type is False: return_str = '此会员卡在该影院无法使用,请使用3.1.3 查询会员卡的详细信息接口查看卡信息' return False, return_str, return_str, return_str, return_str, return_str, '2', 'Y', None, int(time.time() * 1000) # 获取其他参数 redis_key_prefix = f'dspt_api_{data["ip"]}_{data["env"]}_{data["member_type"]}_{data["pid"]}_{data["cid"]}' seat_list = [] # seat_id request_api_seat = {'name': '3.2.6 获取某场次座位状态', 'path': 'play/seat-status'} redis_key_api_seat = f'{redis_key_prefix}_{request_api_seat["path"]}' result_seat, _format_seat, seat_data, _timestamp_seat = get_data_from_redis(redis_key_api_seat) if not result_seat: return False, None, None, None, None, None, None, None, None, None # 获取play_id 和 play_update_time request_api_play = {'name': '3.2.3 获取放映计划列表', 'path': 'cinema/plays'} redis_key_api_play = f'{redis_key_prefix}_{request_api_play["path"]}' result_play, _format_play, seat_price_from_play, _timestamp_play = get_data_from_redis(redis_key_api_play) if not result_play: return False, None, None, None, None, None, None, None, None, None play_id = seat_price_from_play['id'] play_update_time = seat_price_from_play['cineUpdateTime'] lowest_price = f2(seat_price_from_play['lowestPrice']) # 获取 lock_flag request_api_lock = {'name': '3.4.3 座位锁定', 'path': 'seat/lock'} redis_key_api_lock = f'{redis_key_prefix}_{request_api_lock["path"]}' result_lock, _format_lock, seat_price_from_lock, _timestamp_lock = get_data_from_redis(redis_key_api_lock) if not result_lock: return False, None, None, None, None, None, None, None, None, None lock_flag = seat_price_from_lock['lockFlag'] # cinema_price request_api_seat = {'name': '3.4.4 锁定座位后获取票价', 'path': 'seat/price'} redis_key_api_seat = f'{redis_key_prefix}_{request_api_seat["path"]}' result_seat_price, _format_seat_price, seat_data_price, _timestamp_seat_price = get_data_from_redis( redis_key_api_seat) if not result_seat_price: return False, None, None, None, None, None, None, None, None, None # handle_fee request_api_config = {'name': '3.2.2 获取单个影院配置信息', 'path': 'cinema/config'} redis_key_api_config = f'{redis_key_prefix}_{request_api_config["path"]}' result_config, _format_config, seat_price_from_config, _timestamp_config = get_data_from_redis(redis_key_api_config) if not result_config: return False, None, None, None, None, None, None, None, None, None handle_fee = f2(seat_price_from_config['handleFee']) # 计算最大时间戳 last_timestamp = max([_timestamp_seat, _timestamp_play, _timestamp_config, _timestamp_lock, _timestamp_seat_price]) # 判断获取到了全部接口数据,就继续,否则报错 if not (result_seat and result_play and result_lock and result_seat_price and result_config): return_str = '请手动输入参数,检查相关接口返回值:3.2.6 获取某场次座位状态、3.2.3 获取放映计划列表、3.4.3 座位锁定、3.4.4 锁定座位后获取票价、3.2.2 获取单个影院配置信息' return False, return_str, return_str, return_str, return_str, return_str, '1', None, None, last_timestamp # 处理影院定价逻辑 if pay_type['select_price_type'] == 'cinema_price': # 11682-1-27.7-会员票-1 is_cinema_price = '1' is_split_service_fee = None seat_coupons = None # 计算影票价 ticket_price = f2(f2(seat_data_price['totalPrice']) / int(seat_data_price['ticketNum'])) ticket_service = f2(f2(seat_data_price['totalServiceCharge']) / int(seat_data_price['ticketNum'])) cash_pay = 0 # 计算需要非卡余额支付的金额 # 生成座位字段 for seat in seat_data: seat_list.append(f"{seat['cineSeatId']}-{str(handle_fee)}-{str(ticket_price)}-会员票-1") if card_type == '权益卡(积分卡)': cash_pay += f2(ticket_price + handle_fee) else: cash_pay += 0 return True, ','.join( seat_list), play_id, play_update_time, lock_flag, seat_coupons, is_cinema_price, is_split_service_fee, str(cash_pay), last_timestamp # 处理三方定价的逻辑 if pay_type['select_price_type'] == 'third_price': # 11664-1-16.5-会员票-1-26.5-1.5 is_cinema_price = '2' # 处理is_split_service_fee字段 if pay_type['ticket_info']['have_service_fee'] is True: is_split_service_fee = 'Y' else: is_split_service_fee = 'N' # 生成券字段 # 11663-Rog自营兑换券10元@@6777bbcfhirW6VAqkHItn3PZ@@10.00@@0 quan_list = [] quan_price_list = [] quan_price_num = [] seat_id_quan_list = [] if pay_type['ticket_quan_check']: quan_per_ticket = int(int(pay_type['ticket_quan']['ticket_quan_num'])/len(seat_data)) # 每张票平均分配的券数量 quan_price_num = [quan_per_ticket] * len(seat_data) # 每张票平均分配的券数量列表 # 多余的券添加到每张票上 for i in range(int(pay_type['ticket_quan']['ticket_quan_num'])%len(seat_data)): quan_price_num[i] += 1 print('quan_price_num', quan_price_num) # 遍历座位券列表,获取座位id,并写入列表 for index, num in enumerate(quan_price_num): for i in range(num): seat_id_quan_list.append(seat_data[index]['cineSeatId']) print('seat_id_quan_list', seat_id_quan_list) # 生成券字段列表 quan_price = f2(pay_type['ticket_quan']['ticket_quan_value']) quan_num = int(pay_type['ticket_quan']['ticket_quan_num']) for i in range(quan_num): seat_id = seat_id_quan_list[i] quan_list.append(f"{seat_id}-Rog接口测试券{str(quan_price)}@@rog{str(time.time_ns())}{seat_id}@@{str(quan_price)}@@0") quan_price_list.append(quan_price) seat_coupons = ','.join(quan_list) if len(quan_list) > 0 else None # 生成券字段 ticket_price = f2(pay_type['ticket_info']['ticket_price']) ticket_service = f2(f2(seat_data_price['totalServiceCharge']) / int(seat_data_price['ticketNum'])) ticket_price_service = f2(ticket_price + ticket_service) cash_pay = 0 for i, seat in enumerate(seat_data): if i+1 <= len(quan_price_list): real_pay_tmp = f2(ticket_price_service - (quan_price_list[i] * quan_price_num[i])) # 实付票价减去券核销的价格 else: real_pay_tmp = ticket_price_service # 无券核销的实付价格 if is_split_service_fee == 'N': real_pay_tmp -= ticket_service # 如果不包含服务费,则要从实付价格中减去服务费 real_pay = real_pay_tmp if real_pay_tmp > 0 else 0 # 因为使用了券,实付价格可能低于0,需要修正到0 if card_type == '权益卡(积分卡)': cash_pay += f2(real_pay + handle_fee) # 当使用权益卡支付时,需要将实付票价累加到现金支付字段中 else: cash_pay += 0 if ticket_price >= lowest_price: real_ticket_price = ticket_price_service # 计算应付票价,如果用户设定的票价低于最低票价,则按照最低票价计算,否则按照用户定义价计算 else: real_ticket_price = f2(lowest_price + ticket_service) if is_split_service_fee == 'N': real_ticket_price -= ticket_service # 如果不包含服务费,则要减去服务费 if card_type == '权益卡(积分卡)': cash_pay += ticket_service # 如果是权益卡则单独累加服务费 seat_list.append( f"{seat['cineSeatId']}-{str(handle_fee)}-{str(real_pay)}-会员票-1-{str(real_ticket_price)}-{str(ticket_service)}") return True, ','.join( seat_list), play_id, play_update_time, lock_flag, seat_coupons, is_cinema_price, is_split_service_fee, str(cash_pay), last_timestamp