Esempio n. 1
0
    def charges(self, type=None, start_time=None,
                end_time=None, limit=None, offset=None):
        """Get this account's charge records."""

        if limit and limit < 0:
            raise exception.InvalidParameterValue(err="Invalid limit")
        if offset and offset < 0:
            raise exception.InvalidParameterValue(err="Invalid offset")

        user_id = acl.get_limited_to_user(
            request.headers, 'account_charge') or self._id

        self.conn = pecan.request.db_conn
        charges = self.conn.get_charges(request.context,
                                        user_id=user_id,
                                        type=type,
                                        limit=limit,
                                        offset=offset,
                                        start_time=start_time,
                                        end_time=end_time)
        charges_list = []
        for charge in charges:
            charges_list.append(models.Charge.from_db_model(charge))

        total_price, total_count = self.conn.get_charges_price_and_count(
            request.context, user_id=user_id, type=type,
            start_time=start_time, end_time=end_time)
        total_price = gringutils._quantize_decimal(total_price)

        return models.Charges.transform(total_price=total_price,
                                        total_count=total_count,
                                        charges=charges_list)
Esempio n. 2
0
    def get_all(self,
                type=None,
                limit=None,
                offset=None,
                region_id=None,
                user_id=None,
                project_id=None,
                owed=None,
                charged=None,
                bill_methods=None):

        if limit and limit < 0:
            raise exception.InvalidParameterValue(err="Invalid limit")
        if offset and offset < 0:
            raise exception.InvalidParameterValue(err="Invalid offset")

        conn = pecan.request.db_conn
        orders = conn.get_active_orders(request.context,
                                        type=type,
                                        limit=limit,
                                        offset=offset,
                                        region_id=region_id,
                                        user_id=user_id,
                                        project_id=project_id,
                                        owed=owed,
                                        charged=charged,
                                        bill_methods=bill_methods)
        return [models.Order.from_db_model(order) for order in orders]
Esempio n. 3
0
    def get(self, offset=None, limit=None):
        """Get the accounts of this sales person."""
        context = pecan.request.context
        if not acl.limit_to_sales(context, self.sales_id):
            raise exception.NotAuthorized()

        if limit and limit < 0:
            raise exception.InvalidParameterValue(err="Invalid limit")
        if offset and offset < 0:
            raise exception.InvalidParameterValue(err="Invalid offset")

        conn = pecan.request.db_conn
        accounts_number, sales_amount = conn.get_salesperson_amount(
            context, self.sales_id)
        accounts = conn.get_salesperson_customer_accounts(
            context, self.sales_id, offset, limit)
        account_list = []
        for account in accounts:
            user = kunkka.get_uos_user(account.user_id)
            account_list.append(
                models.SalesPersonAccount(user_id=account.user_id,
                                          user_name=user['name'],
                                          user_email=user.get('email', ''),
                                          real_name=user.get('real_name', ''),
                                          mobile_number=user.get('phone', ''),
                                          company=user.get('company', ''),
                                          balance=account.balance,
                                          consumption=account.consumption,
                                          owed=account.owed))

        return models.SalesPersonAccounts(total_count=accounts_number,
                                          accounts=account_list)
Esempio n. 4
0
    def get_all(self,
                user_id=None,
                limit=None,
                offset=None,
                sort_key='dispatched,used',
                sort_dir='asc'):
        """Get all precharges."""
        context = pecan.request.context
        conn = pecan.request.db_conn
        check_policy(context, "account:precharge")

        if limit and limit < 0:
            raise exception.InvalidParameterValue(err="Invalid limit")
        if offset and offset < 0:
            raise exception.InvalidParameterValue(err="Invalid offset")

        try:
            precharges = conn.get_precharges(context,
                                             user_id=user_id,
                                             limit=limit,
                                             offset=offset,
                                             sort_key=sort_key,
                                             sort_dir=sort_dir)
            total_count = conn.get_precharges_count(context, user_id=user_id)
            pecan.response.headers['X-Total-Count'] = str(total_count)
        except Exception as e:
            LOG.exception('Failed to get all precharges')
            raise exception.DBError(reason=e)

        precharges = [models.PreCharge.from_db_model(p) for p in precharges]
        return models.PreCharges.transform(precharges=precharges,
                                           total_count=total_count)
