diff --git a/TODO.md b/TODO.md index 11998e8a..46271e8f 100644 --- a/TODO.md +++ b/TODO.md @@ -109,3 +109,4 @@ at + clock time, midnight, noon- At 3:30 p.m., At 4:01, At noon * latest by 'id' *always* +* replace add_now by default=lambda: timezone.now() diff --git a/orchestra/apps/bills/models.py b/orchestra/apps/bills/models.py index fe96fe5b..ffe54030 100644 --- a/orchestra/apps/bills/models.py +++ b/orchestra/apps/bills/models.py @@ -35,17 +35,21 @@ class Bill(models.Model): (PENDING, _("Pending")), (BAD_DEBT, _("Bad debt")), ) - + BILL = 'BILL' + INVOICE = 'INVOICE' + AMENDMENTINVOICE = 'AMENDMENTINVOICE' + FEE = 'FEE' + AMENDMENTFEE = 'AMENDMENTFEE' + PROFORMA = 'PROFORMA' TYPES = ( - ('INVOICE', _("Invoice")), - ('AMENDMENTINVOICE', _("Amendment invoice")), - ('FEE', _("Fee")), - ('AMENDMENTFEE', _("Amendment Fee")), - ('PROFORMA', _("Pro forma")), + (INVOICE, _("Invoice")), + (AMENDMENTINVOICE, _("Amendment invoice")), + (FEE, _("Fee")), + (AMENDMENTFEE, _("Amendment Fee")), + (PROFORMA, _("Pro forma")), ) - number = models.CharField(_("number"), max_length=16, unique=True, - blank=True) + number = models.CharField(_("number"), max_length=16, unique=True, blank=True) account = models.ForeignKey('accounts.Account', verbose_name=_("account"), related_name='%(class)s') type = models.CharField(_("type"), max_length=16, choices=TYPES) @@ -63,7 +67,7 @@ class Bill(models.Model): objects = BillManager() class Meta: - get_latest_by = 'created_on' + get_latest_by = 'id' def __unicode__(self): return self.number @@ -101,8 +105,8 @@ class Bill(models.Model): def set_number(self): cls = type(self) bill_type = self.get_type() - if bill_type == 'BILL': - raise TypeError("get_new_number() can not be used on a Bill class") + if bill_type == self.BILL: + raise TypeError('This method can not be used on BILL instances') prefix = getattr(settings, 'BILLS_%s_NUMBER_PREFIX' % bill_type) if self.is_open: prefix = 'O{}'.format(prefix) @@ -117,8 +121,7 @@ class Bill(models.Model): number_length = settings.BILLS_NUMBER_LENGTH zeros = (number_length - len(str(number))) * '0' number = zeros + str(number) - self.number = '{prefix}{year}{number}'.format( - prefix=prefix, year=year, number=number) + self.number = '{prefix}{year}{number}'.format(prefix=prefix, year=year, number=number) def get_due_date(self, payment=None): now = timezone.now() @@ -134,7 +137,7 @@ class Bill(models.Model): self.due_on = self.get_due_date(payment=payment) self.total = self.get_total() self.html = self.render(payment=payment) - if self.get_type() != 'PROFORMA': + if self.get_type() != self.PROFORMA: self.transactions.create(bill=self, source=payment, amount=self.total) self.closed_on = timezone.now() self.is_open = False @@ -175,8 +178,8 @@ class Bill(models.Model): 'default_due_date': self.get_due_date(payment=payment), 'now': timezone.now(), }) - template = getattr(settings, 'BILLS_%s_TEMPLATE' % self.get_type(), - settings.BILLS_DEFAULT_TEMPLATE) + template_name = 'BILLS_%s_TEMPLATE' % self.get_type() + template = getattr(settings, template_name, settings.BILLS_DEFAULT_TEMPLATE) bill_template = loader.get_template(template) html = bill_template.render(context) html = html.replace('-pageskip-', '') @@ -234,8 +237,7 @@ class BillLine(models.Model): """ Base model for bill item representation """ bill = models.ForeignKey(Bill, verbose_name=_("bill"), related_name='lines') description = models.CharField(_("description"), max_length=256) - rate = models.DecimalField(_("rate"), blank=True, null=True, - max_digits=12, decimal_places=2) + rate = models.DecimalField(_("rate"), blank=True, null=True, max_digits=12, decimal_places=2) quantity = models.DecimalField(_("quantity"), max_digits=12, decimal_places=2) subtotal = models.DecimalField(_("subtotal"), max_digits=12, decimal_places=2) tax = models.PositiveIntegerField(_("tax")) @@ -261,7 +263,7 @@ class BillLine(models.Model): return total def save(self, *args, **kwargs): - # TODO cost of this shit + # TODO cost and consistency of this shit super(BillLine, self).save(*args, **kwargs) if self.bill.is_open: self.bill.total = self.bill.get_total() @@ -270,8 +272,7 @@ class BillLine(models.Model): class BillSubline(models.Model): """ Subline used for describing an item discount """ - line = models.ForeignKey(BillLine, verbose_name=_("bill line"), - related_name='sublines') + line = models.ForeignKey(BillLine, verbose_name=_("bill line"), related_name='sublines') description = models.CharField(_("description"), max_length=256) total = models.DecimalField(max_digits=12, decimal_places=2) # TODO type ? Volume and Compensation diff --git a/orchestra/apps/domains/admin.py b/orchestra/apps/domains/admin.py index e7b6ce57..2f7fafcc 100644 --- a/orchestra/apps/domains/admin.py +++ b/orchestra/apps/domains/admin.py @@ -57,7 +57,9 @@ class DomainAdmin(ChangeListDefaultFilter, AccountAdminMixin, ExtendedModelAdmin list_filter = [TopDomainListFilter] change_readonly_fields = ('name',) search_fields = ['name', 'account__user__username'] - default_changelist_filters = (('top_domain', 'True'),) + default_changelist_filters = ( + ('top_domain', 'True'), + ) form = DomainAdminForm def structured_name(self, domain): diff --git a/orchestra/apps/domains/backends.py b/orchestra/apps/domains/backends.py index 04e22fb3..acc5592b 100644 --- a/orchestra/apps/domains/backends.py +++ b/orchestra/apps/domains/backends.py @@ -74,7 +74,9 @@ class Bind9MasterDomainBackend(ServiceController): class Bind9SlaveDomainBackend(Bind9MasterDomainBackend): verbose_name = _("Bind9 slave domain") - related_models = (('domains.Domain', 'origin'),) + related_models = ( + ('domains.Domain', 'origin'), + ) def save(self, domain): context = self.get_context(domain) diff --git a/orchestra/apps/issues/models.py b/orchestra/apps/issues/models.py index b47efdb7..2341da5b 100644 --- a/orchestra/apps/issues/models.py +++ b/orchestra/apps/issues/models.py @@ -161,7 +161,7 @@ class Message(models.Model): created_on = models.DateTimeField(_("created on"), auto_now_add=True) class Meta: - get_latest_by = "created_on" + get_latest_by = 'id' def __unicode__(self): return u"#%i" % self.id @@ -188,4 +188,6 @@ class TicketTracker(models.Model): related_name='ticket_trackers') class Meta: - unique_together = (('ticket', 'user'),) + unique_together = ( + ('ticket', 'user'), + ) diff --git a/orchestra/apps/orchestration/models.py b/orchestra/apps/orchestration/models.py index c990a406..dcd68c0c 100644 --- a/orchestra/apps/orchestration/models.py +++ b/orchestra/apps/orchestration/models.py @@ -66,7 +66,7 @@ class BackendLog(models.Model): last_update = models.DateTimeField(_("last update"), auto_now=True) class Meta: - get_latest_by = 'created' + get_latest_by = 'id' @property def execution_time(self): diff --git a/orchestra/apps/orders/models.py b/orchestra/apps/orders/models.py index 7e110fe6..5054b2d9 100644 --- a/orchestra/apps/orders/models.py +++ b/orchestra/apps/orders/models.py @@ -81,9 +81,9 @@ class Order(models.Model): related_name='orders') content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField(null=True) - service = models.ForeignKey(settings.ORDERS_SERVICE_MODEL, - verbose_name=_("service"), related_name='orders') - registered_on = models.DateField(_("registered"), auto_now_add=True) # TODO datetime field? + service = models.ForeignKey(settings.ORDERS_SERVICE_MODEL, verbose_name=_("service"), + related_name='orders') + registered_on = models.DateField(_("registered"), default=lambda: timezone.now()) cancelled_on = models.DateField(_("cancelled"), null=True, blank=True) billed_on = models.DateField(_("billed on"), null=True, blank=True) billed_until = models.DateField(_("billed until"), null=True, blank=True) @@ -93,6 +93,9 @@ class Order(models.Model): content_object = generic.GenericForeignKey() objects = OrderQuerySet.as_manager() + class Meta: + get_latest_by = 'id' + def __unicode__(self): return str(self.service) @@ -180,6 +183,7 @@ class MetricStorage(models.Model): order = models.ForeignKey(Order, verbose_name=_("order"), related_name='metrics') value = models.DecimalField(_("value"), max_digits=16, decimal_places=2) created_on = models.DateField(_("created"), auto_now_add=True) +# default=lambda: timezone.now()) updated_on = models.DateTimeField(_("updated")) class Meta: @@ -203,9 +207,11 @@ class MetricStorage(models.Model): metric.save() -_excluded_models = (MetricStorage, LogEntry, Order, ContentType, MigrationRecorder.Migration) +accounts.register(Order) +_excluded_models = (MetricStorage, LogEntry, Order, ContentType, MigrationRecorder.Migration) + @receiver(post_delete, dispatch_uid="orders.cancel_orders") def cancel_orders(sender, **kwargs): if sender not in _excluded_models: @@ -218,7 +224,6 @@ def cancel_orders(sender, **kwargs): if related and related != instance: Order.update_orders(related) - @receiver(post_save, dispatch_uid="orders.update_orders") def update_orders(sender, **kwargs): if sender not in _excluded_models: @@ -229,7 +234,3 @@ def update_orders(sender, **kwargs): related = helpers.get_related_objects(instance) if related and related != instance: Order.update_orders(related) - - - -accounts.register(Order) diff --git a/orchestra/apps/orders/tests/functional_tests/tests.py b/orchestra/apps/orders/tests/functional_tests/tests.py index 225deca5..0b1a522d 100644 --- a/orchestra/apps/orders/tests/functional_tests/tests.py +++ b/orchestra/apps/orders/tests/functional_tests/tests.py @@ -2,10 +2,11 @@ import datetime import decimal import sys -from dateutil import relativedelta +from dateutil.relativedelta import relativedelta from django.contrib.contenttypes.models import ContentType from django.db.models import F from django.utils import timezone +from freezegun import freeze_time from orchestra.apps.accounts.models import Account from orchestra.apps.mails.models import Mailbox @@ -56,21 +57,21 @@ class FTPBillingTest(BaseBillingTest): def test_ftp_account_1_year_fiexed(self): service = self.create_ftp_service() user = self.create_ftp() - bp = timezone.now().date() + relativedelta.relativedelta(years=1) + bp = timezone.now().date() + relativedelta(years=1) bills = service.orders.bill(billing_point=bp, fixed_point=True) self.assertEqual(10, bills[0].get_total()) def test_ftp_account_2_year_fiexed(self): service = self.create_ftp_service() user = self.create_ftp() - bp = timezone.now().date() + relativedelta.relativedelta(years=2) + bp = timezone.now().date() + relativedelta(years=2) bills = service.orders.bill(billing_point=bp, fixed_point=True) self.assertEqual(20, bills[0].get_total()) def test_ftp_account_6_month_fixed(self): service = self.create_ftp_service() self.create_ftp() - bp = timezone.now().date() + relativedelta.relativedelta(months=6) + bp = timezone.now().date() + relativedelta(months=6) bills = service.orders.bill(billing_point=bp, fixed_point=True) self.assertEqual(5, bills[0].get_total()) @@ -95,7 +96,7 @@ class FTPBillingTest(BaseBillingTest): account = self.create_account() service = self.create_ftp_service() user = self.create_ftp(account=account) - first_bp = timezone.now().date() + relativedelta.relativedelta(years=2) + first_bp = timezone.now().date() + relativedelta(years=2) bills = service.orders.bill(billing_point=first_bp, fixed_point=True) self.assertEqual(1, service.orders.active().count()) user.delete() @@ -103,7 +104,7 @@ class FTPBillingTest(BaseBillingTest): user = self.create_ftp(account=account) self.assertEqual(1, service.orders.active().count()) self.assertEqual(2, service.orders.count()) - bp = timezone.now().date() + relativedelta.relativedelta(years=1) + bp = timezone.now().date() + relativedelta(years=1) bills = service.orders.bill(billing_point=bp, fixed_point=True, new_open=True) discount = bills[0].lines.order_by('id')[0].sublines.get() self.assertEqual(decimal.Decimal(-20), discount.total) @@ -246,7 +247,9 @@ class DomainBillingTest(BaseBillingTest): self.assertEqual(6, bills[0].get_total()) -class TrafficBillingTest(BaseBillingTest): +class BaseTrafficBillingTest(BaseBillingTest): + METRIC = 'account.resources.traffic.used' + def create_traffic_service(self): service = Service.objects.create( description="Traffic", @@ -255,7 +258,7 @@ class TrafficBillingTest(BaseBillingTest): billing_period=Service.MONTHLY, billing_point=Service.FIXED_DATE, is_fee=False, - metric='account.resources.traffic.used', + metric=self.METRIC, pricing_period=Service.BILLING_PERIOD, rate_algorithm=Service.STEP_PRICE, on_cancel=Service.NOTHING, @@ -287,7 +290,9 @@ class TrafficBillingTest(BaseBillingTest): MonitorData.objects.create(monitor='FTPTraffic', content_object=account.user, value=value, date=date) data = ResourceData.get_or_create(account, self.resource) data.update() - + + +class TrafficBillingTest(BaseTrafficBillingTest): def test_traffic(self): service = self.create_traffic_service() resource = self.create_traffic_resource() @@ -297,7 +302,7 @@ class TrafficBillingTest(BaseBillingTest): bills = service.orders.bill(commit=False) self.assertEqual([(account, [])], bills) - # Prepay + # move into the past delta = datetime.timedelta(days=60) date = (timezone.now()-delta).date() order = service.orders.get() @@ -322,10 +327,71 @@ class TrafficBillingTest(BaseBillingTest): account1 = self.create_account() account2 = self.create_account() # TODO - + + +class TrafficPrepayBillingTest(BaseTrafficBillingTest): + METRIC = "max((account.resources.traffic.used or 0) - getattr(account.miscellaneous.filter(service__name='traffic prepay').last(), 'amount', 0), 0)" + + def create_prepay_service(self): + service = Service.objects.create( + description="Traffic prepay", + content_type=ContentType.objects.get_for_model(Miscellaneous), + match="miscellaneous.is_active and miscellaneous.service.name.lower() == 'traffic prepay'", + billing_period=Service.ANUAL, + billing_point=Service.FIXED_DATE, + is_fee=False, + metric="miscellaneous.amount", + pricing_period=Service.BILLING_PERIOD, + rate_algorithm=Service.STEP_PRICE, + on_cancel=Service.NOTHING, # TODO on_register == NOTHING or make on_cancel generic + payment_style=Service.PREPAY, + tax=0, + nominal_price=5 + ) + return service + + def create_prepay(self, amount, account=None): + if not account: + account = self.create_account() + name = 'traffic prepay' + service, __ = MiscService.objects.get_or_create(name='traffic prepay', description='Traffic prepay', has_amount=True) + return Miscellaneous.objects.create(service=service, description=name, account=account, amount=amount) + def test_traffic_prepay(self): - pass - # TODO + service = self.create_traffic_service() + prepay_service = self.create_prepay_service() + account = self.create_account() + + self.create_traffic_resource() + prepay = self.create_prepay(10, account=account) + self.report_traffic(account, timezone.now(), 10**9) + + print prepay_service.orders.all() + # TODO metric on the current day! how to solve it consistently? + # TODO prepay doesnt allow for discount + + # move into the past + # TODO with patch.object(timezone, 'now', return_value=now+relativedelta(years=1)): + delta = datetime.timedelta(days=60) + date = (timezone.now()-delta).date() + order = service.orders.get() + order.registered_on = date + order.save() + + metric = order.metrics.latest() + metric.updated_on -= delta + metric.save() + + bills = service.orders.bill(proforma=True) + self.assertEqual(0, bills[0].get_total()) + + self.report_traffic(account, date, 10**10*9) + metric = order.metrics.latest() + metric.updated_on -= delta + metric.save() + + bills = service.orders.bill(proforma=True) + self.assertEqual((90-10-10)*10, bills[0].get_total()) class MailboxBillingTest(BaseBillingTest): @@ -403,7 +469,7 @@ class MailboxBillingTest(BaseBillingTest): self.allocate_disk(mailbox, 10) bill = service.orders.bill()[0] self.assertEqual(0, bill.get_total()) - bp = timezone.now().date() + relativedelta.relativedelta(years=1) + bp = timezone.now().date() + relativedelta(years=1) bill = disk_service.orders.bill(billing_point=bp, fixed_point=True)[0] self.assertEqual(90, bill.get_total()) mailbox = self.create_mailbox(account=account) @@ -421,38 +487,30 @@ class MailboxBillingTest(BaseBillingTest): account = self.create_account() mailbox = self.create_mailbox(account=account) now = timezone.now() - bp = now.date() + relativedelta.relativedelta(years=1) + bp = now.date() + relativedelta(years=1) + options = dict(billing_point=bp, fixed_point=True, proforma=True, new_open=True) self.allocate_disk(mailbox, 10) - bill = service.orders.bill(billing_point=bp, fixed_point=True, proforma=True, new_open=True)[0] + bill = service.orders.bill(**options).pop() self.assertEqual(9*10, bill.get_total()) - self.allocate_disk(mailbox, 20) - created_on = now+relativedelta.relativedelta(months=6) - order = service.orders.get() - metric = order.metrics.latest('id') - metric.created_on = created_on - metric.save() - bill = service.orders.bill(billing_point=bp, fixed_point=True, proforma=True, new_open=True)[0] - self.assertEqual(9*10*0.5 + 19*10*0.5, bill.get_total()) + with freeze_time(now+relativedelta(months=6)): + self.allocate_disk(mailbox, 20) + bill = service.orders.bill(**options).pop() + total = 9*10*0.5 + 19*10*0.5 + self.assertEqual(total, bill.get_total()) - self.allocate_disk(mailbox, 30) - created_on = now+relativedelta.relativedelta(months=9) - order = service.orders.get() - metric = order.metrics.latest('id') - metric.created_on = created_on - metric.save() - bill = service.orders.bill(billing_point=bp, fixed_point=True, proforma=True, new_open=True)[0] - self.assertEqual(9*10*0.5 + 19*10*0.25 + 29*10*0.25, bill.get_total()) + with freeze_time(now+relativedelta(months=9)): + self.allocate_disk(mailbox, 30) + bill = service.orders.bill(**options).pop() + total = 9*10*0.5 + 19*10*0.25 + 29*10*0.25 + self.assertEqual(total, bill.get_total()) - self.allocate_disk(mailbox, 10) - created_on = now+relativedelta.relativedelta(years=1) - order = service.orders.get() - metric = order.metrics.latest('id') - metric.created_on = created_on - metric.save() - bill = service.orders.bill(billing_point=bp, fixed_point=True, proforma=True, new_open=True)[0] - self.assertEqual(9*10*0.5 + 19*10*0.25 + 29*10*0.25, bill.get_total()) + with freeze_time(now+relativedelta(years=1)): + self.allocate_disk(mailbox, 10) + bill = service.orders.bill(**options).pop() + total = 9*10*0.5 + 19*10*0.25 + 29*10*0.25 + self.assertEqual(total, bill.get_total()) class JobBillingTest(BaseBillingTest): @@ -480,9 +538,9 @@ class JobBillingTest(BaseBillingTest): def create_job(self, amount, account=None): if not account: account = self.create_account() - job_name = '%s.es' % random_ascii(10) - job_service, __ = MiscService.objects.get_or_create(name='job', description='Random job', has_amount=True) - return Miscellaneous.objects.create(service=job_service, description=job_name, account=account, amount=amount) + description = 'Random Job %s' % random_ascii(10) + service, __ = MiscService.objects.get_or_create(name='job', description=description, has_amount=True) + return Miscellaneous.objects.create(service=service, description=description, account=account, amount=amount) def test_job(self): service = self.create_job_service() @@ -499,7 +557,22 @@ class JobBillingTest(BaseBillingTest): class PlanBillingTest(BaseBillingTest): def create_plan_service(self): - pass + service = Service.objects.create( + description="Association membership fee", + content_type=ContentType.objects.get_for_model(Miscellaneous), + match="account.is_active and account.type == 'ASSOCIATION'", + billing_period=Service.ANUAL, + billing_point=Service.FIXED_DATE, + is_fee=True, + metric='', + pricing_period=Service.BILLING_PERIOD, + rate_algorithm=Service.STEP_PRICE, + on_cancel=Service.DISCOUNT, + payment_style=Service.PREPAY, + tax=0, + nominal_price=20 + ) + return service def create_plan(self): if not account: diff --git a/orchestra/apps/resources/models.py b/orchestra/apps/resources/models.py index c8a4fb2b..02d5a047 100644 --- a/orchestra/apps/resources/models.py +++ b/orchestra/apps/resources/models.py @@ -161,7 +161,7 @@ class MonitorData(models.Model): content_object = GenericForeignKey() class Meta: - get_latest_by = 'date' + get_latest_by = 'id' verbose_name_plural = _("monitor data") def __unicode__(self): diff --git a/orchestra/apps/services/handlers.py b/orchestra/apps/services/handlers.py index 4f477351..16fc7708 100644 --- a/orchestra/apps/services/handlers.py +++ b/orchestra/apps/services/handlers.py @@ -288,7 +288,9 @@ class ServiceHandler(plugins.Plugin): dsize, new_end = self.apply_compensations(order, only_beyond=True) cprice += dsize*price if cprice: - discounts = (('compensation', -cprice),) + discounts = ( + ('compensation', -cprice), + ) if new_end: size = self.get_price_size(order.new_billed_until, new_end) price += price*size @@ -386,7 +388,9 @@ class ServiceHandler(plugins.Plugin): discounts = () dsize, new_end = self.apply_compensations(order) if dsize: - discounts=(('compensation', -dsize*price),) + discounts=( + ('compensation', -dsize*price), + ) if new_end: order.new_billed_until = new_end end = new_end diff --git a/orchestra/apps/services/tests/test_handler.py b/orchestra/apps/services/tests/test_handler.py index eb22246b..827351a6 100644 --- a/orchestra/apps/services/tests/test_handler.py +++ b/orchestra/apps/services/tests/test_handler.py @@ -326,7 +326,7 @@ class HandlerTests(BaseTestCase): rates = [ {'price': decimal.Decimal('0.00'), 'quantity': 2}, {'price': decimal.Decimal('9.00'), 'quantity': 28}, - ] + ] for rate, result in zip(rates, results): self.assertEqual(rate['price'], result.price) self.assertEqual(rate['quantity'], result.quantity) @@ -337,7 +337,7 @@ class HandlerTests(BaseTestCase): rates = [ {'price': decimal.Decimal('0.00'), 'quantity': 4}, {'price': decimal.Decimal('9.00'), 'quantity': 26}, - ] + ] for rate, result in zip(rates, results): self.assertEqual(rate['price'], result.price) self.assertEqual(rate['quantity'], result.quantity) @@ -348,7 +348,7 @@ class HandlerTests(BaseTestCase): rates = [ {'price': decimal.Decimal('0.00'), 'quantity': 6}, {'price': decimal.Decimal('9.00'), 'quantity': 24}, - ] + ] for rate, result in zip(rates, results): self.assertEqual(rate['price'], result.price) self.assertEqual(rate['quantity'], result.quantity) @@ -366,3 +366,6 @@ class HandlerTests(BaseTestCase): lines = service.handler.generate_bill_lines(orders, account, commit=False) print lines print len(lines) + # TODO + + # TODO test incomplete rate 1 -> nominal_price 10 -> rate diff --git a/orchestra/apps/websites/backends/apache.py b/orchestra/apps/websites/backends/apache.py index 3c770e95..9fd7303b 100644 --- a/orchestra/apps/websites/backends/apache.py +++ b/orchestra/apps/websites/backends/apache.py @@ -13,7 +13,9 @@ from .. import settings class Apache2Backend(ServiceController): model = 'websites.Website' - related_models = (('websites.Content', 'website'),) + related_models = ( + ('websites.Content', 'website'), + ) verbose_name = _("Apache 2") def save(self, site): diff --git a/orchestra/bin/orchestra-admin b/orchestra/bin/orchestra-admin index 41096e69..9b4c44dc 100755 --- a/orchestra/bin/orchestra-admin +++ b/orchestra/bin/orchestra-admin @@ -82,7 +82,7 @@ export -f get_orchestra_dir function print_install_requirements_help () { - cat <<- EOF + cat <<- EOF ${bold}NAME${normal} ${bold}orchetsra-admin install_requirements${normal} - Installs all Orchestra requirements using apt-get and pip @@ -157,7 +157,8 @@ function install_requirements () { iceweasel" PIP="${PIP} \ selenium \ - xvfbwrapper" + xvfbwrapper \ + freezegun" fi # Make sure locales are in place before installing postgres @@ -253,6 +254,7 @@ function print_install_certificate_help () { EOF } + function install_certificate () { opts=$(getopt -o h -l help -- "$@") || exit 1 set -- $opts @@ -311,7 +313,6 @@ function uninstall_certificate () { export -f uninstall_certificate - function print_install_postfix_help () { cat <<- EOF @@ -329,7 +330,7 @@ function print_install_postfix_help () { function install_postfix () { opts=$(getopt -o h -l help -- "$@") || exit 1 set -- $opts - + while [ $# -gt 0 ]; do case $1 in -h|--help) print_deploy_help; exit 0 ;; @@ -364,6 +365,7 @@ function install_postfix () { } export -f install_postfix + function print_uninstall_postfix_help () { cat <<- EOF