def __init__(self, domain, date_start=None, date_end=None, contact_emails=None): self.date_start = date_start self.date_end = date_end self.contact_emails = contact_emails self.domain = ensure_domain_instance(domain) self.logged_throttle_error = False if self.domain is None: raise InvoiceError("Domain '{}' is not a valid domain on HQ!".format(self.domain))
def __init__(self, date_start, date_end, domain, recipients=None): """ The Invoice generated will always be for the month preceding the invoicing_date. For example, if today is July 5, 2014 then the invoice will be from June 1, 2014 to June 30, 2014. """ self.date_start = date_start self.date_end = date_end self.domain = ensure_domain_instance(domain) self.recipients = recipients self.logged_throttle_error = False if self.domain is None: raise InvoiceError("Domain '%s' is not a valid domain on HQ!" % domain)
def ensure_full_coverage(self, subscriptions): plan_version = DefaultProductPlan.get_default_plan_by_domain( self.domain, edition=SoftwarePlanEdition.COMMUNITY ).plan.get_version() if not plan_version.feature_charges_exist_for_domain(self.domain): return community_ranges = self.get_community_ranges(subscriptions) if not community_ranges: return do_not_invoice = any([s.do_not_invoice for s in subscriptions]) account = BillingAccount.get_or_create_account_by_domain( self.domain.name, created_by=self.__class__.__name__, created_by_invoicing=True)[0] if account.date_confirmed_extra_charges is None: logger.error( "[BILLING] " "Domain '%s' is going to get charged on " "Community, but they haven't formally acknowledged this. " "Someone on ops should reconcile this soon. To be on the " "safe side, we've marked the invoices as Do Not Invoice." % self.domain.name ) do_not_invoice = True if not BillingContactInfo.objects.filter(account=account).exists(): # No contact information exists for this account. # This shouldn't happen, but if it does, we can't continue # with the invoice generation. raise InvoiceError("No Billing Contact Info could be found " "for domain '%s'." % self.domain.name) # First check to make sure none of the existing subscriptions is set # to do not invoice. Let's be on the safe side and not send a # community invoice out, if that's the case. for c in community_ranges: # create a new community subscription for each # date range that the domain did not have a subscription community_subscription = Subscription( account=account, plan_version=plan_version, subscriber=self.subscriber, date_start=c[0], date_end=c[1], do_not_invoice=do_not_invoice, ) community_subscription.save() subscriptions.append(community_subscription)
def draw_table(self, items): origin_x = inches(0.5) origin_y = inches(6.72) self.canvas.translate(origin_x, origin_y) height = inches(0.725 * len(items)) description_x = inches(2.4) quantity_x = inches(3.15) rate_x = inches(3.9) subtotal_x = inches(5.1) credits_x = inches(6.0) total_x = inches(7.25) header_height = inches(0.3) self.canvas.rect(0, 0, total_x, -height) self.canvas.setFillColorRGB(*LIGHT_GRAY) self.canvas.rect(0, 0, total_x, header_height, fill=1) self.canvas.setFillColorRGB(*BLACK) self.canvas.line(description_x, header_height, description_x, -height) self.canvas.line(quantity_x, header_height, quantity_x, -height) self.canvas.line(rate_x, header_height, rate_x, -height) self.canvas.line(subtotal_x, header_height, subtotal_x, -height) self.canvas.line(credits_x, header_height, credits_x, -height) self.canvas.setFontSize(SMALL_FONT_SIZE) self.canvas.drawCentredString(midpoint(0, description_x), inches(0.1), "PRODUCT") self.canvas.drawCentredString(midpoint(description_x, quantity_x), inches(0.1), "QUANTITY") self.canvas.drawCentredString(midpoint(quantity_x, rate_x), inches(0.1), "UNIT COST") self.canvas.drawCentredString(midpoint(rate_x, subtotal_x), inches(0.1), "SUBTOTAL") self.canvas.drawCentredString(midpoint(subtotal_x, credits_x), inches(0.1), "CREDITS") self.canvas.drawCentredString(midpoint(credits_x, total_x), inches(0.1), "TOTAL") self.canvas.setFontSize(DEFAULT_FONT_SIZE) coord_y = 0 for item_index in range(len(items)): if coord_y < -height: raise InvoiceError("Cannot fit line items on invoice") item = items[item_index] description = Paragraph(item.description, ParagraphStyle('', fontSize=DEFAULT_FONT_SIZE, )) description.wrapOn(self.canvas, description_x - inches(0.2), -header_height) coord_y -= description.height + inches(0.05) description.drawOn(self.canvas, inches(0.1), coord_y) self.canvas.drawCentredString( midpoint(description_x, quantity_x), coord_y, str(item.quantity) ) self.canvas.drawCentredString( midpoint(quantity_x, rate_x), coord_y, get_money_str(item.unit_cost) ) self.canvas.drawCentredString( midpoint(rate_x, subtotal_x), coord_y, get_money_str(item.subtotal) ) self.canvas.drawCentredString( midpoint(subtotal_x, credits_x), coord_y, get_money_str(item.credits) ) self.canvas.drawCentredString( midpoint(credits_x, total_x), coord_y, get_money_str(item.total) ) coord_y -= inches(0.1) self.canvas.line(0, coord_y, total_x, coord_y) self.canvas.translate(-origin_x, -origin_y)
def draw_table(self): origin_x = inches(0.5) origin_y = inches(6.2) self.canvas.translate(origin_x, origin_y) height = inches(3.5) description_x = inches(2.4) quantity_x = inches(3.15) rate_x = inches(3.9) subtotal_x = inches(5.1) credits_x = inches(6.3) total_x = inches(7.5) header_height = inches(0.3) self.canvas.rect(0, 0, total_x, -height) self.canvas.setFillColorRGB(*LIGHT_GRAY) self.canvas.rect(0, 0, total_x, header_height, fill=1) self.canvas.setFillColorRGB(*BLACK) self.canvas.line(description_x, header_height, description_x, -height) self.canvas.line(quantity_x, header_height, quantity_x, -height) self.canvas.line(rate_x, header_height, rate_x, -height) self.canvas.line(subtotal_x, header_height, subtotal_x, -height) self.canvas.line(credits_x, header_height, credits_x, -height) self.canvas.drawCentredString(midpoint(0, description_x), inches(0.1), "Product") self.canvas.drawCentredString(midpoint(description_x, quantity_x), inches(0.1), "Quantity") self.canvas.drawCentredString(midpoint(quantity_x, rate_x), inches(0.1), "Unit Cost") self.canvas.drawCentredString(midpoint(rate_x, subtotal_x), inches(0.1), "Subtotal") self.canvas.drawCentredString(midpoint(subtotal_x, credits_x), inches(0.1), "Credits Applied") self.canvas.drawCentredString(midpoint(credits_x, total_x), inches(0.1), "Total") coord_y = 0 for item_index in range(len(self.items)): if coord_y < -height: raise InvoiceError("Cannot fit line items on invoice") item = self.items[item_index] description = Paragraph(item.description, ParagraphStyle( '', fontSize=12, )) description.wrapOn(self.canvas, description_x - inches(0.2), -header_height) coord_y -= description.height + inches(0.05) description.drawOn(self.canvas, inches(0.1), coord_y) self.canvas.drawCentredString(midpoint(description_x, quantity_x), coord_y, str(item.quantity)) self.canvas.drawCentredString(midpoint(quantity_x, rate_x), coord_y, get_money_str(item.unit_cost)) self.canvas.drawCentredString(midpoint(rate_x, subtotal_x), coord_y, get_money_str(item.subtotal)) self.canvas.drawCentredString(midpoint(subtotal_x, credits_x), coord_y, get_money_str(item.credits)) self.canvas.drawCentredString(midpoint(credits_x, total_x), coord_y, get_money_str(item.total)) coord_y -= inches(0.1) self.canvas.line(0, coord_y, total_x, coord_y) self.canvas.translate(-origin_x, -origin_y)