Esempio n. 5
0
    def get(self, user_id=None, type=None, start_time=None,
            end_time=None, limit=None, offset=None,
            sort_key='created_at', sort_dir='desc'):
        """Get all charges of all account."""

        check_policy(request.context, "charges:all")

        if limit and limit < 0:
            raise exception.InvalidParameterValue(err="Invalid limit")
        if offset and offset < 0:
            raise exception.InvalidParameterValue(err="Invalid offset")

        users = {}

        def _get_user(user_id):
            user = users.get(user_id)
            if user:
                return user
            contact = kunkka.get_uos_user(user_id) or {}
            user_name = contact.get('name')
            email = contact.get('email')
            real_name = contact.get('real_name')
            mobile = contact.get('phone')
            company = contact.get('company')
            users[user_id] = models.User(user_id=user_id,
                                         user_name=user_name,
                                         email=email,
                                         real_name=real_name,
                                         mobile=mobile,
                                         company=company)
            return users[user_id]

        self.conn = pecan.request.db_conn
        charges = self.conn.get_charges(request.context,
                                        user_id=user_id,
                                        type=type,
                                        limit=limit,
                                        offset=offset,
                                        start_time=start_time,
                                        end_time=end_time,
                                        sort_key=sort_key,
                                        sort_dir=sort_dir)
        charges_list = []
        for charge in charges:
            acharge = models.Charge.from_db_model(charge)
            acharge.actor = _get_user(charge.operator)
            acharge.target = _get_user(charge.user_id)
            charges_list.append(acharge)

        total_price, total_count = self.conn.get_charges_price_and_count(
            request.context, user_id=user_id, type=type,
            start_time=start_time, end_time=end_time)
        total_price = gringutils._quantize_decimal(total_price)

        return models.Charges.transform(total_price=total_price,
                                        total_count=total_count,
                                        charges=charges_list)
Esempio n. 6
0
def transform_unit_price_string(data):
    price_type = ['price', 'monthly_price', 'yearly_price']
    json_data = json.loads(data)

    for p in price_type:
        if p in json_data:
            if 'segmented' not in json_data[p]:
                err = 'Should have the segmented'
                raise exception.InvalidParameterValue(err=err)
            # transform SegmentedItem
            segmented = json_data[p]['segmented']
            new_seg = []
            for s in segmented:
                s['price'] = _quantize_decimal(s['price'])
                new_seg.append(models.SegmentedItem.transform(**s))
            json_data[p]['segmented'] = new_seg

            # transform PriceData
            if 'base_price' not in json_data[p]:
                json_data[p]['base_price'] = \
                    _quantize_decimal(0)
            json_data[p]['base_price'] = \
                _quantize_decimal(json_data[p]['base_price'])
            json_data[p] = models.PriceData.transform(**json_data[p])
    return models.UnitPriceData.transform(**json_data)
Esempio n. 7
0
    def get_all(self,
                name=None,
                service=None,
                region_id=None,
                limit=None,
                offset=None,
                sort_key='created_at',
                sort_dir='desc'):
        """Get all product."""

        if limit and limit < 0:
            raise exception.InvalidParameterValue(err="Invalid limit")
        if offset and offset < 0:
            raise exception.InvalidParameterValue(err="Invalid offset")

        filters = {}
        if name:
            filters.update(name=name)
        if service:
            filters.update(service=service)
        if region_id:
            filters.update(region_id=region_id)

        conn = pecan.request.db_conn

        result = conn.get_products(request.context,
                                   filters=filters,
                                   limit=limit,
                                   offset=offset,
                                   sort_key=sort_key,
                                   sort_dir=sort_dir)
        products = []
        for p in result:
            unit_price = \
                gringutils.transform_unit_price_string(p.unit_price)
            sp = models.Product.transform(name=p.name,
                                          service=p.service,
                                          region_id=p.region_id,
                                          product_id=p.product_id,
                                          description=p.description,
                                          unit_price=unit_price,
                                          created_at=p.created_at,
                                          updated_at=p.updated_at)
            products.append(sp)
        total_count = conn.get_products_count(request.context, filters=filters)
        return models.Products(total_count=total_count, products=products)
Esempio n. 8
0
    def __init__(self, unit_price):
        try:
            self.unit_price = unit_price
        except (Exception) as e:
            err = 'Extra data is not a valid JSON string, %s' % (e)
            LOG.warning(err)
            raise exception.InvalidParameterValue(err=err)

        self.new_unit_price = {}
