Esempio n. 1
0
def generate_monthly_bills(billing_range=None, domain_name=None):
    logging.info("[Billing] Generating Monthly Bills")
    from corehq.apps.domain.models import Domain
    if domain_name is not None:
        domains = [domain_name]
    else:
        domains = [domain['key'] for domain in Domain.get_all(include_docs=False)]
    for domain in domains:
        HQMonthlyBill.create_bill_for_domain(domain, billing_range=billing_range)
Esempio n. 2
0
    def get_billable_domains(cls):
        marked_domains = SMSBillable.get_db().view('hqbilling/domains_marked_for_billing', reduce=False).all()

        prev_month, _ = HQMonthlyBill.get_default_start_end()

        recent = SMSBillable.get_db().view('hqbilling/domains_with_billables',
                                           startkey=[prev_month.year, prev_month.month],
                                           group=True,
                                           group_level=3).all()
        
        recent_counts = defaultdict(int)
        for r in recent:
            recent_counts[r['key'][-1]] += r['value']
        for m in marked_domains:
            if m['key'] not in recent_counts.keys():
                recent_counts[m['key']] = 0

        all_time = SMSBillable.get_db().view('hqbilling/domains_with_billables',
                                             group=True,
                                             group_level=3).all()
        all_time_counts = defaultdict(int)
        for a in all_time:
            if a['key'][-1] not in recent_counts.keys():
                all_time_counts[a['key'][-1]] += a['value']

        sorted_recent = sorted(recent_counts.iteritems(), key=operator.itemgetter(1), reverse=True)
        sorted_all_time = sorted(all_time_counts.iteritems(), key=operator.itemgetter(1), reverse=True)

        return [Domain.get_by_name(r[0]) for r in sorted_recent if r[0]] + \
               [Domain.get_by_name(a[0]) for a in sorted_all_time if a[0]]
Esempio n. 3
0
 def testSMSBilling(self):
     generate_monthly_bills()
     last_bill = HQMonthlyBill.get_bills(self.domain.name).first()
     if last_bill:
         self.assertEqual(self.tropo_bill.total_billed, last_bill.incoming_sms_billed)
         self.assertEqual(self.unicel_bill.total_billed + self.mach_bill.total_billed, last_bill.outgoing_sms_billed)
     else:
         raise Exception("Monthly Bill not successfully generated.")
Esempio n. 4
0
    def rows(self):
        rows = []

        for domain in self.domains:
            all_bills = HQMonthlyBill.get_bills(domain.name,
                start=self.datespan.startdate_param_utc,
                end=self.datespan.enddate_param_utc
            ).all()
            for bill in all_bills:
                nice_start = bill.billing_period_start.strftime("%B %d, %Y")
                nice_end = bill.billing_period_end.strftime("%B %d, %Y")
                rows.append([
                    domain.name,
                    self._format_client(domain),
                    self.table_cell(
                        bill.billing_period_start,
                        nice_start
                    ),
                    self.table_cell(
                        bill.billing_period_end,
                        nice_end
                    ),
                    self._format_bill_amount(bill.incoming_sms_billed),
                    self._format_bill_amount(bill.outgoing_sms_billed),
                    self._format_bill_amount(bill.incoming_sms_billed+bill.outgoing_sms_billed),
                    bill.currency.currency_code,
                    self.table_cell(
                        int(bill.paid),
                        mark_safe(render_to_string("hqbilling/partials/paid_button.html", {
                            'payment_status': "yes" if bill.paid else "no",
                            'bill_id': bill.get_id,
                            'payment_status_text': "Paid" if bill.paid else "Not Paid",
                            'button_class': "btn-success paid" if bill.paid else "btn-danger",
                            'billing_start': nice_start,
                            'billing_end': nice_end,
                            'domain': domain.name,
                        }))
                    ),
                    mark_safe('<a href="%s" class="btn btn-primary">View Invoice</a>' %
                        reverse("billing_invoice", kwargs=dict(bill_id=bill.get_id))),
                    mark_safe('<a href="%s" class="btn"><i class="icon icon-list"></i> View Itemized</a>' %
                        reverse("billing_itemized", kwargs=dict(bill_id=bill.get_id)))
                ])

        return rows
