예제 #1
0
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
예제 #2
0
    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
예제 #3
0
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
예제 #4
0
    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)
예제 #5
0
 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
예제 #6
0
 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
예제 #7
0
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
예제 #8
0
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 {}
예제 #9
0
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
예제 #10
0
 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)
예제 #11
0
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
예제 #12
0
 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
예제 #13
0
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
예제 #14
0
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)
예제 #15
0
 def tax(self):
     taxes = as_list(self.data.get('tax'))
     return [ActorTax(data=item) for item in taxes]
예제 #16
0
 def processors(self):
     procs = as_list(self.data.get('processor'))
     return [ActorProcessor(data=item) for item in procs]
예제 #17
0
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
예제 #18
0
 def carriers(self):
     carriers_data = as_list(self.data.get('carrier'))
     return [ActorCarrier(data=carrier) for carrier in carriers_data]
예제 #19
0
 def services(self):
     services_data = as_list(self.data.get('service'))
     return [ActorService(data=service) for service in services_data]
예제 #20
0
 def invoices(self):
     invoices = as_list(self.data.get('invoice'))
     return [ActorInvoice(data=item) for item in invoices]
예제 #21
0
 def items(self):
     items = as_list(self.data.get('item'))
     return [ActorItem(data=item) for item in items]
예제 #22
0
 def subitem(self):
     subitems = as_list(self.data.get('subitem'))
     return [ActorSubItem(data=item) for item in subitems]
예제 #23
0
 def option_list(self):
     op_list = as_list(self.data.get('option'))
     return [ActorOption(data=item) for item in op_list]
예제 #24
0
 def carriers(self):
     carriers_list = as_list(self.data.get('carrier'))
     return [ActorCarrier(data=item) for item in carriers_list]
예제 #25
0
 def items_json(self):
     items = as_list(self.data.get('item'))
     return ujson.dumps(items)
예제 #26
0
 def valid_items(self):
     items_data = as_list(self.data.get('item'))
     return [ActorItem(data=item) for item in items_data if item['name']]
예제 #27
0
 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 {}
예제 #28
0
 def shipments(self):
     shipments_data = as_list(self.data.get('shipment'))
     return [ActorShipment(data=spm) for spm in shipments_data]
예제 #29
0
    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,
        }
예제 #30
0
 def regs(self):
     regs_data = as_list(self.data['id'])
     return [Registration(data=item) for item in regs_data]