def get_shipping_info(req, resp, order_id): from common.data_access import data_access xml_resp = data_access(REMOTE_API_NAME.GET_SHIPPING_LIST, req, resp, id_order=order_id) shipments = xmltodict.parse(xml_resp)['shipments'] shipment_info = {} need_select_carrier = False for shipment in as_list(shipments['shipment']): method = int(shipment['@method']) if method == SCM.CARRIER_SHIPPING_RATE: if not shipment['delivery'].get('@postage'): xml_resp = data_access(REMOTE_API_NAME.GET_SHIPPING_FEE, req, resp, shipment=shipment['@id']) carriers = xmltodict.parse(xml_resp)['carriers'] shipment['delivery'].update({'carrier': carriers['carrier']}) need_select_carrier = True else: pass shipment['delivery'].update({'carrier': as_list(shipment['delivery'].get('carrier'))}) for car in shipment['delivery']['carrier']: car['service'] = as_list(car['service']) shipment['item'] = as_list(shipment['item']) shipment['@method'] = SCM.toReverseDict().get(int(shipment['@method'])) shipment_info[shipment['@id']] = shipment data = { 'order_id': order_id, 'order_created': format_date(shipments['@order_create_date']), 'shipments_detail': shipment_info, 'need_select_carrier': need_select_carrier, } return data
def _get_from_redis(self, obj_id=None, **kw): if obj_id: obj_ids = [obj_id] else: obj_ids = self._filter_obj_ids(**kw) resp_dict = {} types = {} categories = {} shops = {} for _id in obj_ids: obj = self.redis_cli.get(self.obj_redis_key % _id) if obj: resp_dict[_id] = ujson.loads(obj) type_id = resp_dict[_id].get('type', {}).get('@id') cate_id = resp_dict[_id].get('category', {}).get('@id') if type_id and type_id not in types: t_obj = self.redis_cli.get(TYPE % type_id) if t_obj: types[type_id] = ujson.loads(t_obj) if cate_id and cate_id not in categories: categories[cate_id] = ujson.loads( self.redis_cli.get(CATEGORY % cate_id) or "{}") shop_list = as_list(resp_dict[_id].get('shop')) for s in shop_list: shop_id = s.get('@id') if shop_id and shop_id not in shops: shops[shop_id] = ujson.loads( self.redis_cli.get(SHOP % shop_id)) for sale in resp_dict.itervalues(): # update shop and brand info new_shops = [] brand = None for s in as_list(sale.get('shop')): shop_id = s.get('@id') if shop_id and shops[shop_id]: shop_info = copy.deepcopy(shops[shop_id]) brand = shop_info.pop('brand') new_shops.append(shop_info) else: new_shops.append(s) sale['shop'] = new_shops if brand: sale['brand'] = brand type_id = sale.get('type', {}).get('@id') category_id = sale.get('category', {}).get('@id') if type_id and type_id in types: # update type name sale['type']['name'] = types[type_id].get('name', '') # update category info if category_id and categories.get(category_id): sale['category'] = categories.get(category_id, {}) return resp_dict
def _out_of_stock(sale_info, id_variant, id_type, id_shop, quantity): if not id_variant: id_variant = '' if not id_type: id_type = '' if not id_shop or id_shop == '0': id_shop = '' for stock in as_list(sale_info['available'].get('stocks')): if stock['@attribute'] == str(id_type) and stock['@variant'] == str(id_variant): for s in as_list(stock.get('stock')): if s['@shop'] == str(id_shop): if int(s['#text']) < quantity: return True break break return False
def parse_xml(self, xml, is_entire_result, **kw): logging.info('parse types xml: %s, is_entire_result:%s', xml, is_entire_result) data = xmltodict.parse(xml) data = data.get('types', data.get('info')) version = data['@version'] types = as_list(data.get('type', None)) cats = as_list(data.get('category', None)) try: self._refresh_redis(version, types, is_entire_result, **kw) self._refresh_cats_redis(cats, **kw) except (RedisError, ConnectionError), e: logging.error('Redis Error: %s', (e,), exc_info=True)
def get(self, **kw): taxes = super(TaxesCacheProxy, self).get(**kw) from_country = kw.get('fromCountry') from_province = kw.get('fromProvince') to_country = kw.get('toCountry') to_province = kw.get('toProvince') category = kw.get('category') taxes = dict([ (k, v) for k, v in taxes.iteritems() if v['country'] == from_country and ( 'province' not in v or from_province and v['province'] == from_province) and (v['shipping']['@country'] == 'None' or v['shipping']['@country'] == to_country) and ('@province' not in v['shipping'] or to_province and v['shipping']['province'] == to_province) ]) resp_dict = {} for k, v in taxes.iteritems(): category_conds = [ cond for cond in as_list(v.get('apply')) if cond.get('@to') ] if category_conds: for cond in category_conds: if cond['@to'] == category: resp_dict[k] = v break else: resp_dict[k] = v return resp_dict
def registrations(self): types = as_list(self.data.get('id')) regs = {} for type_ in types: act = ActorRegistration(data=type_) regs[act.type] = act return regs
def _get_invoice_ids(invoices_resp): err = (invoices_resp.get('error') or invoices_resp.get('err')) if isinstance(invoices_resp, dict) else "" if err or 'content' not in invoices_resp: id_invoices = [] else: invoices = as_list(invoices_resp['content']) id_invoices = [long(iv['id']) for iv in invoices_resp['content']] return id_invoices
def get_valid_attr(attrlist, attr_id): if not attr_id or not attrlist: return {} attrlist = as_list(attrlist) for attr in attrlist: if attr['@id'] == str(attr_id): return attr return {}
def _get_shop_addr(sale_info, id_shop=None): country_code = province_code = None for shop in as_list(sale_info.get('shop')): if id_shop and shop['@id'] != str(id_shop): continue addr = shop.get('address', {}).get('country') if addr and addr.get("#text"): country_code = addr["#text"] province_code = addr.get("@province") break return country_code, province_code
def parse_xml(self, xml, is_entire_result, **kw): logging.info('parse brandsettings xml: %s, is_entire_result:%s', xml, is_entire_result) data = xmltodict.parse(xml) data = data.get('settings', {}) version = data['@version'] g_settings = as_list(data.get('setting', None)) try: self._refresh_redis(version, g_settings, is_entire_result) except (RedisError, ConnectionError), e: logging.error('Redis Error: %s', (e,), exc_info=True)
def get_brief_product(sale, req, resp, calc_price=True, is_business_account=False): id_sale = sale['@id'] _type = sale.get('type', {}) short_desc = sale.get('short_desc') or '' if short_desc == 'None': short_desc = '' product_info = { 'id': id_sale, 'name': sale.get('name') or '', 'desc': sale.get('desc') or '', 'short_desc': short_desc, 'img': sale.get('img') or '', 'link': get_url_format(FRT_ROUTE_ROLE.PRDT_INFO) % { 'id_type': _type.get('@id', 0), 'type_name': get_normalized_name(FRT_ROUTE_ROLE.PRDT_INFO, 'type_name', _type.get('name', '')), 'id_sale': id_sale, 'sale_name': get_normalized_name(FRT_ROUTE_ROLE.PRDT_INFO, 'sale_name', sale.get('name', '')), }, 'currency': sale.get('price', {}).get('@currency') or '', 'variant': as_list(sale.get('variant')), } if calc_price: price = get_product_default_display_price(sale)[1] for v in product_info['variant']: price = cal_price_with_premium(v, price) break country_code, province_code = _get_shop_addr(sale) if not country_code: country_code, province_code = _get_brand_addr(sale) _cate_id = sale.get('category', {}).get('@id', 0) #TODO: call user_country_province() to get user location ?? user_country_code, user_province_code = None, None tax_info = get_category_tax_info(req, resp, country_code, province_code, user_country_code, user_province_code, _cate_id, is_business_account) product_info['price'] = price if calc_before_tax_price(req, resp): product_info['price_with_tax_calc'] = price * (1 + tax_info['rate'] / 100.0) else: product_info['price_with_tax_calc'] = price / (1 + tax_info['rate'] / 100.0) product_info['show_final_price'] = tax_info['show_final_price'] if not settings.PRODUCTION and not product_info['img']: product_info['img'] = '/img/dollar-example.jpg' return product_info
def _on_get(self, req, resp, **kwargs): id_order = req.get_param('id_order') id_invoices = req.get_param('id_invoices') remote_resp = data_access(REMOTE_API_NAME.INIT_PAYMENT, req, resp, order=id_order, invoices=id_invoices) err = (remote_resp.get('error') or remote_resp.get('err')) \ if isinstance(remote_resp, dict) else "" if err: id_trans = "" processors = [] else: payment = xmltodict.parse(remote_resp) err = payment.get('error', {}).get('#text') if err: err = "Error Message: %s" % err processors = as_list(payment.get('payment', {}).get('processor')) id_trans = payment.get('payment', {}).get('@transaction') if settings.BRAND_NAME == "DRAGONDOLLAR": processors = [ p for p in processors if int(p['@id']) in (PAYMENT_TYPES.PAYPAL, PAYMENT_TYPES.STRIPE) ] if settings.BRAND_NAME == "BREUER": processor = PAYMENT_TYPES.PAYBOX return self._payment_form(req, resp, id_trans=id_trans, processor=processor, id_order=id_order) data = { 'step': 'init', 'err': err, 'id_trans': id_trans, 'processors': processors, 'id_order': id_order } return data
def order_items_match_group(order_items, groups, conds, operation): group_conds = [ m['id'] for m in conds if m['id_type'] == COUPON_CONDITION_IDTYPE.GROUP ] for id_group in group_conds: group = groups.get(str(id_group)) if not group: continue group_sales = [int(s['@id']) for s in as_list(group['sales']['sale'])] matched_items = [ o['sale_id'] for o in order_items if o['brand_id'] == int(group['brand']['@id']) and o['shop_id'] == int(group['shop']['@id']) and o['sale_id'] in group_sales ] if operation == COUPON_CONDITION_OPERATION.MATCH_ALL: if len(set(matched_items)) == len(group_sales): return True else: if len(matched_items) > 0: return True return False
def get_product_default_display_price(sale, type_attr=None): ori_price = sale.get('price', {}).get('#text') or '' discount_price = sale.get('discount_price') valid_from = sale.get('discount', {}).get('@from') or '' valid_to = sale.get('discount', {}).get('@to') or '' if type_attr: if 'price' in type_attr: ori_price = type_attr['price'].get('#text') discount_price = type_attr.get('discount_price') else: for type_attr in as_list(sale.get('type', {}).get('attribute')): if 'price' in type_attr: ori_price = type_attr['price'].get('#text') discount_price = type_attr.get('discount_price') break if not discount_price: discount_price = ori_price now = datetime.datetime.utcnow() if valid_from and parse_ts(valid_from) > now \ or valid_to and parse_ts(valid_to) < now: discount_price = ori_price return float(ori_price), float(discount_price)
def tax(self): taxes = as_list(self.data.get('tax')) return [ActorTax(data=item) for item in taxes]
def processors(self): procs = as_list(self.data.get('processor')) return [ActorProcessor(data=item) for item in procs]
def send_order_email(conn, id_order): order_resp = get_order_detail(conn, id_order, 0) user_profile = order_resp.get('user_info') first_name = user_profile.get('first_name') user_email = get_user_email(conn, user_profile.get('users_id')) shipping_lists = [] for item in order_resp.get('order_items', []): for item_id, item_info in item.iteritems(): id_sale = str(item_info['sale_id']) if item_info['id_variant'] == 0: product_name = item_info['name'] variant_name = '' else: product_name, variant_name = item_info['name'].rsplit('-', 1) one = { 'id_sale': id_sale, 'quantity': item_info['quantity'], 'product_name': product_name, 'variant_name': variant_name, 'type_name': item_info.get('type_name') or '', 'price': item_info['price'], 'picture': item_info['picture'], } item_invoice_info = {} for iv in item_info['invoice_info']: iv_item_info = ujson.loads(iv['invoice_item']) if iv_item_info: taxes = as_list(iv_item_info.get('tax', {})) iv['tax'] = sum([ float(t['#text']) for t in taxes if t.get('@to_worldwide') == 'True' or t.get('@show') == 'True' ]) iv['tax_per_item'] = iv['tax'] / int(iv_item_info['qty']) iv['show_final_price'] = len( [t for t in taxes if t.get('@show') == 'True']) > 0 else: iv['tax'] = 0 iv['tax_per_item'] = 0 iv['show_final_price'] = False item_invoice_info[iv['shipment_id']] = iv for _shipment_info in item_info['shipment_info']: shipment_id = _shipment_info.get('shipment_id') if not shipment_id: # sth. wrong when create order continue shipping_list = _shipment_info.copy() shipping_list.update(item_invoice_info.get(shipment_id)) shipping_list['item'] = one shipping_list['currency'] = cur_symbol( shipping_list['currency']) shipping_lists.append(shipping_list) data = { 'first_name': first_name, 'order_id': id_order, 'shipping_lists': shipping_lists, 'order_invoice_url': settings.FRONT_ORDER_INVOICE_URL % { 'id_order': id_order }, } email_content = render_content('order_email.html', base_url=settings.FRONT_ROOT_URI, **to_unicode(data)) gevent.spawn(send_html_email, user_email, settings.ORDER_EMAIL_SUBJECT, email_content) return data
def carriers(self): carriers_data = as_list(self.data.get('carrier')) return [ActorCarrier(data=carrier) for carrier in carriers_data]
def services(self): services_data = as_list(self.data.get('service')) return [ActorService(data=service) for service in services_data]
def invoices(self): invoices = as_list(self.data.get('invoice')) return [ActorInvoice(data=item) for item in invoices]
def items(self): items = as_list(self.data.get('item')) return [ActorItem(data=item) for item in items]
def subitem(self): subitems = as_list(self.data.get('subitem')) return [ActorSubItem(data=item) for item in subitems]
def option_list(self): op_list = as_list(self.data.get('option')) return [ActorOption(data=item) for item in op_list]
def carriers(self): carriers_list = as_list(self.data.get('carrier')) return [ActorCarrier(data=item) for item in carriers_list]
def items_json(self): items = as_list(self.data.get('item')) return ujson.dumps(items)
def valid_items(self): items_data = as_list(self.data.get('item')) return [ActorItem(data=item) for item in items_data if item['name']]
def _get_meta_by_route(self, route): meta = route.get('meta', None) and as_list(route['meta']) or None return meta and dict(map(lambda x: [x['@name'], x['#text']], meta)) or {}
def shipments(self): shipments_data = as_list(self.data.get('shipment')) return [ActorShipment(data=spm) for spm in shipments_data]
def _on_get(self, req, resp, **kwargs): is_routed = is_routed_template(self.role) sale_id = kwargs.get('id_sale') if not sale_id: raise ValidationError('ERR_ID') sale_name = type_id = type_name = None if is_routed: sale_name = kwargs.get('sale_name') if not sale_name: raise ValidationError('ERR_Name') type_id = kwargs.get('id_type') if not type_id: raise ValidationError('ERR_ID') type_name = kwargs.get('type_name') if not type_name: raise ValidationError('ERR_NAME') # all sales all_sales = data_access(REMOTE_API_NAME.GET_SALES, req, resp) if not all_sales or sale_id not in all_sales: raise ValidationError('ERR_ID') product_info = all_sales[sale_id] product_info['desc'] = product_info.get('desc', '').split('\n') if is_routed: type_info = get_type_from_sale(product_info) normalized_type_name = get_normalized_name( FRT_ROUTE_ROLE.PRDT_INFO, 'type_name', type_info['name']) normalized_sale_name = get_normalized_name( FRT_ROUTE_ROLE.PRDT_INFO, 'sale_name', product_info.get('name', '')) if type(normalized_type_name) is unicode: normalized_type_name = normalized_type_name.encode('UTF-8') if type(normalized_sale_name) is unicode: normalized_sale_name = normalized_sale_name.encode('UTF-8') if normalized_type_name != type_name or \ normalized_sale_name != sale_name: self.redirect( get_url_format(FRT_ROUTE_ROLE.PRDT_INFO) % { 'id_type': type_id, 'type_name': normalized_type_name, 'id_sale': sale_id, 'sale_name': normalized_sale_name, }) return # product info if not settings.PRODUCTION and not product_info.get('img'): product_info['img'] = '/img/dollar-example.jpg' product_info['variant'] = as_list(product_info.get('variant')) # price product_info['display'] = dict() ori_price, price = get_product_default_display_price(product_info) product_info['display']['price'] = price product_info['display']['ori_price'] = ori_price ## if it uses type attribute price, disable the type attribute ## which has no price. type_attrs = as_list(product_info.get('type', {}).get('attribute')) if 'type' in product_info: product_info['type']['attribute'] = type_attrs unified_price = product_info.get('price', {}).get('#text') if not unified_price: for type_attr in type_attrs: if (not 'price' in type_attr or not float(type_attr['price'].get('#text', 0))): type_attr['disabled'] = True ## Disable the type attribute which has no quantity. stocks = as_list(product_info.get('available', {}).get('stocks')) if 'available' in product_info: product_info['available']['stocks'] = stocks for stock in stocks: stock['stock'] = as_list(stock.get('stock')) for type_attr in type_attrs: stock = sum([ sum(int(ss.get('#text', 0)) for ss in x.get('stock')) for x in stocks if x.get('@attribute') == type_attr.get('@id') ]) if stock <= 0: type_attr['disabled'] = True ## Disable the brand attribute which has no quantity. variants = as_list(product_info.get('variant')) product_info['variant'] = variants for var in variants: stock = sum([ sum(int(ss.get('#text', 0)) for ss in x.get('stock')) for x in stocks if x.get('@variant') == var.get('@id') ]) if stock <= 0: var['disabled'] = True taxes_rate = {} _cate_id = product_info.get('category', {}).get('@id', 0) shops = dict([(node['@id'], node) for node in as_list(product_info.get('shop'))]) shops.update({"0": product_info.get('brand', {})}) show_final_price = False for _id, node in shops.iteritems(): addr = node.get('address', {}).get('country') if addr and addr.get("#text"): country_code = addr["#text"] province_code = addr.get("@province") user_country_code, user_province_code = \ user_country_province(req, resp, self.users_id) is_business_account = \ user_is_business_account(req, resp, self.users_id) category_tax_info = get_category_tax_info( req, resp, country_code, province_code, user_country_code, user_province_code, _cate_id, is_business_account) taxes_rate[_id] = category_tax_info['rate'] show_final_price = category_tax_info['show_final_price'] return { 'cur_type_id': type_id, 'product_info': product_info, 'product_list': get_random_products(all_sales, req, resp, self.users_id), 'taxes_rate': taxes_rate, 'show_final_price': show_final_price, }
def regs(self): regs_data = as_list(self.data['id']) return [Registration(data=item) for item in regs_data]