Esempio n. 5
0
    def handle(self, *args, **options):
        if len(args) < 2:
            raise CommandError("year and month are required")

        if len(args) > 2:
            domains = [Domain.get_by_name(args[2])]
        else:
            domains = SelectSMSBillableDomainsFilter.get_billable_domains()

        first_day, last_day = month_span(int(args[0]), int(args[1]))
        print "\nRecalculating SMS in HQ Bills\n----\n"
        for domain in domains:
            bills_for_domain = HQMonthlyBill.get_bills(domain.name,
                start=first_day.isoformat(),
                end=last_day.isoformat()).all()
            print "Found %d SMS Bills for domain %s" % (len(bills_for_domain), domain.name)
            for bill in bills_for_domain:
                bill._get_sms_activities(INCOMING)
                bill._get_sms_activities(OUTGOING)
                bill.save()
                sys.stdout.flush()
            print "\n"
Esempio n. 6
0
 def default_datespan(self):
     start, end = HQMonthlyBill.get_default_start_end()
     datespan = DateSpan(start, end, format="%Y-%m-%d", timezone=self.timezone)
     datespan.is_default = True
     return datespan
Esempio n. 7
0
    def setUp(self):
        for domain in Domain.get_all():
            domain.delete()

        start_date, _ = HQMonthlyBill.get_default_start_end()
        sms_date = start_date + datetime.timedelta(days=7)

        all_billables = SMSBillable.get_all()
        # all_billables contains duplicates; only delete each doc once
        for b_id in set(b._id for b in all_billables):
            SMSBillable.get_db().delete_doc(b_id)

        self.domain = Domain()
        self.domain.name = "domain_with_sms"
        self.domain.is_active = True
        self.domain.date_created = sms_date
        self.domain.save()

        # Incoming billables

        self.tropo_bill = TropoSMSBillable()
        self.tropo_bill.billable_date = sms_date
        self.tropo_bill.billable_amount = 2
        self.tropo_bill.conversion_rate = 1
        self.tropo_bill.dimagi_surcharge = 0.002
        self.tropo_bill.rate_id = "INCOMING_RATE_TROPO"
        self.tropo_bill.log_id = "INCOMING_LOG_TROPO"
        self.tropo_bill.domain = self.domain.name
        self.tropo_bill.direction = INCOMING
        self.tropo_bill.phone_number = "+15551234567"
        self.tropo_bill.tropo_id = "TROPO_ID"
        self.tropo_bill.save()

        # Outgoing billables

        self.mach_bill = MachSMSBillable()
        self.mach_bill.billable_date = sms_date
        self.mach_bill.contacted_mach_api = sms_date
        self.mach_bill.mach_delivered_date = sms_date
        self.mach_bill.billable_amount = 0.01
        self.mach_bill.conversion_rate = 1.2
        self.mach_bill.dimagi_surcharge = 0.002
        self.mach_bill.rate_id = "OUTGOING_MACH_RATE"
        self.mach_bill.log_id = "OUTGOING_MACH_LOG"
        self.mach_bill.domain = self.domain.name
        self.mach_bill.direction = OUTGOING
        self.mach_bill.phone_number = "+15551234567"
        self.mach_bill.mach_delivery_status = "delivered"
        self.mach_bill.mach_id = "MACH_MESSAGE_ID"
        self.mach_bill.save()

        self.unicel_bill = UnicelSMSBillable()
        self.unicel_bill.billable_date = sms_date
        self.unicel_bill.billable_amount = 2
        self.unicel_bill.conversion_rate = 1
        self.unicel_bill.dimagi_surcharge = 0.002
        self.unicel_bill.rate_id = "OUTGOING_UNICEL_RATE"
        self.unicel_bill.log_id = "OUTGOING_UNICEL_LOG"
        self.unicel_bill.domain = self.domain.name
        self.unicel_bill.direction = OUTGOING
        self.unicel_bill.phone_number = "+15551234567"
        self.unicel_bill.unicel_id = "UNICEL_ID"
        self.unicel_bill.save()