Esempio n. 9
0
    def get_all(self, purchase):
        """Get price of a group of products."""

        if purchase.bill_method not in ['hour', 'month', 'year']:
            err = 'Should specify bill_method among hour, month and year'
            raise exception.InvalidParameterValue(err=err)

        if not isinstance(purchase.bill_period, int):
            purchase.bill_period = 1

        conn = pecan.request.db_conn

        unit_price = quantize_decimal(0)
        unit = purchase.bill_method

        for p in purchase.purchases:
            if all([p.product_id, p.quantity]):
                try:
                    product = conn.get_product(request.context, p.product_id)
                except exception.ProductIdNotFound:
                    LOG.warn("Product %s not found" % p.product_id)
                    raise
            elif all([p.product_name, p.service, p.region_id, p.quantity]):
                filters = dict(name=p.product_name,
                               service=p.service,
                               region_id=p.region_id)
                products = list(
                    conn.get_products(request.context, filters=filters))
                if len(products) == 0:
                    LOG.error('Product %s of region %s not found',
                              p.product_name, p.region_id)
                    raise exception.ProductNameNotFound(
                        product_name=p.product_name)
                product = products[0]
            else:
                err = "Every purchase item should specify product_name, "\
                      "service, region_id and quantity or "\
                      "product_id and quantity."
                raise exception.MissingRequiredParams(reason=err)
            try:
                if product.unit_price:
                    unit_price_data = jsonutils.loads(product.unit_price)
                    price_data = pricing.get_price_data(unit_price_data, unit)
                else:
                    price_data = None

                unit_price += pricing.calculate_price(p.quantity, price_data)
            except (Exception) as e:
                LOG.error('Calculate price of product %s failed, %s',
                          p.product_name, e)
                raise e
        total_price = unit_price * purchase.bill_period
        return models.Price.transform(unit_price=unit_price,
                                      unit=unit,
                                      total_price=total_price)
Esempio n. 10
0
    def _validate_renew(self, renew):
        err = None
        if 'method' not in renew or 'period' not in renew:
            err = 'Must specify method and period'
        elif renew['method'] not in ['month', 'year']:
            err = 'Wrong method, should be month or year'
        elif not isinstance(renew['period'], int) or renew['period'] <= 0:
            err = 'Wrong period, should be an integer greater than 0'

        if err:
            LOG.warn(err)
            raise exception.InvalidParameterValue(err=err)
Esempio n. 11
0
    def get_all(self, owed=None, limit=None, offset=None, duration=None):
        """Get all accounts."""

        check_policy(request.context, "account:all")

        if limit and limit < 0:
            raise exception.InvalidParameterValue(err="Invalid limit")
        if offset and offset < 0:
            raise exception.InvalidParameterValue(err="Invalid offset")

        self.conn = pecan.request.db_conn

        duration = gringutils.normalize_timedelta(duration)
        if duration:
            active_from = datetime.datetime.utcnow() - duration
        else:
            active_from = None

        try:
            accounts = self.conn.get_accounts(request.context,
                                              owed=owed,
                                              limit=limit,
                                              offset=offset,
                                              active_from=active_from)
            count = self.conn.get_accounts_count(request.context,
                                                 owed=owed,
                                                 active_from=active_from)
            pecan.response.headers['X-Total-Count'] = str(count)
        except exception.NotAuthorized as e:
            LOG.exception('Failed to get all accounts')
            raise exception.NotAuthorized()
        except Exception as e:
            LOG.exception('Failed to get all accounts')
            raise exception.DBError(reason=e)

        accounts = [
            models.AdminAccount.from_db_model(account) for account in accounts
        ]

        return models.AdminAccounts(total_count=count, accounts=accounts)
Esempio n. 12
0
    def get_all(self,
                start_time=None,
                end_time=None,
                type=None,
                project_id=None,
                limit=None,
                offset=None):

        if limit and limit < 0:
            raise exception.InvalidParameterValue(err="Invalid limit")
        if offset and offset < 0:
            raise exception.InvalidParameterValue(err="Invalid offset")

        conn = pecan.request.db_conn

        bills_db = list(
            conn.get_bills(pecan.request.context,
                           project_id=project_id,
                           start_time=start_time,
                           end_time=end_time,
                           type=type,
                           limit=limit,
                           offset=offset))
        total_count, total_price = conn.get_bills_count_and_sum(
            pecan.request.context,
            project_id=project_id,
            start_time=start_time,
            end_time=end_time,
            type=type)

        total_price = gringutils._quantize_decimal(total_price)

        bills = []
        for bill in bills_db:
            bills.append(models.Bill.from_db_model(bill))

        return models.Bills.transform(total_price=total_price,
                                      total_count=total_count,
                                      bills=bills)
