def test_publish(self): Tariff.create_tariff(self.localized_name("tariff_for_balance"), "tariff!!!", "rub", None) customer_id = Customer.new_customer( "*****@*****.**", "123qwe", self.admin_user.user_id).customer_id db.session.commit() customer = Customer.get_by_id(customer_id) news_id = self.admin_client.news.create(**self.test_news)['news_id'] # check publish news = self.admin_client.news.publish(news_id, publish=True) self.assertTrue(news['published']) self.assertEqual(outbox[0].to, [customer.email]) self.assertIn(self.test_news['subject'], outbox[0].subject) news_id = self.admin_client.news.create(subject='$test_subject', body='test_body')['news_id'] self.admin_client.news.publish(news_id, publish=True) self.assertEqual(len(outbox), 1) # check unpublish news = self.admin_client.news.publish(news_id, publish=False) self.assertFalse(news['published']) self.assertEqual(len(outbox), 1) # check publish deleted news self.admin_client.news.delete(news_id) with self.expect_error(errors.RemovedNews): self.admin_client.news.publish(news_id, publish=True)
def task_os_create_tenant_and_user(customer_id, email): # email is just for logs customer = Customer.get_by_id(customer_id) log.debug("task_os_create_tenant_and_user: {}", customer) if not customer: log.warning("Can't find customer {} {}. Possible customer was removed by system test", customer_id, email) return info = openstack.create_tenant_and_user(email, customer_id, customer.tariff.flavors(), password=customer.os_user_password, enabled=True) log.debug("Openstack info: {}", info) # Tests can delete customer already here, therefore no updates are required if not conf.test: db.session.commit() db.session.close() customer = Customer.get_by_id(customer_id) if customer: customer.update_os_credentials(info['tenant_id'], info['tenant_name'], info['user_id'], info["username"], info['password']) send_email_os_credentials(info['email'], info['name'], info['password'], info['tenant_id'], language=customer.locale_language()) db.session.commit() else: final_delete_from_os(info['tenant_id'], info['user_id'])
def task_os_create_tenant_and_user(customer_id, email): # email is just for logs customer = Customer.get_by_id(customer_id) log.debug("task_os_create_tenant_and_user: {}", customer) if not customer: log.warning( "Can't find customer {} {}. Possible customer was removed by system test", customer_id, email) return info = openstack.create_tenant_and_user(email, customer_id, customer.tariff.flavors(), password=customer.os_user_password, enabled=True) log.debug("Openstack info: {}", info) # Tests can delete customer already here, therefore no updates are required if not conf.test: db.session.commit() db.session.close() customer = Customer.get_by_id(customer_id) if customer: customer.update_os_credentials(info['tenant_id'], info['tenant_name'], info['user_id'], info["username"], info['password']) send_email_os_credentials(info['email'], info['name'], info['password'], info['tenant_id'], language=customer.locale_language()) db.session.commit() else: final_delete_from_os(info['tenant_id'], info['user_id'])
def delete_product(cust_id, wishlist_id, pid): # """ delete product ID to a wishlist """ """ Delete a product from a Wishlist This endpoint will delete a product from a wishlist based on the customer ID, Wishlist ID, an product ID specified in the path --- tags: - Wishlists parameters: - name: cust_id in: path description: ID of customer who wants to delete a product from his/her wishlist required: true type: integer - name: wishlist_id in: path description: ID of wishlist to be updated required: true type: integer - name: pid in: path description: ID of product to be deleted required: true type: integer responses: 200: description: Product deleted from a wishlist schema: id: Wishlist properties: Customer ID: type: integer description: ID of customer Wishlist: type: object properties: wishlist name: type: string description: the Wishlists's name Product list: type: array items: type: string description: the list of products in a Wishlist 404: description: Not Found (either customer ID or wishlist ID is not valid, no record found) """ # TODO add products changes as well, for now just asses the wishlists if Customer.check_custid(cust_id): message = Customer.find_by_id(cust_id, wishlist_id) if message: result = Customer.deleteProduct(cust_id, wishlist_id, pid) res = Customer.find_by_id(cust_id, wishlist_id) return make_response(jsonify(res), status.HTTP_200_OK) else: message = {'Error': 'Wishlist with given ID not found'} return make_response(jsonify(message), status.HTTP_404_NOT_FOUND) else: message = {'Invalid': 'Invalid customer ID'} return make_response(jsonify(message), status.HTTP_404_NOT_FOUND)
def test_report_unknown_service(self): prepay_entity_customer = {"customer_type": "entity", "detailed_info": { "name": "test prepay entity customer", "contract_number": "2015/4568", "contract_date": "2015-01-01", "organization_type": "OOO", "name": "Some Company", "full_organization_name": "OOO Some Company", "primary_state_registration_number": "159 8525 15552", "individual_tax_number": "52 59 5555555", "legal_address_country": "RU", "legal_address_city": "NN", "legal_address_address": "Ошарская, 13", "location_country": "RU", "location_city": "NN", "location_address": "Ошарская", "general_manager_name": "Васильев Е.В", "general_accountant_name": "Иванова В.Н", "contact_person_name": "Петров Василий" }} self.create_tariff("First Tariff", default=True) customer_info = self.create_customer("*****@*****.**", **prepay_entity_customer) customer_id = customer_info["customer_id"] customer = Customer.get_by_id(customer_id) tenant = Tenant.create(uuid.uuid4().hex, "test tenant") tenant_id = tenant.tenant_id customer.confirm_email() # clear db session customer.os_tenant_id = tenant_id db.session.commit() start = datetime(2015, 4, 1) end = datetime(2015, 4, 1, 10) - timedelta(seconds=1) customer = Customer.get_by_id(customer_id) Customer.fake_usage(customer, start, end, "service_unknown", "unknown resource", 1) db.session.commit() report = self.get_customer_report(customer_id, start, end, "pdf", filename="unknown_service.pdf") self.assertTrue(report) report = self.get_customer_report(customer_id, start, end, "pdf", filename="unknown_service_detailed.pdf", report_type="detailed") self.assertTrue(report)
def test_publish(self): Tariff.create_tariff(self.localized_name("tariff_for_balance"), "tariff!!!", "rub", None) customer_id = Customer.new_customer("*****@*****.**", "123qwe", self.admin_user.user_id).customer_id db.session.commit() customer = Customer.get_by_id(customer_id) news_id = self.admin_client.news.create(**self.test_news)['news_id'] # check publish news = self.admin_client.news.publish(news_id, publish=True) self.assertTrue(news['published']) self.assertEqual(outbox[0].to, [customer.email]) self.assertIn(self.test_news['subject'], outbox[0].subject) news_id = self.admin_client.news.create(subject='$test_subject', body='test_body')['news_id'] self.admin_client.news.publish(news_id, publish=True) self.assertEqual(len(outbox), 1) # check unpublish news = self.admin_client.news.publish(news_id, publish=False) self.assertFalse(news['published']) self.assertEqual(len(outbox), 1) # check publish deleted news self.admin_client.news.delete(news_id) with self.expect_error(errors.RemovedNews): self.admin_client.news.publish(news_id, publish=True)
def setUp(self): self._frame = CarbonFrame(10, 100) self._frontWheel = RoadWheel("Front RoadWheel", 10, 100) self._backWheel1 = MountainWheel("Back MountainWheel", 10, 100) self._backWheel2 = RoadWheel("Back RoadWheel", 10, 100) self._bike = BicycleModel("Good Build", self._frontWheel, self._backWheel2, self._frame) self._customer = Customer('Customer', 10000)
def new_cusotmer(email, password, address, phone, name, data): existing_user = Customer.query.filter_by(email=email).first() if existing_user: return "Email already exist" customer = Customer(email, password, address, phone, name) customer.fb_link = data.get('fb_link') db.session.add(customer) db.session.commit()
def test_report_unknown_service(self): prepay_entity_customer = { "customer_type": "entity", "detailed_info": { "name": "test prepay entity customer", "contract_number": "2015/4568", "contract_date": "2015-01-01", "organization_type": "OOO", "name": "Some Company", "full_organization_name": "OOO Some Company", "primary_state_registration_number": "159 8525 15552", "individual_tax_number": "52 59 5555555", "legal_address_country": "RU", "legal_address_city": "NN", "legal_address_address": "Ошарская, 13", "location_country": "RU", "location_city": "NN", "location_address": "Ошарская", "general_manager_name": "Васильев Е.В", "general_accountant_name": "Иванова В.Н", "contact_person_name": "Петров Василий" } } self.create_tariff("First Tariff", default=True) customer_info = self.create_customer("*****@*****.**", **prepay_entity_customer) customer_id = customer_info["customer_id"] customer = Customer.get_by_id(customer_id) tenant = Tenant.create(uuid.uuid4().hex, "test tenant") tenant_id = tenant.tenant_id customer.confirm_email() # clear db session customer.os_tenant_id = tenant_id db.session.commit() start = datetime(2015, 4, 1) end = datetime(2015, 4, 1, 10) - timedelta(seconds=1) customer = Customer.get_by_id(customer_id) Customer.fake_usage(customer, start, end, "service_unknown", "unknown resource", 1) db.session.commit() report = self.get_customer_report(customer_id, start, end, "pdf", filename="unknown_service.pdf") self.assertTrue(report) report = self.get_customer_report( customer_id, start, end, "pdf", filename="unknown_service_detailed.pdf", report_type="detailed") self.assertTrue(report)
def update_quota(customer_id, user_id, quotas): from model import Customer, CustomerHistory customer = Customer.get_by_id(customer_id) if not customer: logbook.warning("Customer id '{}' not found for quota update", customer_id) return customer = Customer.get_by_id(customer_id) openstack.change_tenant_quotas(customer.os_tenant_id, **quotas) CustomerHistory.quota_changed(customer, user_id, None)
def clear_wishlist(cust_id, wishlist_id): # """ Clear the contents of the wishlist with the given id""" """ Clear all products of a Wishlist This endpoint will clear all products of a Wishlist based on the customer id and Wishlist id specified in the path --- tags: - Wishlists parameters: - name: cust_id in: path description: ID of customer who wants to view his/her wishlist required: true type: integer - name: wishlist_id in: path description: ID of wishlist to be retrieved required: true type: integer responses: 200: description: Wishlist cleared schema: id: Wishlist properties: Customer ID: type: integer description: ID of customer Wishlist: type: object properties: wishlist name: type: string description: the Wishlists's name Product list: type: array items: type: string description: the list of products in a Wishlist 404: description: Not Found (either customer ID or wishlist ID is not valid, no record found) """ if Customer.check_custid(cust_id): message = Customer.find_by_id(cust_id, wishlist_id) if message: res = Customer.clear_list(cust_id, wishlist_id) return make_response(jsonify(message), status.HTTP_200_OK) else: message = {'Error': 'Wishlist with the given ID not found'} return make_response(jsonify(message), status.HTTP_404_NOT_FOUND) else: message = {'Invalid': 'Invalid customer ID'} return make_response(jsonify(message), status.HTTP_404_NOT_FOUND)
class CustomerTest(unittest.TestCase): def setUp(self): self._frame = CarbonFrame(10, 100) self._frontWheel = RoadWheel("Front RoadWheel", 10, 100) self._backWheel1 = MountainWheel("Back MountainWheel", 10, 100) self._backWheel2 = RoadWheel("Back RoadWheel", 10, 100) self._bike = BicycleModel("Good Build", self._frontWheel, self._backWheel2, self._frame) self._customer = Customer('Customer', 10000) def test_buy_bike(self): self._customer.buy_bike(self._bike) self.assertNotEqual(None, self._customer.get_bike()) self.assertEqual(self._customer.get_funds(), 9970)
class CustomerPersistence: customers = [ Customer(555555, 'nif', '11223344E', '*****@*****.**', 'Enriqueta', 'Parlem', '668668668'), Customer(555556, 'nif', '44332211F', '*****@*****.**', 'David', 'David Enterprise', '667667667') ] def get_all_customers(self): return self.customers def get_customer_by_id(self, id): for customer in self.customers: if customer._id == id: return customer
def delete_wishlist(cust_id, wishlist_id): # """ Delete the wishlist with the provided id""" """ Delete a Wishlist This endpoint will delete a Wishlist based on the customer id and Wishlist id specified in the path --- tags: - Wishlists description: Deletes a wishlist from the database parameters: - name: cust_id in: path description: ID of customer who wants to delete his/her wishlist required: true type: integer - name: wishlist_id in: path description: ID of wishlist to be deleted required: true type: integer responses: 204: description: Wishlist deleted """ success = Customer.delete_by_id(cust_id, wishlist_id) return make_response('', status.HTTP_204_NO_CONTENT)
def test_collector_sequence(self): start_time = datetime.datetime(2015, 3, 20, 9, 12) end_time = datetime.datetime(2015, 3, 21) project = Tenant("boss", start_time) disk = Disk(project, "test_disk", start_time, 1234567890) hour_price = Decimal(self.image_size_price)*2 t = start_time count = 0 while t < end_time: disk.repeat_message(t, t + datetime.timedelta(hours=1)) with mock.patch("os_interfaces.openstack_wrapper.openstack") as openstack: openstack.get_tenant_usage = project.usage project.prepare_messages() tenants_usage = self.collector.run_usage_collection(t + datetime.timedelta(hours=1, minutes=10)) self.assertTrue(tenants_usage[project.project_id]) t += datetime.timedelta(hours=1) count += 1 account = Customer.get_by_id(project.customer_id).account_dict()["RUB"] hours = int((end_time - start_time).total_seconds() // 3600) + 1 total_cost = hours * hour_price self.assertLess(abs(account["withdraw"] - total_cost), 0.0001)
def clean_up_customer_service_usage(self, customer_id, end_date): from model import Customer customer = Customer.get_by_id(customer_id) if not customer: logbook.warning("Customer id '{}' not found for cleaning up services usage", customer_id) return customer.clean_up_service_usage(end_date)
def get_used_quotas(customer_id): from model import Customer customer = Customer.get_by_id(customer_id) if not customer: logbook.warning("Customer id '{}' not found for getting used quotas", customer_id) return customer.get_used_quotas()
def aggregate(self, report_id): logbook.info("Get customer usage aggregation for {}", report_id) customer = Customer.get_by_id(report_id.customer_id) if not customer: raise Exception("Customer %s not found" % report_id.customer_id) with timed("get_usage simple"): aggregated_usage = ServiceUsage.get_usage(customer, report_id.start, report_id.end) tariffs = {} services = set() for usage in aggregated_usage: service_id, tariff_id, cost, usage_volume = usage services.add(service_id) if not tariff_id: logbook.error("ServiceUsage {} is not completed. Tariff is not filled", usage) continue tariff = Tariff.get_by_id(tariff_id) tariff_report = tariffs.get(tariff_id) if tariff_report is None: tariff_report = self.tariff_report_type(tariff, customer) tariffs[tariff_id] = tariff_report tariff_report.add_usage(usage) total = Counter() for tariff_id, tariff in tariffs.items(): total_tariff, currency = tariff.aggregate() total[currency] += total_tariff for t, value in total.items(): total[t] = decimal_to_string(value) logbook.info("Aggregated {} for {}. Services: {}", total, customer, services) return self.prepare_result(list(tariffs.values()), total, customer, report_id.start, report_id.end)
def customers(): ''' 'GET': show customers table. 'POST': save a new customer or add a car to existing customer. ''' if request.method == 'POST': fullname = (request.form['fullname']).split() last_name = fullname[0] first_name = fullname[1] if len(fullname) == 3: middle_name = fullname[2] else: middle_name = '' phone_number = request.form['phone_number'] car_brand = request.form['car_brand'] car_number = request.form['car_number'] new_customer = Customer( last_name=last_name, first_name=first_name, middle_name=middle_name, phone_number=phone_number, ) new_car = Car( brand=car_brand, number=car_number, customer=new_customer, ) db_session.add(new_customer) db_session.add(new_car) db_session.commit() return redirect(url_for('customers')) else: customers = db_session.query(Customer).all() return render_template('customers.html', customers=customers)
def make_action(cls, state, now=None): from model import Customer logbook.info("Try apply action: {}", state) now = now or utcnow().datetime machine = cls.machines[state.name] customer = Customer.get_by_id(state.customer_id) try: new_state_name = getattr(machine, state.action)(customer) except Exception as e: logbook.error("action {} failed: {}", state, e) state.remove() db.session.commit() raise state.step += 1 if not new_state_name: if state.step >= len(machine.schedule): logbook.info("Actions {} are completed for {}", cls.name, customer) state.remove() db.session.commit() return new_state = machine.schedule[state.step] else: new_state = find_first(machine.schedule, lambda x: x[0] == new_state_name) if not new_state: state.remove() db.session.commit() raise Exception("Can't find new state %s for machine %s" % (new_state_name, cls.name)) state.action = new_state[0] state.scheduled_at = now + timedelta(seconds=new_state[1]) logbook.info("New action {} is scheduled", state)
class CustomerTest(unittest.TestCase): def setUp(self): self._frame = CarbonFrame(10, 100) self._frontWheel = RoadWheel("Front RoadWheel", 10, 100) self._backWheel1 = MountainWheel("Back MountainWheel", 10, 100) self._backWheel2 = RoadWheel("Back RoadWheel", 10, 100) self._bike = BicycleModel( "Good Build", self._frontWheel, self._backWheel2, self._frame ) self._customer = Customer('Customer', 10000) def test_buy_bike(self): self._customer.buy_bike(self._bike) self.assertNotEqual(None, self._customer.get_bike()) self.assertEqual(self._customer.get_funds(), 9970)
def process_registration(): """Process user registration""" first_name = request.form.get("first_name") last_name = request.form.get("last_name") email = request.form.get("email") password = request.form.get("password") password = pbkdf2_sha256.encrypt(password, rounds=20000, salt_size=16) street_address = request.form.get("address") zipcode = request.form.get("zipcode") state = request.form.get("state") phone = request.form.get("phone") user = Customer(first_name=first_name, last_name=last_name, email=email, password_hash=password, street_address=street_address, zipcode=zipcode, state=state, phone=phone) db.session.add(user) db.session.commit() session['email'] = email if session.get('email'): flash("Registration successful! Welcome to Farm to Front Door.") else: flash("Please enable cookies to log in") return redirect("/products")
def test_receipts_report(self): self.create_tariff("default_tariff", default=True) customer_info = self.create_customer_by_self( "*****@*****.**") db.session.commit() customer_id = customer_info["customer_id"] self.admin_client.customer.update_balance( customer_id, "100", "test withdraw for test mode", "RUB") self.admin_client.customer.update(customer_id, detailed_info={ "passport_series_number": "1234 567 890", "passport_issued_by": "UFMS Russia", "passport_issued_date": "2013-01-01" }) customer_db = Customer.get_by_id(customer_id) customer_db.confirm_email() self.admin_client.customer.make_prod(customer_id) self.admin_client.customer.update_balance( customer_id, "100", "test withdraw for prod mode", "RUB") start = utcnow().datetime - timedelta(days=30) end = utcnow().datetime + timedelta(hours=1) report = self.get_report("receipts", start, end, "csv") self.assertTrue(report) self.assertGreater(report.count(b";"), 5) report = [row for row in report.split(b"\r\n") if row] self.assertEqual(len(report), 2) # header + balance update after prod self.get_report("receipts", start, end, "tsv")
def customers_stats(self): """ Returns customer statistics. **Example**:: { "customer_stats": { "pending_prod_private": 0, "production": 2, "pending_prod_private_blocked": 0, "pending_prod": 0, "total": 5, "private_deleted": 1, "production_private_blocked": 0, "entity_deleted": 0, "total_test": 3, "pending_prod_entity_blocked": 0, "production_private": 2, "test_private_blocked": 1, "production_entity_blocked": 0, "test_entity_blocked": 0, "production_entity": 0, "test_private": 2, "test_entity": 1, "pending_prod_entity": 0, "total_blocked": 1, "total_deleted": 1 } } """ return {"customer_stats": Customer.customers_stat()}
def test_collector_sequence(self): start_time = datetime.datetime(2015, 3, 20, 9, 12) end_time = datetime.datetime(2015, 3, 21) project = Tenant("boss", start_time) disk = Disk(project, "test_disk", start_time, 1234567890) hour_price = Decimal(self.image_size_price) * 2 t = start_time count = 0 while t < end_time: disk.repeat_message(t, t + datetime.timedelta(hours=1)) with mock.patch( "os_interfaces.openstack_wrapper.openstack") as openstack: openstack.get_tenant_usage = project.usage project.prepare_messages() tenants_usage = self.collector.run_usage_collection( t + datetime.timedelta(hours=1, minutes=10)) self.assertTrue(tenants_usage[project.project_id]) t += datetime.timedelta(hours=1) count += 1 account = Customer.get_by_id(project.customer_id).account_dict()["RUB"] hours = int((end_time - start_time).total_seconds() // 3600) + 1 total_cost = hours * hour_price self.assertLess(abs(account["withdraw"] - total_cost), 0.0001)
def aggregate(self, report_id): logbook.info("Get detailed customer usage aggregation for {}", report_id) customer = Customer.get_by_id(report_id.customer_id) if not customer: raise Exception("Customer %s not found" % report_id.customer_id) with timed("get_usage simple"): aggregated_usage = ServiceUsage.get_detailed_usage( customer, report_id.start, report_id.end) tariffs = {} services = set() for usage in aggregated_usage: tariff = Tariff.get_by_id(usage.tariff_id) tariff_report = tariffs.get(usage.tariff_id) if tariff_report is None: tariff_report = self.tariff_report_type(tariff, customer) tariffs[usage.tariff_id] = tariff_report tariff_report.add_usage(usage) total = Counter() for tariff_id, tariff in tariffs.items(): total_tariff, currency = tariff.aggregate() total[currency] += total_tariff for t, value in total.items(): total[t] = decimal_to_string(value) logbook.info("Aggregated {} for {}. Services: {}", total, customer, services) return self.prepare_result(list(tariffs.values()), total, customer, report_id.start, report_id.end)
def stat(self): result = Counter() flavors = openstack.get_nova_flavors() id2flavor = {flavor.id: flavor for flavor in flavors} for tenant_id in Customer.active_tenants(): servers = openstack.get_nova_servers(tenant_id=tenant_id) for server in servers: if not server.status == 'ACTIVE': continue server_flavor_id = server.flavor['id'] server_flavor = id2flavor.get(server_flavor_id) if server_flavor: server_flavor_name = server_flavor.name result['flavor.%s.vcpus' % server_flavor_name] += server_flavor.vcpus result['flavor.%s.ram' % server_flavor_name] += server_flavor.ram else: logbook.error("Server {} in tenant {} has unknown flavor: {}", server, tenant_id, server.flavor) # Check total resource usage for each tenant limits = openstack.get_nova_limits(tenant_id=tenant_id) for k, v in limits.items(): if v > 0 and k in ['totalCoresUsed', 'totalRAMUsed']: result[k] += v return result
def test_receipts_report(self): self.create_tariff("default_tariff", default=True) customer_info = self.create_customer_by_self("*****@*****.**") db.session.commit() customer_id = customer_info["customer_id"] self.admin_client.customer.update_balance(customer_id, "100", "test withdraw for test mode", "RUB") self.admin_client.customer.update(customer_id, detailed_info={"passport_series_number": "1234 567 890", "passport_issued_by": "UFMS Russia", "passport_issued_date": "2013-01-01"}) customer_db = Customer.get_by_id(customer_id) customer_db.confirm_email() self.admin_client.customer.make_prod(customer_id) self.admin_client.customer.update_balance(customer_id, "100", "test withdraw for prod mode", "RUB") start = utcnow().datetime - timedelta(days=30) end = utcnow().datetime + timedelta(hours=1) report = self.get_report("receipts", start, end, "csv") self.assertTrue(report) self.assertGreater(report.count(b";"), 5) report = [row for row in report.split(b"\r\n") if row] self.assertEqual(len(report), 2) # header + balance update after prod self.get_report("receipts", start, end, "tsv")
def notify_managers_about_new_service_in_tariff(self, customer_id, flavor_name): customer = Customer.get_by_id(customer_id) if not customer: logbook.error("Customer {} not found in notify manager", customer_id) return logbook.info("notify manager about adding new service to tariff {}", customer.tariff.name) from api.admin.user import UserApi service_edit_url = urljoin( request_base_url(), posixpath.join(UserApi.ADMIN_FRONTEND_PATH, "tariffs", str(customer.tariff.tariff_id), "services")) customer_url = urljoin( request_base_url(), posixpath.join(UserApi.ADMIN_FRONTEND_PATH, "index", str(customer.customer_id), "info")) subject, body = MessageTemplate.get_rendered_message( MessageTemplate.NEW_SERVICE_IN_TARIFF, language=preferred_language(), account=customer.email, flavor_name=flavor_name, tariff=customer.tariff.name, customer_url=customer_url, service_edit_url=service_edit_url) logbook.info("Sending email notification to delete data of {}", customer.email) send_email.delay(get_customers_manager(customer), subject, body)
def add_customer(cname, cphno, cemail, caddress): customer = Customer(customer_name=cname, customer_phno=cphno, customer_email=cemail, customer_address=caddress) session.add(customer) session.commit()
def payment_check(self, *args, **request_data): """Checks payment availability for customer Parameters must be sent as json object. :param Int TransactionId: Mandatory - System transaction number. :param Numeric Amount: Mandatory - Payment amount from widget. Dot as separator, two digits after dot. :param String Currency: Mandatory - Currency: RUB/USD/EUR/GBP from widget parameters. :param String InvoiceId: Not mandatory - Order number from widget parameters. :param String AccountId: Mandatory - Customer identifier from widget parameters. :param String SubscriptionId: Not mandatory - Subscription identifier from widget parameters (for recurrent payments). :param String Name: Not mandatory - Card holder name. :param String Email: Payer's e-mail :param DateTime: Mandatory - Payment creation date/time in UTC (yyyy-MM-dd HH:mm:ss). :param String IpAddress: Not mandatory - Payer IP-address :param String IpCountry: Not mandatory - Payer's country double-chars code (according to ISO3166-1) :param String IpCity: Not mandatory - Payer's city :param String IpRegion: Not mandatory - Payer's region. :param String IpDistrict: Not mandatory - Payer's district. :param String CardFirstSix: Mandatory - Credit card first 6 digits :param String CardLastFour: Mandatory - Credit card last 6 digits :param String CardType: Mandatory - Card payment system: Visa or MasterCard or Maestro :param String CardExpDate: Mandatory - Card expiration date MM/YY :param String Issuer: Not mandatory - Issuer bank name :param String IssuerBankCountry: Not mandatory - Issuer bank country double-char code (according to ISO3166-1) :param String Description: Not mandatory - Payment description from widget parameters. :param Json Data: Not mandatory - Any json-data from widget. :param Bit TestMode: Mandatory - Test mode flag (1 or 0) :param String Status: Mandatory - Payment status: Completed — for single-step, Authorized — for double-step. :return: Status code, looks like {'code': 0} """ logbook.info("[payment_check] Request info:{}", request_data) short_payment_info = dict([(key, request_data.get(key)) for key in PaymentsApi.payment_info_fields]) # Common validation validation_res, validation_info = self.validate_request(request_data, short_payment_info) if not validation_res: log_error("[payment_check] {} Payment info: {}", validation_info, short_payment_info) return {'code': self.ERROR_COMMON} # Currency validation currency = request_data['Currency'] if not currency or currency not in conf.currency.active: log_error("[payment_check] Invalid or incompatible currency: {}. Payment info: {}", currency, short_payment_info) return {'code': self.ERROR_COMMON} # Customer validation customer_id = request_data['AccountId'] customer = Customer.get_by_id(customer_id, False) if not customer: log_error("[payment_check] Customer {} not found. Payment info: {}", customer_id, short_payment_info) return {'code': self.ERROR_COMMON} if customer.is_test_mode(): # Payments in test mode is not allowed logbook.warning("[payment_check] Customer {} in test mode. Payment info {}", customer, short_payment_info) return {'code': self.ERROR_COMMON} return {'code': self.ERROR_OK}
def create_customer(): f_name = input("First Name: ") l_name = input("Last Name: ") email = input("Email: ") customer = Customer(f_name=f_name, l_name=l_name, email=email) session.add(customer) session.commit() print('created!\n')
def create_customer(cname, cphno, caddress): customer = Customer(customer_name=cname, customer_phno=cphno, customer_address=caddress) session.add(customer) session.commit
def load_customers(): """Load customer from faker into database.""" email_company = ['@gmail.com', '@hotmail.com'] for i in range(0, 43): first_name = fake.first_name_male() last_name = fake.last_name() email = first_name + last_name + random.choice(email_company) customer = Customer(first_name=first_name, last_name=last_name, gender_code='M', phone_number=str(fake.phone_number()), email=email, birth_date=fake.date(pattern="%Y %m %d"), address=fake.street_address(), city=fake.city(), state='CA', zipcode=int(fake.zipcode()), user_id=1) db.session.add(customer) for i in range(0, 57): first_name = fake.first_name_male() last_name = fake.last_name() email = first_name + last_name + random.choice(email_company) customer = Customer(first_name=first_name, last_name=last_name, gender_code='FM', phone_number=str(fake.phone_number()), email=email, birth_date=fake.date(pattern="%Y %m %d"), address=fake.street_address(), city=fake.city(), state='CA', zipcode=int(fake.zipcode()), user_id=1) db.session.add(customer) db.session.commit()
def clean_up_customer_service_usage(self, customer_id, end_date): from model import Customer customer = Customer.get_by_id(customer_id) if not customer: logbook.warning( "Customer id '{}' not found for cleaning up services usage", customer_id) return customer.clean_up_service_usage(end_date)
def setUp(self): self._frame = CarbonFrame(10, 100) self._frontWheel = RoadWheel("Front RoadWheel", 10, 100) self._backWheel1 = MountainWheel("Back MountainWheel", 10, 100) self._backWheel2 = RoadWheel("Back RoadWheel", 10, 100) self._bike = BicycleModel( "Good Build", self._frontWheel, self._backWheel2, self._frame ) self._customer = Customer('Customer', 10000)
def send_email_with_news(subject, body): if subject.startswith(conf.devel.test_prefix): return customers = Customer.news_subscribers() subject, body = MessageTemplate.get_rendered_message(MessageTemplate.NEWS, language=preferred_language(), news_subject=subject, news_body=body) for customer in customers: send_email.delay(customer.subscription_info()['news']['email'], subject, body)
def test(self): bravit = self.table.create_customer( Customer(name="Виталий Брагилевский")) cid = bravit.id customer = self.table.find_customer(cid) self.assertEqual(bravit, customer) self.table.delete_customer(cid) customer = self.table.find_customer(cid) self.assertEqual(None, customer)
def customer_create(): form = CustomerForm(request.form) if form.validate_on_submit(): customer = Customer(phone=form.phone.data, email=form.email.data, name=form.name.data) return redirect('/') return render_template('customer/create.html', form=form)
def test_usage_report(self): self.create_tariff("default_tariff", default=True) customer_info = self.create_customer_by_self("*****@*****.**") customer = Customer.get_by_id(customer_info["customer_id"]) tenant = Tenant.create(uuid.uuid4().hex, "test tenant") customer.os_tenant_id = tenant.tenant_id db.session.commit() start = datetime(2015, 4, 1) end = datetime(2015, 4, 25) end_report = end + timedelta(hours=24) cost1 = Decimal(0) cost1 += Customer.fake_usage(customer, start, end, self.service_nano_id, uuid.uuid4().hex, 1) cost1 += Customer.fake_usage(customer, start + timedelta(days=5), end, self.service_micro_id, uuid.uuid4().hex, 1) cost1 += Customer.fake_usage(customer, start + timedelta(days=6), end, self.service_nano_id, uuid.uuid4().hex, 1) cost1 += Customer.fake_usage(customer, start, end, "storage.image", uuid.uuid4().hex, 60 * conf.GIGA) customer2_info = self.create_customer("*****@*****.**") tenant2 = Tenant.create(uuid.uuid4().hex, "test tenant 2") customer2 = Customer.get_by_id(customer2_info["customer_id"]) customer2.os_tenant_id = tenant2.tenant_id cost2 = Customer.fake_usage(customer2, start, end, self.service_nano_id, uuid.uuid4().hex, 1) db.session.commit() report = self.get_report("usage", start, end_report, "csv", locale="en_us") self.assertTrue(report) report = [row.decode("ascii") for row in report.split(b"\r\n") if row] parsed_report = csv.reader(report) cust_1 = [ row for row in parsed_report if row[0] == '*****@*****.**' ] cust_1_cost = sum(Decimal(row[1]) for row in cust_1) parsed_report = csv.reader(report) cust_2 = [ row for row in parsed_report if row[0] == '*****@*****.**' ] cust_2_cost = sum(Decimal(row[1]) for row in cust_2) self.assertEqual(len(cust_2), 1) self.assertEqual(len(cust_1), 1) self.assertEqual(cust_1_cost, cost1) self.assertEqual(cust_2_cost, cost2)
def notify_managers_about_hdd(self, customer_id): customer = Customer.get_by_id(customer_id) if not customer: logbook.error("Customer {} not found in notify manager", customer_id) return logbook.info("notify manager about hdd for removing for customer {}", customer) from model.account.customer_history import CustomerHistory block_event = CustomerHistory.get_last_block_event(customer) send_email_hdd_notification(get_customers_manager(customer), block_event.date, customer.email)
def auto_report(time_now=None, email_prefix=None): from model import Customer if time_now is None: time_now = utcnow().datetime tasks = Customer.auto_withdraw_query(email_prefix, now=time_now).all() logbook.info("Found {} task for auto report", len(tasks)) for task in tasks: customer_auto_report.delay(task.customer_id, time_now) return len(tasks)
def reset_user_password(customer_id): customer = Customer.get_by_id(customer_id) if not customer: log.warning("Can't find customer for reset user password {} {}. Possible customer was removed by system test", customer_id) return password = openstack.reset_user_password(customer.os_user_id) customer.update_os_password(password) send_email_os_credentials(customer.email, customer.os_username, password, customer.os_tenant_id, language=customer.locale_language())
def main(): import docopt from model import Customer opt = docopt.docopt(__doc__) tenant_id = opt["--tenant"] customer_id = opt["--customer"] if customer_id: try: customer_id = int(customer_id) customer = Customer.get_by_id(customer_id) except ValueError: customer = Customer.get_by_email(customer_id) if not customer: logbook.warning("Customer {} not found", customer_id) return else: tenant_id = customer.tenant.tenant_id start = opt["--start"] end = opt["--end"] now = arrow.utcnow().date() start = arrow.get(start) if start else now - timedelta(minutes=15) end = arrow.get(end) if end else now metric = opt["--metric"] service = opt["--service"] if service: service_mapping = {data["service"]: name for name, data in conf.fitter.collection.meter_mappings.items()} if service not in service_mapping: logbook.warning("Service {} not found", service) return metric = service_mapping[service] samples = openstack.get_tenant_usage(tenant_id, metric, start, end, limit=int(opt["--limit"])) logbook.info("Found {} samples", len(samples)) for s in samples: pprint(s._info)
def process_pending_deferred_changes(cls, time_now=None, name_prefix=""): db.session.rollback() logbook.debug("Process pending deferred changes task for customer prefix {} and time {}", name_prefix, time_now) time_now = time_now or utcnow().datetime query = cls.find_deferred(time_now) if name_prefix: customer_ids = [c.customer_id for c in Customer.get_customers_by_prefix_info_field(name_prefix, "name")] query = query.filter(cls.customer_id.in_(customer_ids)) if customer_ids else [] count = 0 for deferred in query: cls.do_deferred_changes(deferred) count += 1 logbook.debug("Processed {} pending deferred changes", count) db.session.commit() return count
def __init__(self, name, start_time): self.project_id = Service.hash(time.time()) self.messages = defaultdict(list) self.name = name self.description = name self.event = None self.timestamps = None self.customer_email = "*****@*****.**" % self.name self.customer_password = self.name + self.name self.customer = Customer.new_customer(self.customer_email, self.customer_password, None) self.customer_id = self.customer.customer_id self.customer.email_confirmed = True self.start_balance = Decimal(100) self.customer.modify_balance(self.start_balance, self.customer.tariff.currency, None, "Initial balance") tenant = TenantDb.create(self.project_id, name, start_time) self.customer.os_tenant_id = tenant.tenant_id db.session.add(tenant) db.session.commit()
def collect_usage(self, tenant, mutex, end=None): # Collects usage for a given tenant from when they were last collected, # up to the given end, and breaks the range into one hour windows. end = end or datetime.utcnow() time_label = TimeLabel(tenant.last_collected + timedelta(minutes=1)) end_time_label = TimeLabel(end) usage = {} logbook.info('collect_usage for {}, from {} till {} (last_collected: {})', tenant, time_label, end_time_label, tenant.last_collected) customer = Customer.get_by_tenant_id(tenant.tenant_id) if not customer: logbook.error("Customer for tenant {} not found", tenant) return usage while time_label < end_time_label: try: usages = self._collect_usage(tenant, time_label, customer) tenant.last_collected = time_label.datetime_range()[1] if usages: db.session.add(customer) total_cost = customer.calculate_usage_cost(usages) customer.withdraw(total_cost) if not conf.test: db.session.commit() usage[time_label] = [usage.to_dict() for usage in usages], total_cost except Exception: self.errors += 1 import traceback traceback.print_exc() logbook.exception("Usage process failed for {} and {}", tenant, time_label) db.session.rollback() return usage time_label = time_label.next() mutex.update_ttl() return usage
def notify_managers_about_new_service_in_tariff(self, customer_id, flavor_name): customer = Customer.get_by_id(customer_id) if not customer: logbook.error("Customer {} not found in notify manager", customer_id) return logbook.info("notify manager about adding new service to tariff {}", customer.tariff.name) from api.admin.user import UserApi service_edit_url = urljoin(request_base_url(), posixpath.join(UserApi.ADMIN_FRONTEND_PATH, "tariffs", str(customer.tariff.tariff_id), "services")) customer_url = urljoin(request_base_url(), posixpath.join(UserApi.ADMIN_FRONTEND_PATH, "index", str(customer.customer_id), "info")) subject, body = MessageTemplate.get_rendered_message(MessageTemplate.NEW_SERVICE_IN_TARIFF, language=preferred_language(), account=customer.email, flavor_name=flavor_name, tariff=customer.tariff.name, customer_url=customer_url, service_edit_url=service_edit_url) logbook.info("Sending email notification to delete data of {}", customer.email) send_email.delay(get_customers_manager(customer), subject, body)
def test_usage_report(self): self.create_tariff("default_tariff", default=True) customer_info = self.create_customer_by_self("*****@*****.**") customer = Customer.get_by_id(customer_info["customer_id"]) tenant = Tenant.create(uuid.uuid4().hex, "test tenant") customer.os_tenant_id = tenant.tenant_id db.session.commit() start = datetime(2015, 4, 1) end = datetime(2015, 4, 25) end_report = end + timedelta(hours=24) cost1 = Decimal(0) cost1 += Customer.fake_usage(customer, start, end, self.service_nano_id, uuid.uuid4().hex, 1) cost1 += Customer.fake_usage(customer, start + timedelta(days=5), end, self.service_micro_id, uuid.uuid4().hex, 1) cost1 += Customer.fake_usage(customer, start + timedelta(days=6), end, self.service_nano_id, uuid.uuid4().hex, 1) cost1 += Customer.fake_usage(customer, start, end, "storage.image", uuid.uuid4().hex, 60*conf.GIGA) customer2_info = self.create_customer("*****@*****.**") tenant2 = Tenant.create(uuid.uuid4().hex, "test tenant 2") customer2 = Customer.get_by_id(customer2_info["customer_id"]) customer2.os_tenant_id = tenant2.tenant_id cost2 = Customer.fake_usage(customer2, start, end, self.service_nano_id, uuid.uuid4().hex, 1) db.session.commit() report = self.get_report("usage", start, end_report, "csv", locale="en_us") self.assertTrue(report) report = [row.decode("ascii") for row in report.split(b"\r\n") if row] parsed_report = csv.reader(report) cust_1 = [row for row in parsed_report if row[0] == '*****@*****.**'] cust_1_cost = sum(Decimal(row[1]) for row in cust_1) parsed_report = csv.reader(report) cust_2 = [row for row in parsed_report if row[0] == '*****@*****.**'] cust_2_cost = sum(Decimal(row[1]) for row in cust_2) self.assertEqual(len(cust_2), 1) self.assertEqual(len(cust_1), 1) self.assertEqual(cust_1_cost, cost1) self.assertEqual(cust_2_cost, cost2)
def test_report_with_two_tariffs(self): prepay_entity_customer = {"customer_type": "entity", "detailed_info": { "name": "test prepay entity customer", "contract_number": "2015/4568", "contract_date": "2015-01-01", "organization_type": "OOO", "name": "Some Company", "full_organization_name": "OOO Some Company", "primary_state_registration_number": "159 8525 15552", "individual_tax_number": "52 59 5555555", "legal_address_country": "RU", "legal_address_city": "NN", "legal_address_address": "Ошарская, 13", "location_country": "RU", "location_city": "NN", "location_address": "Ошарская", "general_manager_name": "Васильев Е.В", "general_accountant_name": "Иванова В.Н", "contact_person_name": "Петров Василий" }} self.create_tariff("First Tariff", default=True) customer_info = self.create_customer("*****@*****.**", **prepay_entity_customer) customer_id = customer_info["customer_id"] customer = Customer.get_by_id(customer_id) tenant = Tenant.create(uuid.uuid4().hex, "test tenant") tenant_id = tenant.tenant_id customer.os_tenant_id = tenant_id db.session.commit() start = datetime(2015, 4, 1) middle_end = datetime(2015, 4, 1, 15) - timedelta(seconds=1) end = datetime(2015, 4, 2) - timedelta(seconds=1) end_second = datetime(2015, 4, 3) - timedelta(seconds=1) end_report = end_second + timedelta(hours=24) vm_nano = uuid.uuid4().hex vm_small = uuid.uuid4().hex vm_nano2 = "nano2" storage_id = "disk1" Customer.fake_usage(customer, start, end, self.service_nano_id, vm_nano, 1, resource_name="nano1") Customer.fake_usage(customer, start, end, self.service_small_id, vm_small, 1, resource_name="my little pony") Customer.fake_usage(customer, start, middle_end , self.service_nano_id, vm_nano2, 1, resource_name="pico") Customer.fake_usage(customer, start, middle_end, "storage.volume", storage_id, 1237852421) Customer.fake_usage(customer, middle_end + timedelta(hours=1), end, "storage.volume", storage_id, 77777777777) Customer.fake_usage(customer, start, end, "net.allocated_ip", "ip_floating_1", 3, resource_name="192.168.1.1") Customer.fake_usage(customer, start, end, "net.allocated_ip", "ip_floating_2", 7) db.session.commit() second_tariff = self.create_tariff("Second Tariff", default=True) self.admin_client.customer.update(customer_id, tariff=second_tariff["tariff_id"]) customer = Customer.get_by_id(customer_id) customer.confirm_email() # clear db session customer = Customer.get_by_id(customer_id) customer.os_tenant_id = tenant_id # confirm email cleared tenant id Customer.fake_usage(customer, end + timedelta(minutes=1), end_second, self.service_nano_id, vm_nano, 1, resource_name="nano1") db.session.commit() report_tsv = self.get_customer_report(customer_id, start, end_report, "tsv", "detailed") report_csv = self.get_customer_report(customer_id, start, end_report, "csv", "detailed") report = self.get_customer_report(customer_id, start, end_report, "pdf", "detailed", filename="detailed.pdf") report_json = self.get_customer_report(customer_id, start, end_report, "json", "detailed") nano_cost = self.service_cost("2.23", start, end) nano2_cost = self.service_cost("2.23", start, middle_end) small_cost = self.service_cost("12.23", start, end) ip_floating_1_cost = self.service_cost("43.45", start, end)*3 ip_floating_2_cost = self.service_cost("43.45", start, end)*7 t1_cost = nano_cost + small_cost + nano2_cost + ip_floating_1_cost + ip_floating_2_cost self.assertEqual(len(report_json["tariffs"]), 2) self.assertEqual(Decimal(report_json["tariffs"][0]["total_cost"]), t1_cost) t2_cost = self.service_cost("2.23", end + timedelta(minutes=1), end_second) self.assertEqual(Decimal(report_json["tariffs"][1]["total_cost"]), t2_cost) self.assertEqual(Decimal(report_json["total"]["RUB"]), t1_cost + t2_cost) report = self.get_customer_report(customer_id, start, end_report, "pdf", filename="two_tariff.pdf") self.assertTrue(report) report = self.get_customer_report(customer_id, start, end_report, "csv", filename="two_tariff.csv") self.assertTrue(report) report = self.get_customer_report(customer_id, start, end_report, "tsv", filename="two_tariff.tsv") self.assertTrue(report) report_simple_json = self.get_customer_report(customer_id, start, end_report, "json", filename="two_tariff.pdf") self.assertTrue(report_simple_json) self.assertEqual(Decimal(report_simple_json["total"]["RUB"]), t1_cost + t2_cost) report = self.get_customer_report(customer_id, start, end_report, "pdf", "acceptance_act") report = self.get_customer_report(customer_id, end_report + timedelta(days=1), end_second + timedelta(days=31), "pdf", filename="empty.pdf")
def process_request(self, req): db = self.env.get_db_cnx() if req.method == 'POST': if not req.args.get('name') or not req.args.get('mininame'): raise TracError(_('Name and Label are required fields.')) cust = Customer(self.env, req.args.get('id')) cust.name = req.args.get('name') cust.mininame = req.args.get('mininame') cust.curmilestone = req.args.get('curmilestone') if req.args.get('submit') == "add": cust.insert(db) add_notice(req, _('The customer %(name)s has been added.', name=cust.name)) elif req.args.get('submit') == "update": cust.update(db) add_notice(req, _('The customer %(name)s has been updated.', name=cust.name)) req.redirect(req.href.customers(None)) else: data = {} cursor = db.cursor() cursor.execute('select id, name, mininame, curmilestone from customer order by mininame') customers = [] for id, name, mininame, curmilestone in cursor: cust = Customer(self.env) cust.id = id cust.name = name cust.mininame = mininame cust.curmilestone = curmilestone customers.append(cust) data.update({'customers': customers}) data.update({'milestones': model.Milestone.select(self.env, db=db)}) if req.args.get('id'): data.update({'customer': Customer(self.env, req.args.get('id'))}) else: data.update({'customer': None}) return 'customers.html', data, None
def stat(self): return Customer.customers_stat()
def test_hour_stat(self, wrp_get_volumes, wrp_get_images, wrp_get_floating_ips, wrp_get_nova_servers, wrp_get_nova_flavors, wrp_get_snapshots, wrp_get_tenants, wrp_get_nova_limits, wrp_get_ceilometer_samples): self.create_tariff("stat") self.create_customer("*****@*****.**") blocked = self.create_customer("*****@*****.**") self.admin_client.customer.block(blocked["customer_id"]) entity = self.create_customer("*****@*****.**") self.admin_client.customer.update(entity["customer_id"], customer_type="entity") customer_info = self.create_customer("*****@*****.**", make_prod=True) tenant = ModelTenant.create("fake tenant_id", "fake tenant") customer = Customer.get_by_id(customer_info["customer_id"]) customer.os_tenant_id = tenant.tenant_id db.session.add(tenant) db.session.flush() deleted = self.create_customer("*****@*****.**", make_prod=True) self.admin_client.customer.delete(deleted["customer_id"]) from task.notifications import hour_stats from keystoneclient.v2_0.tenants import Tenant from novaclient.v2.flavors import Flavor from novaclient.v2.servers import Server from cinderclient.v2.volume_snapshots import Snapshot from cinderclient.v2.volumes import Volume from ceilometerclient.v2.samples import Sample info_flavors = [ {'OS-FLV-DISABLED:disabled': False, 'OS-FLV-EXT-DATA:ephemeral': 0, 'disk': 30, 'id': 'flavor_id_1', 'links': [{ 'href': 'http://openstack.org:8774/v2/2a870d56e2b9411a86fd1736f2217c10/flavors/0316748f-a62f-49ce-a5fe-22e84fb9ad62', 'rel': 'self'}, { 'href': 'http://openstack.org:8774/2a870d56e2b9411a86fd1736f2217c10/flavors/0316748f-a62f-49ce-a5fe-22e84fb9ad62', 'rel': 'bookmark'}], 'name': 'Medium', 'os-flavor-access:is_public': False, 'ram': 8192, 'rxtx_factor': 1.0, 'swap': '', 'vcpus': 2}, {'OS-FLV-DISABLED:disabled': False, 'OS-FLV-EXT-DATA:ephemeral': 0, 'disk': 30, 'id': 'flavor_id_2', 'links': [{ 'href': 'http://openstack.ru:8774/v2/2a870d56e2b9411a86fd1736f2217c10/flavors/25e56f22-0ead-41d3-8485-e07af3114de0', 'rel': 'self'}, { 'href': 'http://openstack.ru:8774/2a870d56e2b9411a86fd1736f2217c10/flavors/25e56f22-0ead-41d3-8485-e07af3114de0', 'rel': 'bookmark'}], 'name': 'M.Large', 'os-flavor-access:is_public': False, 'ram': 24576, 'rxtx_factor': 1.0, 'swap': '', 'vcpus': 4} ] info_servers = [ {'OS-DCF:diskConfig': 'AUTO', 'OS-EXT-AZ:availability_zone': 'zone', 'OS-EXT-SRV-ATTR:host': 'qk-9', 'OS-EXT-SRV-ATTR:hypervisor_hostname': 'qk-9.domain.tld', 'OS-EXT-SRV-ATTR:instance_name': 'instance-00000ef3', 'OS-EXT-STS:power_state': 1, 'OS-EXT-STS:task_state': None, 'OS-EXT-STS:vm_state': 'active', 'OS-SRV-USG:launched_at': '2015-10-01T20:23:32.000000', 'OS-SRV-USG:terminated_at': None, 'accessIPv4': '', 'accessIPv6': '', 'addresses': {'Internet-IPs': [{'OS-EXT-IPS-MAC:mac_addr': 'fa:16:3e:e7:13:b3', 'OS-EXT-IPS:type': 'fixed', 'addr': '192.168.19.63', 'version': 4}]}, 'config_drive': '', 'created': '2015-10-01T20:23:15Z', 'flavor': { 'id': 'flavor_id_1', 'links': [{ 'href': 'http://openstack.ru:8774/2a870d56e2b9411a86fd1736f2217c10/flavors/6214ea5e-8d51-4025-885c-e14821b220cc', 'rel': 'bookmark'}]}, 'hostId': 'cb111a482618c143ca7a28c87ff0a93a1fb19283192509ac22c32af0', 'id': '4eda7eb2-e1c9-4f92-b32f-663c11d2deb0', 'image': '', 'key_name': None, 'links': [{ 'href': 'http://openstack.ru:8774/v2/2a870d56e2b9411a86fd1736f2217c10/servers/4eda7eb2-e1c9-4f92-b32f-663c11d2deb0', 'rel': 'self'}, { 'href': 'http://openstack.ru:8774/2a870d56e2b9411a86fd1736f2217c10/servers/4eda7eb2-e1c9-4f92-b32f-663c11d2deb0', 'rel': 'bookmark'}], 'metadata': {}, 'name': 'active_test', 'os-extended-volumes:volumes_attached': [{'id': '115feaa7-1126-461d-ad60-067da6dff7c9'}], 'progress': 0, 'security_groups': [{'name': 'default'}], 'status': 'ACTIVE', 'tenant_id': 'tenant_id_1', 'updated': '2015-10-01T20:23:32Z', 'user_id': '25640457f00a485698caabf72bba5f8a'}, {'OS-DCF:diskConfig': 'AUTO', 'OS-EXT-AZ:availability_zone': 'zone', 'OS-EXT-SRV-ATTR:host': 'qk-13', 'OS-EXT-SRV-ATTR:hypervisor_hostname': 'qk-13.domain.tld', 'OS-EXT-SRV-ATTR:instance_name': 'instance-00000ef0', 'OS-EXT-STS:power_state': 1, 'OS-EXT-STS:task_state': None, 'OS-EXT-STS:vm_state': 'active', 'OS-SRV-USG:launched_at': '2015-10-01T20:21:17.000000', 'OS-SRV-USG:terminated_at': None, 'accessIPv4': '', 'accessIPv6': '', 'addresses': { 'Internet-IPs': [{'OS-EXT-IPS-MAC:mac_addr': 'fa:16:3e:c6:e1:ac', 'OS-EXT-IPS:type': 'fixed', 'addr': '192.169.19.62', 'version': 4}]}, 'config_drive': '', 'created': '2015-10-01T20:21:01Z', 'flavor': {'id': 'flavor_id_2', 'links': [ { 'href': 'http://openstack.ru:8774/2a870d56e2b9411a86fd1736f2217c10/flavors/6214ea5e-8d51-4025-885c-e14821b220cc', 'rel': 'bookmark'} ]}, 'hostId': 'ccf318ebe253336d47f9bc105c723af000579aa2bc3111262e43e032', 'id': 'c7856a12-a749-47f2-8c7a-e4ee6e310ef6', 'image': '', 'key_name': 'testtesttest', 'links': [{ 'href': 'http://openstack.ru:8774/v2/2a870d56e2b9411a86fd1736f2217c10/servers/c7856a12-a749-47f2-8c7a-e4ee6e310ef6', 'rel': 'self'}, { 'href': 'http://openstack.ru:8774/2a870d56e2b9411a86fd1736f2217c10/servers/c7856a12-a749-47f2-8c7a-e4ee6e310ef6', 'rel': 'bookmark'}], 'metadata': {}, 'name': 'testtesttest', 'os-extended-volumes:volumes_attached': [{'id': 'eac9cfdf-6f88-4ab9-b005-0e4f2534bc08'}], 'progress': 0, 'security_groups': [{'name': 'default'}], 'status': 'stopped', 'tenant_id': 'tenant_id_2', 'updated': '2015-10-01T20:21:18Z', 'user_id': '25640457f00a485698caabf72bba5f8a'} ] info_floating_ips = [ {'fixed_ip_address': None, 'floating_ip_address': '192.168.122.220', 'floating_network_id': '14d12e05-6e0f-4b1c-b8cd-43747eb5b8c5', 'id': '9a31e9ff-6b23-43e6-afad-ddd3ba194597', 'port_id': None, 'router_id': None, 'status': 'DOWN', 'tenant_id': 'd31e2dbfe716428daddbd4631bb73ab0'}, {'fixed_ip_address': None, 'floating_ip_address': '192.168.122.220', 'floating_network_id': '14d12e05-6e0f-4b1c-b8cd-43747eb5b8c5', 'id': '9a31e9ff-6b23-43e6-afad-ddd3ba194597', 'port_id': None, 'router_id': None, 'status': 'UP', 'tenant_id': 'd31e2dbfe716428daddbd4631bb73ab0'}] info_images = [ { 'checksum': 'ee1eca47dc88f4879d8a229cc70a07c6', 'container_format': 'bare', 'created_at': '2015-08-05T10:24:00Z', 'disk_format': 'qcow2', 'file': '/v2/images/cf70343a-54a7-46e8-9707-330f149d16ef/file', 'id': 'cf70343a-54a7-46e8-9707-330f149d16ef', 'min_disk': 0, 'min_ram': 0, 'name': 'cirros-0.3.4-x86_64', 'owner': '514c60f95d9240508be98d1bf20fdccb', 'protected': False, 'schema': '/v2/schemas/image', 'size': 5, 'status': 'active', 'tags': [], 'updated_at': '2015-08-05T10:24:00Z', 'virtual_size': None, 'visibility': 'public' }, { 'checksum': 'ee1eca47dc88f4879d8a229cc70a07c6', 'container_format': 'bare', 'created_at': '2015-08-05T10:24:00Z', 'disk_format': 'qcow2', 'file': '/v2/images/cf70343a-54a7-46e8-9707-330f149d16ef/file', 'id': 'cf70343a-54a7-46e8-9707-330f149d16ef', 'min_disk': 0, 'min_ram': 0, 'name': 'cirros-0.3.4-x86_64', 'owner': '514c60f95d9240508be98d1bf20fdccb', 'protected': False, 'schema': '/v2/schemas/image', 'size': 7, 'status': 'active', 'tags': [], 'updated_at': '2015-08-05T10:24:00Z', 'virtual_size': None, 'visibility': 'private' }] info_volumes = [ { 'attachments': [], 'availability_zone': 'nova', 'bootable': 'false', 'consistencygroup_id': None, 'created_at': '2015-10-08T15:24:22.000000', 'description': None, 'encrypted': False, 'id': 'a5514296-4c70-426c-ba74-3e1ffc29bffc', 'links': [ { 'href': 'http://192.168.3.101:8776/v2/514c60f95d9240508be98d1bf20fdccb/volumes/a5514296-4c70-426c-ba74-3e1ffc29bffc', 'rel': 'self'}, { 'href': 'http://192.168.3.101:8776/514c60f95d9240508be98d1bf20fdccb/volumes/a5514296-4c70-426c-ba74-3e1ffc29bffc', 'rel': 'bookmark'}], 'metadata': {}, 'multiattach': False, 'name': 'denis_test_volume_1', 'os-vol-host-attr:host': 'ubuntu-kilo#GlusterFS', 'os-vol-mig-status-attr:migstat': None, 'os-vol-mig-status-attr:name_id': None, 'os-vol-tenant-attr:tenant_id': 'aee181ad99394b9e81ecad5d61d09261', 'os-volume-replication:driver_data': None, 'os-volume-replication:extended_status': None, 'replication_status': 'disabled', 'size': 7, 'snapshot_id': None, 'source_volid': None, 'status': 'available', 'user_id': '5f796d5bee7f424180c6ba79f55811fe', 'volume_type': None }, {'attachments': [{'attachment_id': '6464d0e4-7bfa-4284-87bd-85d151e4fdfd', 'device': '/dev/vda', 'host_name': None, 'id': '51e36e6b-aa99-4adc-8f50-e6066a8c885c', 'server_id': 'a96aa81d-c5e9-4b05-8e6d-9db7838cf94d', 'volume_id': '51e36e6b-aa99-4adc-8f50-e6066a8c885c'}], 'availability_zone': 'nova', 'bootable': 'true', 'consistencygroup_id': None, 'created_at': '2015-10-08T14:14:19.000000', 'description': 'hdisk1 hdisk1 hdisk1', 'encrypted': False, 'id': '51e36e6b-aa99-4adc-8f50-e6066a8c885c', 'links': [{ 'href': 'http://192.168.3.101:8776/v2/514c60f95d9240508be98d1bf20fdccb/volumes/51e36e6b-aa99-4adc-8f50-e6066a8c885c', 'rel': 'self'}, { 'href': 'http://192.168.3.101:8776/514c60f95d9240508be98d1bf20fdccb/volumes/51e36e6b-aa99-4adc-8f50-e6066a8c885c', 'rel': 'bookmark'}], 'metadata': {'attached_mode': 'rw', 'readonly': 'False'}, 'multiattach': False, 'name': 'hdisk1', 'os-vol-host-attr:host': 'ubuntu-kilo#GlusterFS', 'os-vol-mig-status-attr:migstat': None, 'os-vol-mig-status-attr:name_id': None, 'os-vol-tenant-attr:tenant_id': '8e165ea202e346299280cb7afd9ef828', 'os-volume-replication:driver_data': None, 'os-volume-replication:extended_status': None, 'replication_status': 'disabled', 'size': 9, 'snapshot_id': None, 'source_volid': None, 'status': 'in-use', 'user_id': '392b8565a7ad497793d6bd826db6dbc9', 'volume_image_metadata': {'checksum': 'ee1eca47dc88f4879d8a229cc70a07c6', 'container_format': 'bare', 'disk_format': 'qcow2', 'image_id': 'cf70343a-54a7-46e8-9707-330f149d16ef', 'image_name': 'cirros-0.3.4-x86_64', 'min_disk': '0', 'min_ram': '0', 'size': '13287936'}, } ] info_snapshots = [ { 'created_at': '2015-10-08T15:25:00.000000', 'description': '', 'id': '055f5dc8-2224-47eb-8a55-9c3ecf2f74a0', 'metadata': {}, 'name': 'test_snapshot_1', 'os-extended-snapshot-attributes:progress': '100%', 'os-extended-snapshot-attributes:project_id': 'aee181ad99394b9e81ecad5d61d09261', 'size': 3, 'status': 'available', 'volume_id': 'a5514296-4c70-426c-ba74-3e1ffc29bffc' }, { 'created_at': '2015-10-08T15:25:00.000000', 'description': '', 'id': '055f5dc8-2224-47eb-8a55-9c3ecf2f74a0', 'metadata': {}, 'name': 'test_snapshot_2', 'os-extended-snapshot-attributes:progress': '100%', 'os-extended-snapshot-attributes:project_id': 'aee181ad99394b9e81ecad5d61d09261', 'size': 5, 'status': 'available', 'volume_id': 'a5514296-4c70-426c-ba74-3e1ffc29bffc' } ] info_tenants = [ {'description': 'Unit test tenant - 1', 'enabled': True, 'id': 'tenant_id_1', 'name': 'tenant_name_1'}, {'description': 'Unit test tenant - 2', 'enabled': True, 'id': 'tenant_id_2', 'name': 'tenant_name_2'}, {'description': 'Unit test tenant - 3', 'enabled': True, 'id': 'tenant_id_3', 'name': 'tenant_name_3'}, ] info_nova_limits = { 'maxImageMeta': 128, 'maxPersonality': 5, 'maxPersonalitySize': 10240, 'maxSecurityGroupRules': 20, 'maxSecurityGroups': 10, 'maxServerGroupMembers': 10, 'maxServerGroups': 10, 'maxServerMeta': 128, 'maxTotalCores': 20, 'maxTotalFloatingIps': 10, 'maxTotalInstances': 20, 'maxTotalKeypairs': 10, 'maxTotalRAMSize': 20480, 'totalCoresUsed': 1, 'totalFloatingIpsUsed': 0, 'totalInstancesUsed': 1, 'totalRAMUsed': 8192, 'totalSecurityGroupsUsed': 1, 'totalServerGroupsUsed': 0 } info_bandwidth = [ {'id': 'c9510474-5e04-11e5-920d-fa163e4b35b4', 'metadata': {'fref': 'None', 'instance_id': '1b02a1c2-7a6e-404a-b355-d2840d295677', 'instance_type': 'ef9a407d-742d-4f23-9055-decbccb143d9', 'mac': 'fa:16:3e:9e:18:12', 'name': 'tap345a6b63-eb'}, 'meter': 'network.incoming.bytes', 'project_id': '03926f96177e4df9a0fc5c77f6e674d8', 'recorded_at': '2015-09-18T12:57:15.769000', 'resource_id': 'instance-00000018-1b02a1c2-7a6e-404a-b355-d2840d295677-tap345a6b63-eb', 'source': 'openstack', 'timestamp': '2015-09-18T12:57:15', 'type': 'cumulative', 'unit': 'B', 'user_id': 'c1ef3d08d9694acb8740ccb66d0ba945', 'volume': 11.0 }, ] wrp_get_ceilometer_samples.return_value = [Sample(None, s) for s in info_bandwidth] wrp_get_images.return_value = info_images wrp_get_floating_ips.return_value = info_floating_ips wrp_get_tenants.return_value = [Tenant(None, t) for t in info_tenants] wrp_get_nova_servers.return_value = [Server(None, s) for s in info_servers] wrp_get_nova_flavors.return_value = [Flavor(None, f) for f in info_flavors] wrp_get_volumes.return_value = [Volume(None, volume) for volume in info_volumes] wrp_get_snapshots.return_value = [Snapshot(None, snapshot) for snapshot in info_snapshots] wrp_get_nova_limits.return_value = info_nova_limits # Run stat collection hour_stats() expected_stats = { "stats.flavor.total": 2, "stats.flavor.Medium": 1, 'stats.ip.floating.active_customer': 6, 'stats.ip.floating.blocked_customer': 2, 'stats.ip.floating.customer_mode-production': 2, 'stats.ip.floating.customer_mode-test': 6, 'stats.ip.floating.customer_type-entity': 2, 'stats.ip.floating.customer_type-private': 6, 'stats.ip.floating.ip_status-DOWN': 4, 'stats.ip.floating.ip_status-UP': 4, 'stats.ip.floating.total': 8, 'stats.storage.image.total': 2, 'stats.storage.image.total_size': 12, 'stats.storage.image.visibility-public': 1, 'stats.storage.image.visibility-private': 1, 'stats.storage.image.status-active': 2, 'stats.storage.volume.total': 2, 'stats.storage.volume.total_size': 16, 'stats.storage.volume.volume-bootable': 2, 'stats.storage.volume.status-available': 1, 'stats.storage.volume.status-in-use': 1, 'stats.storage.snapshots.total': 2, 'stats.storage.snapshots.total_size': 8, 'stats.storage.snapshots.available': 2, 'stats.resources.totalRAMUsed': 8192*1, 'stats.resources.totalCoresUsed': 1, 'stats.resources.flavor.Medium.ram': 8192, 'stats.resources.flavor.Medium.vcpus': 2, 'stats.network.outgoing.bytes': info_bandwidth[0]['volume'] * len(info_tenants), 'stats.network.incoming.bytes': info_bandwidth[0]['volume'] * len(info_tenants), } for k, v in expected_stats.items(): self.verify_metric(k, v)
def payment_pay(self, *args, **request_data): """Checks payment availability for customer. Parameters must be sent as json object. Request data looks like: { 'AccountId': '1000', # Customer ID here 'Amount': '10.00', 'AuthCode': 'A1B2C3', 'CardExpDate': '10/15', 'CardFirstSix': '424242', 'CardLastFour': '4242', 'CardType': 'Visa', 'Currency': 'RUB', 'Data': '{"myProp":"myProp value"}', 'DateTime': '2015-08-05 06:54:46', 'Description': 'Payment description', 'Email': '*****@*****.**', 'InvoiceId': '1234567', 'IpAddress': '46.251.83.16', 'IpCity': 'Moscow', 'IpCountry': 'RU', 'IpDistrict': 'Moscow federal district', 'IpLatitude': '56.329918', 'IpLongitude': '44.009193', 'IpRegion': 'Moscow district', 'Name': 'CARDHOLDER NAME', 'PaymentAmount': '10.00', # Not found in documentation but exist in request 'PaymentCurrency': 'RUB', # No in docs 'Status': 'Completed', 'TestMode': '1', 'Token': '477BBA133C182267FE5F086924ABDC5DB71F77BFC27F01F2843F2CDC69D89F05', 'TransactionId': '1211506' } :param Int TransactionId: Mandatory - System transaction number. :param Numeric Amount: Mandatory - Payment amount from widget. Dot as separator, two digits after dot. :param String Currency: Mandatory - Currency: RUB/USD/EUR/GBP from widget parameters. :param String InvoiceId: Not mandatory - Order number from widget parameters. :param String AccountId: Mandatory - Customer identifier from widget parameters. :param String SubscriptionId: Not mandatory - Subscription identifier from widget parameters (for recurrent payments). :param String Name: Not mandatory - Card holder name. :param String Email: Payer's e-mail :param DateTime: Mandatory - Payment creation date/time in UTC (yyyy-MM-dd HH:mm:ss). :param String IpAddress: Not mandatory - Payer IP-address :param String IpCountry: Not mandatory - Payer's country double-chars code (according to ISO3166-1) :param String IpCity: Not mandatory - Payer's city :param String IpRegion: Not mandatory - Payer's region. :param String IpDistrict: Not mandatory - Payer's district. :param String CardFirstSix: Mandatory - Credit card first 6 digits :param String CardLastFour: Mandatory - Credit card last 6 digits :param String CardType: Mandatory - Card payment system: Visa or MasterCard or Maestro :param String CardExpDate: Mandatory - Card expiration date MM/YY :param String Issuer: Not mandatory - Issuer bank name :param String IssuerBankCountry: Not mandatory - Issuer bank country double-char code (according to ISO3166-1) :param String Description: Not mandatory - Payment description from widget parameters. :param Json Data: Not mandatory - Any json-data from widget. :param Bit TestMode: Mandatory - Test mode flag (1 or 0) :param String Status: Mandatory - Payment status: Completed — for single-step, Authorized — for double-step. :param String Token: Not mandatory - Card token for recurrent payments without card data. :return: Status code, looks like {'code': 0} """ logbook.info("[payment_pay] Request info:{}", request_data) short_payment_info = dict([(key, request_data.get(key)) for key in PaymentsApi.payment_info_fields]) # Common validation validation_res, validation_info = self.validate_request(request_data, short_payment_info) if not validation_res: log_error("[payment_pay] {} Payment info: {}", validation_info, short_payment_info) # Expected successful code (no other codes were accepted for pay) return {"code": self.ERROR_OK} # Currency validation currency = request_data['Currency'] if not currency or currency not in conf.currency.active: log_error("[payment_pay] Invalid or incompatible currency: {}. Payment info: {}", currency, short_payment_info) # Expected successful code (no other codes were accepted for pay) return {"code": self.ERROR_OK} # Customer validation customer_id = request_data['AccountId'] customer = Customer.get_by_id(customer_id, False) if not customer: log_error("[payment_pay] Customer id '{}' not found. Payment info: {}", customer_id, short_payment_info) # Expected successful code (no other codes were accepted for pay) return {"code": self.ERROR_OK} if customer.is_test_mode(): # Payments in test mode is not allowed logbook.warning("[payment_pay] Customer {} in test mode. Payment info {}", customer, short_payment_info) return {'code': self.ERROR_OK} # Transaction validation transaction_id = request_data['TransactionId'] transaction_count = customer.check_account_history_transaction(transaction_id) if transaction_count: # This transaction already processed logbook.warning("[payment_pay] Customer {}. Transaction already processed. Payment info {}", customer, short_payment_info) return {'code': self.ERROR_OK} payment_description = _("Balance recharge via CloudPayments. Transaction: {}") # Process payment amount = Decimal(request_data['Amount']) customer.modify_balance(amount, currency, None, payment_description.format(request_data['TransactionId']), transaction_id=transaction_id) # Save customer's payment card for automated payments aux_data = request_data.get('Data') if aux_data and aux_data.get('saveAsDefault', False) is True: card_token = request_data.get("Token") if not card_token: log_error("[payment_pay] Customer {} wants to save card, but Token empty. Payment info: {}", customer, short_payment_info) else: card = CustomerCard.add_card(customer_id, request_data['CardLastFour'], request_data['CardType'], card_token, active=True) logbook.info("[payment_pay] Customer {}. Add payment card: {}", customer, card.display()) # Expected successful code (no other codes were accepted for pay) return {"code": 0}