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)
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]
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)
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)
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)
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)
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)
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 = {}
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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
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
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)
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)