Esempio n. 13
0
    def invitees(self, limit=None, offset=None):
        """Get invitees of the inviter."""

        if limit and limit < 0:
            raise exception.InvalidParameterValue(err="Invalid limit")
        if offset and offset < 0:
            raise exception.InvalidParameterValue(err="Invalid offset")

        inviter = acl.get_limited_to_user(request.headers,
                                          'referees_get') or self._id

        self.conn = pecan.request.db_conn
        try:
            _invitees, total_count = self.conn.get_invitees(request.context,
                                                            inviter,
                                                            limit=limit,
                                                            offset=offset)
        except Exception as e:
            LOG.exception('Fail to get invitees')
            raise exception.DBError(reason=e)

        invitees = []
        for invitee in _invitees:
            user = keystone.get_uos_user(invitee.user_id)
            if user:
                user_name = user.get('real_name') or user['email'].split(
                    '@')[0]
                user_email = user['email']
            else:
                user_name = ""
                user_email = ""
            invitees.append(
                models.Invitee(user_id=invitee.user_id,
                               user_name=user_name,
                               user_email=user_email,
                               created_at=invitee.created_at,
                               charged=invitee.charged,
                               reward_value=invitee.reward_value))
        return models.Invitees(total_count=total_count, invitees=invitees)
Esempio n. 14
0
    def get(self, start_time=None, end_time=None, limit=None, offset=None):
        """Get this order's detail."""

        if limit and limit < 0:
            raise exception.InvalidParameterValue(err="Invalid limit")
        if offset and offset < 0:
            raise exception.InvalidParameterValue(err="Invalid offset")

        bills = self._order(start_time=start_time,
                            end_time=end_time,
                            limit=limit,
                            offset=offset)
        bills_list = []
        for bill in bills:
            bills_list.append(models.Bill.from_db_model(bill))

        total_count = self.conn.get_bills_count(request.context,
                                                order_id=self._id,
                                                start_time=start_time,
                                                end_time=end_time)

        return models.Bills.transform(total_count=total_count,
                                      bills=bills_list)
Esempio n. 15
0
    def level(self, level):
        if not isinstance(level, int) or level < 0 or level > 9:
            raise exception.InvalidParameterValue(err="Invalid Level")

        self.conn = pecan.request.db_conn
        try:
            account = self.conn.change_account_level(request.context,
                                                     None,
                                                     level,
                                                     project_id=self._id)
        except Exception as e:
            LOG.exception('Fail to change the account level of: %s' % self._id)
            raise exception.DBError(reason=e)

        return models.UserAccount.from_db_model(account)
Esempio n. 16
0
    def level(self, level):
        """Update the account's level."""
        check_policy(request.context, "account:level")

        if not isinstance(level, int) or level < 0 or level > 9:
            raise exception.InvalidParameterValue(err="Invalid Level")

        self.conn = pecan.request.db_conn
        try:
            account = self.conn.change_account_level(request.context, self._id,
                                                     level)
        except Exception as e:
            LOG.exception('Fail to change the account level of: %s' % self._id)
            raise exception.DBError(reason=e)

        return models.UserAccount.from_db_model(account)
Esempio n. 17
0
    def _validate_resize(self, resize):
        err = None
        if 'resource_type' not in resize:
            err = 'Must specify resource_type'

        resource_type = resize['resource_type']
        if resource_type == 'instance':
            params = ['new_flavor', 'old_flavor', 'service', 'region_id']
            for param in params:
                if param not in resize:
                    err = 'Must specify %s' % param
        else:
            if 'quantity' not in resize:
                err = 'Must specify quantity'

        if err:
            LOG.warn(err)
            raise exception.InvalidParameterValue(err=err)
Esempio n. 18
0
    def switch_auto_renew(self, data):
        """Start/Stop auto renew of this order
        """
        if data.action not in ['start', 'stop']:
            err = "Wrong switch renew action, should be start or stop"
            LOG.warn(err)
            raise exception.InvalidParameterValue(err=err)

        conn = pecan.request.db_conn
        try:
            order = conn.switch_auto_renew(request.context, self._id,
                                           data.action)
        except exception.OrderNotFound as e:
            LOG.warn(e)
            raise
        except exception.OrderRenewError as e:
            LOG.warn(e)
            raise
        except Exception:
            msg = "Fail to switch auto renew of the order %s" % self._id
            LOG.exception(msg)
            raise exception.DBError(reason=msg)
        return models.Order.from_db_model(order)
Esempio n. 19
0
    def get(self,
            output_format='xlsx',
            user_id=None,
            start_time=None,
            end_time=None,
            limit=None,
            offset=None):
        """Export all charges of special user, output formats supported:
           * Excel (Sets + Books)
           * JSON (Sets + Books)
           * YAML (Sets + Books)
           * HTML (Sets)
           * TSV (Sets)
           * CSV (Sets)
        """
        if output_format.lower() not in ["xls", "xlsx", "csv", "json", "yaml"]:
            raise exception.InvalidOutputFormat(output_format=output_format)

        if limit and limit < 0:
            raise exception.InvalidParameterValue(err="Invalid limit")
        if offset and offset < 0:
            raise exception.InvalidParameterValue(err="Invalid offset")

        limit_user_id = acl.get_limited_to_user(request.headers,
                                                'export_charges')

        if limit_user_id:
            user_id = limit_user_id

        headers = (u"充值记录ID", u"充值对象用户名", u"充值对象ID", u"充值对象真实姓名", u"充值对象邮箱",
                   u"充值对象公司", u"充值金额", u"充值类型", u"充值来源", u"充值人员ID", u"充值人员用户名",
                   u"充值时间", u"状态")
        data = []

        users = {}

        def _get_user(user_id):
            user = users.get(user_id)
            if user:
                return user
            contact = kunkka.get_uos_user(user_id) or {}
            user_name = contact.get('name')
            email = contact.get('email')
            real_name = contact.get('real_name') or 'unknown'
            mobile = contact.get('phone') or 'unknown'
            company = contact.get('company') or 'unknown'
            users[user_id] = models.User(user_id=user_id,
                                         user_name=user_name,
                                         email=email,
                                         real_name=real_name,
                                         mobile=mobile,
                                         company=company)
            return users[user_id]

        self.conn = pecan.request.db_conn
        charges = self.conn.get_charges(request.context,
                                        user_id=user_id,
                                        limit=limit,
                                        offset=offset,
                                        start_time=start_time,
                                        end_time=end_time)
        for charge in charges:
            charge.charge_time += datetime.timedelta(hours=8)
            acharge = models.Charge.from_db_model(charge)
            acharge.actor = _get_user(charge.operator)
            acharge.target = _get_user(charge.user_id)
            charge_time = \
                timeutils.strtime(charge.charge_time, fmt=OUTPUT_TIME_FORMAT)

            adata = (acharge.charge_id, acharge.target.user_name,
                     acharge.target.user_id, acharge.target.real_name,
                     acharge.target.email, acharge.target.company,
                     str(acharge.value), acharge.type, acharge.come_from,
                     acharge.actor.user_id, acharge.actor.user_name,
                     charge_time, u"正常")
            data.append(adata)

        data = tablib.Dataset(*data, headers=headers)

        response.content_type = "application/binary; charset=UTF-8"
        response.content_disposition = \
            "attachment; filename=charges.%s" % output_format
        content = getattr(data, output_format)
        if output_format == 'csv':
            content = content.decode("utf-8").encode("gb2312")
        response.write(content)
        return response
Esempio n. 20
0
    def get_all(self,
                output_format='xlsx',
                type=None,
                status=None,
                start_time=None,
                end_time=None,
                limit=None,
                offset=None,
                region_id=None,
                project_id=None,
                user_id=None,
                owed=None):
        """Get queried orders
        If start_time and end_time is not None, will get orders that have bills
        during start_time and end_time, or return all orders directly.
        """
        limit_user_id = acl.get_limited_to_user(request.headers,
                                                'export_orders')

        if limit and limit < 0:
            raise exception.InvalidParameterValue(err="Invalid limit")
        if offset and offset < 0:
            raise exception.InvalidParameterValue(err="Invalid offset")

        if limit_user_id:  # normal user
            user_id = None
            projects = keystone.get_projects_by_user(limit_user_id)
            _project_ids = [project['id'] for project in projects]
            if project_id and project_id in _project_ids:
                project_ids = [project_id]
            else:
                project_ids = _project_ids
        else:  # accountant
            if project_id:  # look up specified project
                project_ids = [project_id]
            else:  # look up all projects
                project_ids = []

        if project_ids:
            project_ids = list(set(project_ids) - set(cfg.CONF.ignore_tenants))

        users = {}
        projects = {}

        def _get_user(user_id):
            user = users.get(user_id)
            if user:
                return user
            contact = kunkka.get_uos_user(user_id)
            user_name = contact['name'] if contact else None
            users[user_id] = models.User(user_id=user_id, user_name=user_name)
            return users[user_id]

        def _get_project(project_id):
            project = projects.get(project_id)
            if project:
                return project
            try:
                project = keystone.get_project(project_id)
                project_name = project.name if project else None
                projects[project_id] = models.SimpleProject(
                    project_id=project_id, project_name=project_name)
                return projects[project_id]
            except Exception as e:
                # Note(chengkun): some project was deleted from keystone,
                # But the project's order still in the gringotts. so when
                # we get the order it will raise 404 project not found error
                LOG.error('error to get project: %s' % e)
                return None

        MAP = [
            {
                "running": u"运行中",
                "stopped": u"暂停中",
                "deleted": u"被删除"
            },
            {
                "instance": u"虚拟机",
                "image": u"镜像",
                "snapshot": u"硬盘快照",
                "volume": u"云硬盘",
                "share": u"共享文件",
                "floatingip": u"公网IP",
                "listener": u"负载均衡监听器",
                "router": u"路由器",
                "alarm": u"监控报警"
            },
        ]

        headers = (u"资源ID", u"资源名称", u"资源类型", u"资源状态", u"单价(元/小时)", u"金额(元)",
                   u"区域", u"用户ID", u"用户名称", u"项目ID", u"项目名称", u"创建时间")
        data = []

        adata = (
            u"过滤条件: 资源类型: %s, 资源状态: %s,用户ID: %s, 项目ID: %s, 区域: %s, 起始时间: %s,  结束时间: %s"
            % (type, status, user_id, project_id, region_id, start_time,
               end_time), "", "", "", "", "", "", "", "", "", "", "")
        data.append(adata)

        conn = pecan.request.db_conn
        orders_db, total_count = conn.get_orders(request.context,
                                                 type=type,
                                                 status=status,
                                                 start_time=start_time,
                                                 end_time=end_time,
                                                 owed=owed,
                                                 limit=limit,
                                                 offset=offset,
                                                 with_count=True,
                                                 region_id=region_id,
                                                 user_id=user_id,
                                                 project_ids=project_ids)
        for order in orders_db:
            price = self._get_order_price(order,
                                          start_time=start_time,
                                          end_time=end_time)
            user = _get_user(order.user_id)
            project = _get_project(order.project_id)
            if project is None:
                continue
            order.created_at += datetime.timedelta(hours=8)
            created_at = \
                timeutils.strtime(order.created_at, fmt=OUTPUT_TIME_FORMAT)
            adata = (order.resource_id, order.resource_name,
                     MAP[1][order.type], MAP[0][order.status],
                     order.unit_price, price, order.region_id, user.user_id,
                     user.user_name, project.project_id, project.project_name,
                     created_at)
            data.append(adata)

        data = tablib.Dataset(*data, headers=headers)

        response.content_type = "application/binary; charset=UTF-8"
        response.content_disposition = \
            "attachment; filename=orders.%s" % output_format
        content = getattr(data, output_format)
        if output_format == 'csv':
            content = content.decode("utf-8").encode("gb2312")
        response.write(content)
        return response
Esempio n. 21
0
    def get_all(self,
                type=None,
                status=None,
                start_time=None,
                end_time=None,
                limit=None,
                offset=None,
                resource_id=None,
                region_id=None,
                project_id=None,
                user_id=None,
                owed=None,
                bill_methods=None):
        """Get queried orders
        If start_time and end_time is not None, will get orders that have bills
        during start_time and end_time, or return all orders directly.
        """
        if limit and limit < 0:
            raise exception.InvalidParameterValue(err="Invalid limit")
        if offset and offset < 0:
            raise exception.InvalidParameterValue(err="Invalid offset")

        limit_user_id = acl.get_limited_to_user(request.headers, 'orders_get')

        if limit_user_id:  # normal user
            user_id = None
            projects = keystone.get_project_list(user=limit_user_id)
            _project_ids = [project.id for project in projects]
            if project_id:
                project_ids = ([project_id]
                               if project_id in _project_ids else _project_ids)
            else:
                project_ids = _project_ids
        else:  # accountant
            if project_id:  # look up specified project
                project_ids = [project_id]
            else:  # look up all projects
                project_ids = None

        if project_ids:
            project_ids = list(set(project_ids) - set(cfg.CONF.ignore_tenants))

        conn = pecan.request.db_conn
        orders_db, total_count = conn.get_orders(request.context,
                                                 type=type,
                                                 status=status,
                                                 start_time=start_time,
                                                 end_time=end_time,
                                                 owed=owed,
                                                 limit=limit,
                                                 offset=offset,
                                                 with_count=True,
                                                 resource_id=resource_id,
                                                 bill_methods=bill_methods,
                                                 region_id=region_id,
                                                 user_id=user_id,
                                                 project_ids=project_ids)
        orders = []
        for order in orders_db:
            price = self._get_order_price(order,
                                          start_time=start_time,
                                          end_time=end_time)
            order.total_price = gringutils._quantize_decimal(price)
            orders.append(models.Order.from_db_model(order))

        return models.Orders.transform(total_count=total_count, orders=orders)
Esempio n. 22
0
    def get_all(self,
                user_id=None,
                owed=None,
                limit=None,
                offset=None,
                sort_key='created_at',
                sort_dir='desc'):
        check_policy(request.context, "account:all")

        if limit and limit < 0:
            raise exception.InvalidParameterValue(err="Invalid limit")
        if offset and offset < 0:
            raise exception.InvalidParameterValue(err="Invalid offset")

        self.conn = pecan.request.db_conn

        try:
            accounts = self.conn.get_accounts(request.context,
                                              user_id=user_id,
                                              owed=owed,
                                              limit=limit,
                                              offset=offset,
                                              sort_key=sort_key,
                                              sort_dir=sort_dir)
            count = self.conn.get_accounts_count(request.context,
                                                 owed=owed,
                                                 user_id=user_id)
            pecan.response.headers['X-Total-Count'] = str(count)
        except exception.NotAuthorized as e:
            LOG.exception('Failed to get all accounts')
            raise exception.NotAuthorized()
        except Exception as e:
            LOG.exception('Failed to get all accounts')
            raise exception.DBError(reason=e)

        results = []
        user_ids = []
        for account in accounts:
            user_ids.append(account.user_id)
            if account.sales_id:
                user_ids.append(account.sales_id)

            if cfg.CONF.external_billing.enable:
                try:
                    external_balance = \
                        self.external_client.get_external_balance(
                            account.user_id)['data'][0]['money']
                    external_balance = \
                        gringutils._quantize_decimal(
                            external_balance)
                    account.balance = external_balance
                except exception.GetExternalBalanceFailed:
                    msg = _('Fail to get %s\'s external balance' %
                            (account.user_id))
                    LOG.warn(msg)

            price_per_day, remaining_day = \
                self._estimate_per_day(account.user_id,
                                       account.balance)

            result = models.AdminAccountInDetail(
                user=None,
                user_id=account.user_id,
                salesperson=None,
                sales_id=account.sales_id,
                balance=account.balance,
                consumption=account.consumption,
                level=account.level,
                project_id=account.project_id,
                domain_id=account.domain_id,
                owed=owed,
                inviter=account.inviter,
                created_at=account.created_at,
                price_per_day=price_per_day,
                remaining_day=remaining_day)
            results.append(result)

        users = keystone.get_users_by_user_ids(user_ids)
        for result in results:
            user = users.get(result.user_id)
            salesperson = users.get(result.sales_id)
            if user:
                result.user = models.UserInDetail(**user)
            if salesperson:
                result.salesperson = models.UserInDetail(**salesperson)

        return models.AdminAccountsInDetail(total_count=count,
                                            accounts=results)