def build_preview_invoice_pdf(event): locale = event.settings.invoice_language if not locale or locale == '__user__': locale = event.settings.locale with rolledback_transaction(), language(locale): order = event.orders.create(status=Order.STATUS_PENDING, datetime=timezone.now(), expires=timezone.now(), code="PREVIEW", total=119) invoice = Invoice( order=order, event=event, invoice_no="PREVIEW", date=timezone.now().date(), locale=locale, organizer=event.organizer ) invoice.invoice_from = event.settings.get('invoice_address_from') introductory = event.settings.get('invoice_introductory_text', as_type=LazyI18nString) additional = event.settings.get('invoice_additional_text', as_type=LazyI18nString) footer = event.settings.get('invoice_footer_text', as_type=LazyI18nString) payment = _("A payment provider specific text might appear here.") invoice.introductory_text = str(introductory).replace('\n', '<br />') invoice.additional_text = str(additional).replace('\n', '<br />') invoice.footer_text = str(footer) invoice.payment_provider_text = str(payment).replace('\n', '<br />') invoice.invoice_to = _("John Doe\n214th Example Street\n012345 Somecity") invoice.file = None invoice.save() invoice.lines.all().delete() InvoiceLine.objects.create( invoice=invoice, description=_("Sample product A"), gross_value=119, tax_value=19, tax_rate=19 ) return event.invoice_renderer.generate(invoice)
def build_preview_invoice_pdf(event): locale = event.settings.invoice_language if not locale or locale == '__user__': locale = event.settings.locale with rolledback_transaction(), language(locale): order = event.orders.create(status=Order.STATUS_PENDING, datetime=timezone.now(), expires=timezone.now(), code="PREVIEW", total=119) invoice = Invoice( order=order, event=event, invoice_no="PREVIEW", date=timezone.now().date(), locale=locale, organizer=event.organizer ) invoice.invoice_from = event.settings.get('invoice_address_from') invoice.invoice_from_name = invoice.event.settings.get('invoice_address_from_name') invoice.invoice_from_zipcode = invoice.event.settings.get('invoice_address_from_zipcode') invoice.invoice_from_city = invoice.event.settings.get('invoice_address_from_city') invoice.invoice_from_country = invoice.event.settings.get('invoice_address_from_country') invoice.invoice_from_tax_id = invoice.event.settings.get('invoice_address_from_tax_id') invoice.invoice_from_vat_id = invoice.event.settings.get('invoice_address_from_vat_id') introductory = event.settings.get('invoice_introductory_text', as_type=LazyI18nString) additional = event.settings.get('invoice_additional_text', as_type=LazyI18nString) footer = event.settings.get('invoice_footer_text', as_type=LazyI18nString) payment = _("A payment provider specific text might appear here.") invoice.introductory_text = str(introductory).replace('\n', '<br />') invoice.additional_text = str(additional).replace('\n', '<br />') invoice.footer_text = str(footer) invoice.payment_provider_text = str(payment).replace('\n', '<br />') invoice.invoice_to_name = _("John Doe") invoice.invoice_to_street = _("214th Example Street") invoice.invoice_to_zipcode = _("012345") invoice.invoice_to_city = _('Sample city') invoice.invoice_to_country = Country('DE') invoice.invoice_to = '{}\n{}\n{} {}'.format( invoice.invoice_to_name, invoice.invoice_to_street, invoice.invoice_to_zipcode, invoice.invoice_to_city ) invoice.invoice_to_beneficiary = '' invoice.file = None invoice.save() invoice.lines.all().delete() if event.tax_rules.exists(): for i, tr in enumerate(event.tax_rules.all()): tax = tr.tax(Decimal('100.00')) InvoiceLine.objects.create( invoice=invoice, description=_("Sample product {}").format(i + 1), gross_value=tax.gross, tax_value=tax.tax, tax_rate=tax.rate ) else: InvoiceLine.objects.create( invoice=invoice, description=_("Sample product A"), gross_value=100, tax_value=0, tax_rate=0 ) return event.invoice_renderer.generate(invoice)
def build_preview_invoice_pdf(event): locale = event.settings.invoice_language if not locale or locale == '__user__': locale = event.settings.locale with rolledback_transaction(), language(locale): order = event.orders.create(status=Order.STATUS_PENDING, datetime=timezone.now(), expires=timezone.now(), code="PREVIEW", total=119) invoice = Invoice( order=order, event=event, invoice_no="PREVIEW", date=timezone.now().date(), locale=locale, organizer=event.organizer ) invoice.invoice_from = event.settings.get('invoice_address_from') invoice.invoice_from_name = invoice.event.settings.get('invoice_address_from_name') invoice.invoice_from_zipcode = invoice.event.settings.get('invoice_address_from_zipcode') invoice.invoice_from_city = invoice.event.settings.get('invoice_address_from_city') invoice.invoice_from_country = invoice.event.settings.get('invoice_address_from_country') invoice.invoice_from_tax_id = invoice.event.settings.get('invoice_address_from_tax_id') invoice.invoice_from_vat_id = invoice.event.settings.get('invoice_address_from_vat_id') introductory = event.settings.get('invoice_introductory_text', as_type=LazyI18nString) additional = event.settings.get('invoice_additional_text', as_type=LazyI18nString) footer = event.settings.get('invoice_footer_text', as_type=LazyI18nString) payment = _("A payment provider specific text might appear here.") invoice.introductory_text = str(introductory).replace('\n', '<br />') invoice.additional_text = str(additional).replace('\n', '<br />') invoice.footer_text = str(footer) invoice.payment_provider_text = str(payment).replace('\n', '<br />') invoice.invoice_to_name = _("John Doe") invoice.invoice_to_street = _("214th Example Street") invoice.invoice_to_zipcode = _("012345") invoice.invoice_to_city = _('Sample city') invoice.invoice_to_country = Country('DE') invoice.invoice_to = '{}\n{}\n{} {}'.format( invoice.invoice_to_name, invoice.invoice_to_street, invoice.invoice_to_zipcode, invoice.invoice_to_city ) invoice.invoice_to_beneficiary = '' invoice.file = None invoice.save() invoice.lines.all().delete() if event.tax_rules.exists(): for i, tr in enumerate(event.tax_rules.all()): tax = tr.tax(Decimal('100.00')) InvoiceLine.objects.create( invoice=invoice, description=_("Sample product {}").format(i + 1), gross_value=tax.gross, tax_value=tax.tax, tax_rate=tax.rate ) else: InvoiceLine.objects.create( invoice=invoice, description=_("Sample product A"), gross_value=100, tax_value=0, tax_rate=0 ) return event.invoice_renderer.generate(invoice)
def build_invoice(invoice: Invoice) -> Invoice: with language(invoice.locale): responses = register_payment_providers.send(invoice.event) for receiver, response in responses: provider = response(invoice.event) if provider.identifier == invoice.order.payment_provider: payment_provider = provider break invoice.invoice_from = invoice.event.settings.get('invoice_address_from') introductory = invoice.event.settings.get('invoice_introductory_text', as_type=LazyI18nString) additional = invoice.event.settings.get('invoice_additional_text', as_type=LazyI18nString) footer = invoice.event.settings.get('invoice_footer_text', as_type=LazyI18nString) payment = payment_provider.render_invoice_text(invoice.order) invoice.introductory_text = str(introductory).replace('\n', '<br />') invoice.additional_text = str(additional).replace('\n', '<br />') invoice.footer_text = str(footer) invoice.payment_provider_text = str(payment).replace('\n', '<br />') try: addr_template = pgettext("invoice", """{i.company} {i.name} {i.street} {i.zipcode} {i.city} {i.country}""") invoice.invoice_to = addr_template.format(i=invoice.order.invoice_address).strip() if invoice.order.invoice_address.vat_id: invoice.invoice_to += "\n" + pgettext("invoice", "VAT-ID: %s") % invoice.order.invoice_address.vat_id except InvoiceAddress.DoesNotExist: invoice.invoice_to = "" invoice.file = None invoice.save() invoice.lines.all().delete() for p in invoice.order.positions.all(): desc = str(p.item.name) if p.variation: desc += " - " + str(p.variation.value) InvoiceLine.objects.create( invoice=invoice, description=desc, gross_value=p.price, tax_value=p.tax_value, tax_rate=p.tax_rate ) if invoice.order.payment_fee: InvoiceLine.objects.create( invoice=invoice, description=_('Payment via {method}').format(method=str(payment_provider.verbose_name)), gross_value=invoice.order.payment_fee, tax_value=invoice.order.payment_fee_tax_value, tax_rate=invoice.order.payment_fee_tax_rate ) return invoice
def build_invoice(invoice: Invoice) -> Invoice: with language(invoice.locale): responses = register_payment_providers.send(invoice.event) for receiver, response in responses: provider = response(invoice.event) if provider.identifier == invoice.order.payment_provider: payment_provider = provider break invoice.invoice_from = invoice.event.settings.get('invoice_address_from') introductory = invoice.event.settings.get('invoice_introductory_text', as_type=LazyI18nString) additional = invoice.event.settings.get('invoice_additional_text', as_type=LazyI18nString) footer = invoice.event.settings.get('invoice_footer_text', as_type=LazyI18nString) payment = payment_provider.render_invoice_text(invoice.order) invoice.introductory_text = str(introductory).replace('\n', '<br />') invoice.additional_text = str(additional).replace('\n', '<br />') invoice.footer_text = str(footer) invoice.payment_provider_text = str(payment).replace('\n', '<br />') try: addr_template = pgettext("invoice", """{i.company} {i.name} {i.street} {i.zipcode} {i.city} {i.country}""") invoice.invoice_to = addr_template.format(i=invoice.order.invoice_address).strip() if invoice.order.invoice_address.vat_id: invoice.invoice_to += "\n" + pgettext("invoice", "VAT-ID: %s") % invoice.order.invoice_address.vat_id except InvoiceAddress.DoesNotExist: invoice.invoice_to = "" invoice.file = None invoice.save() invoice.lines.all().delete() for p in invoice.order.positions.all(): desc = str(p.item.name) if p.variation: desc += " - " + str(p.variation.value) InvoiceLine.objects.create( invoice=invoice, description=desc, gross_value=p.price, tax_value=p.tax_value, tax_rate=p.tax_rate ) if invoice.order.payment_fee: InvoiceLine.objects.create( invoice=invoice, description=_('Payment via {method}').format(method=str(payment_provider.verbose_name)), gross_value=invoice.order.payment_fee, tax_value=invoice.order.payment_fee_tax_value, tax_rate=invoice.order.payment_fee_tax_rate ) return invoice
def build_preview_invoice_pdf(event): locale = event.settings.invoice_language if not locale or locale == '__user__': locale = event.settings.locale with rolledback_transaction(), language(locale): order = event.orders.create(status=Order.STATUS_PENDING, datetime=now(), expires=now(), code="PREVIEW", total=119) invoice = Invoice( order=order, event=event, invoice_no="PREVIEW", date=date.today(), locale=locale ) invoice.invoice_from = event.settings.get('invoice_address_from') introductory = event.settings.get('invoice_introductory_text', as_type=LazyI18nString) additional = event.settings.get('invoice_additional_text', as_type=LazyI18nString) footer = event.settings.get('invoice_footer_text', as_type=LazyI18nString) payment = _("A payment provider specific text might appear here.") invoice.introductory_text = str(introductory).replace('\n', '<br />') invoice.additional_text = str(additional).replace('\n', '<br />') invoice.footer_text = str(footer) invoice.payment_provider_text = str(payment).replace('\n', '<br />') invoice.invoice_to = _("John Doe\n214th Example Street\n012345 Somecity") invoice.file = None invoice.save() invoice.lines.all().delete() InvoiceLine.objects.create( invoice=invoice, description=_("Sample product A"), gross_value=119, tax_value=19, tax_rate=19 ) with tempfile.NamedTemporaryFile(suffix=".pdf") as f: _invoice_generate_german(invoice, f) f.seek(0) return f.read()
def build_invoice(invoice: Invoice) -> Invoice: lp = invoice.order.payments.last() with language(invoice.locale): invoice.invoice_from = invoice.event.settings.get( 'invoice_address_from') invoice.invoice_from_name = invoice.event.settings.get( 'invoice_address_from_name') invoice.invoice_from_zipcode = invoice.event.settings.get( 'invoice_address_from_zipcode') invoice.invoice_from_city = invoice.event.settings.get( 'invoice_address_from_city') invoice.invoice_from_country = invoice.event.settings.get( 'invoice_address_from_country') invoice.invoice_from_tax_id = invoice.event.settings.get( 'invoice_address_from_tax_id') invoice.invoice_from_vat_id = invoice.event.settings.get( 'invoice_address_from_vat_id') introductory = invoice.event.settings.get('invoice_introductory_text', as_type=LazyI18nString) additional = invoice.event.settings.get('invoice_additional_text', as_type=LazyI18nString) footer = invoice.event.settings.get('invoice_footer_text', as_type=LazyI18nString) if lp and lp.payment_provider: if 'payment' in inspect.signature( lp.payment_provider.render_invoice_text).parameters: payment = lp.payment_provider.render_invoice_text( invoice.order, lp) else: payment = lp.payment_provider.render_invoice_text( invoice.order) else: payment = "" invoice.introductory_text = str(introductory).replace('\n', '<br />') invoice.additional_text = str(additional).replace('\n', '<br />') invoice.footer_text = str(footer) invoice.payment_provider_text = str(payment).replace('\n', '<br />') try: ia = invoice.order.invoice_address addr_template = pgettext( "invoice", """{i.company} {i.name} {i.street} {i.zipcode} {i.city} {state} {country}""") invoice.invoice_to = "\n".join( a.strip() for a in addr_template.format( i=ia, country=ia.country.name if ia.country else ia.country_old, state=ia.state_for_address).split("\n") if a.strip()) invoice.internal_reference = ia.internal_reference invoice.invoice_to_company = ia.company invoice.invoice_to_name = ia.name invoice.invoice_to_street = ia.street invoice.invoice_to_zipcode = ia.zipcode invoice.invoice_to_city = ia.city invoice.invoice_to_country = ia.country invoice.invoice_to_state = ia.state invoice.invoice_to_beneficiary = ia.beneficiary if ia.vat_id: invoice.invoice_to += "\n" + pgettext("invoice", "VAT-ID: %s") % ia.vat_id invoice.invoice_to_vat_id = ia.vat_id cc = str(ia.country) if cc in EU_CURRENCIES and EU_CURRENCIES[ cc] != invoice.event.currency: invoice.foreign_currency_display = EU_CURRENCIES[cc] if settings.FETCH_ECB_RATES: gs = GlobalSettingsObject() rates_date = gs.settings.get('ecb_rates_date', as_type=date) rates_dict = gs.settings.get('ecb_rates_dict', as_type=dict) convert = (rates_date and rates_dict and rates_date > (now() - timedelta(days=7)).date() and invoice.event.currency in rates_dict and invoice.foreign_currency_display in rates_dict) if convert: invoice.foreign_currency_rate = ( Decimal( rates_dict[invoice.foreign_currency_display]) / Decimal( rates_dict[invoice.event.currency])).quantize( Decimal('0.0001'), ROUND_HALF_UP) invoice.foreign_currency_rate_date = rates_date except InvoiceAddress.DoesNotExist: ia = None invoice.invoice_to = "" invoice.file = None invoice.save() invoice.lines.all().delete() positions = list( invoice.order.positions.select_related( 'addon_to', 'item', 'tax_rule', 'subevent', 'variation').annotate( addon_c=Count('addons')).prefetch_related( 'answers', 'answers__question').order_by('positionid', 'id')) reverse_charge = False positions.sort(key=lambda p: p.sort_key) for i, p in enumerate(positions): if not invoice.event.settings.invoice_include_free and p.price == Decimal( '0.00') and not p.addon_c: continue desc = str(p.item.name) if p.variation: desc += " - " + str(p.variation.value) if p.addon_to_id: desc = " + " + desc if invoice.event.settings.invoice_attendee_name and p.attendee_name: desc += "<br />" + pgettext( "invoice", "Attendee: {name}").format(name=p.attendee_name) for answ in p.answers.all(): if not answ.question.print_on_invoice: continue desc += "<br />{}{} {}".format( answ.question.question, "" if str(answ.question.question).endswith("?") else ":", str(answ)) if invoice.event.has_subevents: desc += "<br />" + pgettext("subevent", "Date: {}").format( p.subevent) InvoiceLine.objects.create( position=i, invoice=invoice, description=desc, gross_value=p.price, tax_value=p.tax_value, subevent=p.subevent, event_date_from=(p.subevent.date_from if p.subevent else invoice.event.date_from), tax_rate=p.tax_rate, tax_name=p.tax_rule.name if p.tax_rule else '') if p.tax_rule and p.tax_rule.is_reverse_charge( ia) and p.price and not p.tax_value: reverse_charge = True if reverse_charge: if invoice.additional_text: invoice.additional_text += "<br /><br />" invoice.additional_text += pgettext( "invoice", "Reverse Charge: According to Article 194, 196 of Council Directive 2006/112/EEC, VAT liability " "rests with the service recipient.") invoice.reverse_charge = True invoice.save() offset = len(positions) for i, fee in enumerate(invoice.order.fees.all()): fee_title = _(fee.get_fee_type_display()) if fee.description: fee_title += " - " + fee.description InvoiceLine.objects.create( position=i + offset, invoice=invoice, description=fee_title, gross_value=fee.value, tax_value=fee.tax_value, tax_rate=fee.tax_rate, tax_name=fee.tax_rule.name if fee.tax_rule else '') return invoice
def build_invoice(invoice: Invoice) -> Invoice: with language(invoice.locale): payment_provider = invoice.event.get_payment_providers().get( invoice.order.payment_provider) invoice.invoice_from = invoice.event.settings.get( 'invoice_address_from') introductory = invoice.event.settings.get('invoice_introductory_text', as_type=LazyI18nString) additional = invoice.event.settings.get('invoice_additional_text', as_type=LazyI18nString) footer = invoice.event.settings.get('invoice_footer_text', as_type=LazyI18nString) payment = payment_provider.render_invoice_text(invoice.order) invoice.introductory_text = str(introductory).replace('\n', '<br />') invoice.additional_text = str(additional).replace('\n', '<br />') invoice.footer_text = str(footer) invoice.payment_provider_text = str(payment).replace('\n', '<br />') try: ia = invoice.order.invoice_address addr_template = pgettext( "invoice", """{i.company} {i.name} {i.street} {i.zipcode} {i.city} {country}""") invoice.invoice_to = addr_template.format( i=ia, country=ia.country.name if ia.country else ia.country_old).strip() invoice.internal_reference = ia.internal_reference if ia.vat_id: invoice.invoice_to += "\n" + pgettext("invoice", "VAT-ID: %s") % ia.vat_id cc = str(ia.country) if cc in EU_CURRENCIES and EU_CURRENCIES[ cc] != invoice.event.currency: invoice.foreign_currency_display = EU_CURRENCIES[cc] if settings.FETCH_ECB_RATES: gs = GlobalSettingsObject() rates_date = gs.settings.get('ecb_rates_date', as_type=date) rates_dict = gs.settings.get('ecb_rates_dict', as_type=dict) convert = (rates_date and rates_dict and rates_date > (now() - timedelta(days=7)).date() and invoice.event.currency in rates_dict and invoice.foreign_currency_display in rates_dict) if convert: invoice.foreign_currency_rate = ( Decimal( rates_dict[invoice.foreign_currency_display]) / Decimal( rates_dict[invoice.event.currency])).quantize( Decimal('0.0001'), ROUND_HALF_UP) invoice.foreign_currency_rate_date = rates_date except InvoiceAddress.DoesNotExist: ia = None invoice.invoice_to = "" invoice.file = None invoice.save() invoice.lines.all().delete() positions = list( invoice.order.positions.select_related( 'addon_to', 'item', 'tax_rule', 'variation').annotate(addon_c=Count('addons'))) reverse_charge = False positions.sort(key=lambda p: p.sort_key) for i, p in enumerate(positions): if not invoice.event.settings.invoice_include_free and p.price == Decimal( '0.00') and not p.addon_c: continue desc = str(p.item.name) if p.variation: desc += " - " + str(p.variation.value) if p.addon_to_id: desc = " + " + desc InvoiceLine.objects.create( position=i, invoice=invoice, description=desc, gross_value=p.price, tax_value=p.tax_value, tax_rate=p.tax_rate, tax_name=p.tax_rule.name if p.tax_rule else '') if p.tax_rule and p.tax_rule.is_reverse_charge( ia) and p.price and not p.tax_value: reverse_charge = True if reverse_charge: if invoice.additional_text: invoice.additional_text += "<br /><br />" invoice.additional_text += pgettext( "invoice", "Reverse Charge: According to Article 194, 196 of Council Directive 2006/112/EEC, VAT liability " "rests with the service recipient.") invoice.save() offset = len(positions) for i, fee in enumerate(invoice.order.fees.all()): fee_title = _(fee.get_fee_type_display()) if fee.description: fee_title += " - " + fee.description InvoiceLine.objects.create( position=i + offset, invoice=invoice, description=fee_title, gross_value=fee.value, tax_value=fee.tax_value, tax_rate=fee.tax_rate, tax_name=fee.tax_rule.name if fee.tax_rule else '') return invoice
def build_invoice(invoice: Invoice) -> Invoice: with language(invoice.locale): payment_provider = invoice.event.get_payment_providers().get( invoice.order.payment_provider) invoice.invoice_from = invoice.event.settings.get( 'invoice_address_from') introductory = invoice.event.settings.get('invoice_introductory_text', as_type=LazyI18nString) additional = invoice.event.settings.get('invoice_additional_text', as_type=LazyI18nString) footer = invoice.event.settings.get('invoice_footer_text', as_type=LazyI18nString) payment = payment_provider.render_invoice_text(invoice.order) invoice.introductory_text = str(introductory).replace('\n', '<br />') invoice.additional_text = str(additional).replace('\n', '<br />') invoice.footer_text = str(footer) invoice.payment_provider_text = str(payment).replace('\n', '<br />') try: addr_template = pgettext( "invoice", """{i.company} {i.name} {i.street} {i.zipcode} {i.city} {country}""") invoice.invoice_to = addr_template.format( i=invoice.order.invoice_address, country=invoice.order.invoice_address.country.name if invoice.order.invoice_address.country else invoice.order.invoice_address.country_old).strip() if invoice.order.invoice_address.vat_id: invoice.invoice_to += "\n" + pgettext( "invoice", "VAT-ID: %s") % invoice.order.invoice_address.vat_id except InvoiceAddress.DoesNotExist: invoice.invoice_to = "" invoice.file = None invoice.save() invoice.lines.all().delete() positions = list( invoice.order.positions.select_related( 'addon_to', 'item', 'variation').annotate(addon_c=Count('addons'))) positions.sort(key=lambda p: p.sort_key) for p in positions: if not invoice.event.settings.invoice_include_free and p.price == Decimal( '0.00') and not p.addon_c: continue desc = str(p.item.name) if p.variation: desc += " - " + str(p.variation.value) if p.addon_to_id: desc = " + " + desc InvoiceLine.objects.create(invoice=invoice, description=desc, gross_value=p.price, tax_value=p.tax_value, tax_rate=p.tax_rate) if invoice.order.payment_fee: InvoiceLine.objects.create( invoice=invoice, description=_('Payment via {method}').format( method=str(payment_provider.verbose_name)), gross_value=invoice.order.payment_fee, tax_value=invoice.order.payment_fee_tax_value, tax_rate=invoice.order.payment_fee_tax_rate) return invoice
def build_invoice(invoice: Invoice) -> Invoice: invoice.locale = invoice.event.settings.get('invoice_language', invoice.event.settings.locale) if invoice.locale == '__user__': invoice.locale = invoice.order.locale or invoice.event.settings.locale lp = invoice.order.payments.last() with language(invoice.locale, invoice.event.settings.region): invoice.invoice_from = invoice.event.settings.get( 'invoice_address_from') invoice.invoice_from_name = invoice.event.settings.get( 'invoice_address_from_name') invoice.invoice_from_zipcode = invoice.event.settings.get( 'invoice_address_from_zipcode') invoice.invoice_from_city = invoice.event.settings.get( 'invoice_address_from_city') invoice.invoice_from_country = invoice.event.settings.get( 'invoice_address_from_country') invoice.invoice_from_tax_id = invoice.event.settings.get( 'invoice_address_from_tax_id') invoice.invoice_from_vat_id = invoice.event.settings.get( 'invoice_address_from_vat_id') introductory = invoice.event.settings.get('invoice_introductory_text', as_type=LazyI18nString) additional = invoice.event.settings.get('invoice_additional_text', as_type=LazyI18nString) footer = invoice.event.settings.get('invoice_footer_text', as_type=LazyI18nString) if lp and lp.payment_provider: if 'payment' in inspect.signature( lp.payment_provider.render_invoice_text).parameters: payment = str( lp.payment_provider.render_invoice_text(invoice.order, lp)) else: payment = str( lp.payment_provider.render_invoice_text(invoice.order)) else: payment = "" if invoice.event.settings.invoice_include_expire_date and invoice.order.status == Order.STATUS_PENDING: if payment: payment += "<br />" payment += pgettext( "invoice", "Please complete your payment before {expire_date}.").format( expire_date=date_format(invoice.order.expires, "SHORT_DATE_FORMAT")) invoice.introductory_text = str(introductory).replace('\n', '<br />') invoice.additional_text = str(additional).replace('\n', '<br />') invoice.footer_text = str(footer) invoice.payment_provider_text = str(payment).replace('\n', '<br />') try: ia = invoice.order.invoice_address addr_template = pgettext( "invoice", """{i.company} {i.name} {i.street} {i.zipcode} {i.city} {state} {country}""") invoice.invoice_to = "\n".join( a.strip() for a in addr_template.format( i=ia, country=ia.country.name if ia.country else ia.country_old, state=ia.state_for_address).split("\n") if a.strip()) invoice.internal_reference = ia.internal_reference invoice.custom_field = ia.custom_field invoice.invoice_to_company = ia.company invoice.invoice_to_name = ia.name invoice.invoice_to_street = ia.street invoice.invoice_to_zipcode = ia.zipcode invoice.invoice_to_city = ia.city invoice.invoice_to_country = ia.country invoice.invoice_to_state = ia.state invoice.invoice_to_beneficiary = ia.beneficiary if ia.vat_id: invoice.invoice_to += "\n" + pgettext("invoice", "VAT-ID: %s") % ia.vat_id invoice.invoice_to_vat_id = ia.vat_id cc = str(ia.country) if cc in EU_CURRENCIES and EU_CURRENCIES[ cc] != invoice.event.currency and invoice.event.settings.invoice_eu_currencies: invoice.foreign_currency_display = EU_CURRENCIES[cc] if settings.FETCH_ECB_RATES: gs = GlobalSettingsObject() rates_date = gs.settings.get('ecb_rates_date', as_type=date) rates_dict = gs.settings.get('ecb_rates_dict', as_type=dict) convert = (rates_date and rates_dict and rates_date > (now() - timedelta(days=7)).date() and invoice.event.currency in rates_dict and invoice.foreign_currency_display in rates_dict) if convert: invoice.foreign_currency_rate = ( Decimal( rates_dict[invoice.foreign_currency_display]) / Decimal( rates_dict[invoice.event.currency])).quantize( Decimal('0.0001'), ROUND_HALF_UP) invoice.foreign_currency_rate_date = rates_date except InvoiceAddress.DoesNotExist: ia = None invoice.invoice_to = "" invoice.file = None invoice.save() invoice.lines.all().delete() positions = list( invoice.order.positions.select_related( 'addon_to', 'item', 'tax_rule', 'subevent', 'variation').annotate( addon_c=Count('addons')).prefetch_related( 'answers', 'answers__question').order_by('positionid', 'id')) reverse_charge = False positions.sort(key=lambda p: p.sort_key) tax_texts = [] for i, p in enumerate(positions): if not invoice.event.settings.invoice_include_free and p.price == Decimal( '0.00') and not p.addon_c: continue desc = str(p.item.name) if p.variation: desc += " - " + str(p.variation.value) if p.addon_to_id: desc = " + " + desc if invoice.event.settings.invoice_attendee_name and p.attendee_name: desc += "<br />" + pgettext( "invoice", "Attendee: {name}").format(name=p.attendee_name) for recv, resp in invoice_line_text.send(sender=invoice.event, position=p): if resp: desc += "<br/>" + resp for answ in p.answers.all(): if not answ.question.print_on_invoice: continue desc += "<br />{}{} {}".format( answ.question.question, "" if str(answ.question.question).endswith("?") else ":", str(answ)) if invoice.event.has_subevents: desc += "<br />" + pgettext("subevent", "Date: {}").format( p.subevent) InvoiceLine.objects.create( position=i, invoice=invoice, description=desc, gross_value=p.price, tax_value=p.tax_value, subevent=p.subevent, item=p.item, variation=p.variation, attendee_name=p.attendee_name if invoice.event.settings.invoice_attendee_name else None, event_date_from=p.subevent.date_from if invoice.event.has_subevents else invoice.event.date_from, event_date_to=p.subevent.date_to if invoice.event.has_subevents else invoice.event.date_to, tax_rate=p.tax_rate, tax_name=p.tax_rule.name if p.tax_rule else '') if p.tax_rule and p.tax_rule.is_reverse_charge( ia) and p.price and not p.tax_value: reverse_charge = True if p.tax_rule: tax_text = p.tax_rule.invoice_text(ia) if tax_text and tax_text not in tax_texts: tax_texts.append(tax_text) offset = len(positions) for i, fee in enumerate(invoice.order.fees.all()): if fee.fee_type == OrderFee.FEE_TYPE_OTHER and fee.description: fee_title = fee.description else: fee_title = _(fee.get_fee_type_display()) if fee.description: fee_title += " - " + fee.description InvoiceLine.objects.create( position=i + offset, invoice=invoice, description=fee_title, gross_value=fee.value, event_date_from=None if invoice.event.has_subevents else invoice.event.date_from, event_date_to=None if invoice.event.has_subevents else invoice.event.date_to, tax_value=fee.tax_value, tax_rate=fee.tax_rate, tax_name=fee.tax_rule.name if fee.tax_rule else '') if fee.tax_rule and fee.tax_rule.is_reverse_charge( ia) and fee.value and not fee.tax_value: reverse_charge = True if fee.tax_rule: tax_text = fee.tax_rule.invoice_text(ia) if tax_text and tax_text not in tax_texts: tax_texts.append(tax_text) if tax_texts: invoice.additional_text += "<br /><br />" invoice.additional_text += "<br />".join(tax_texts) invoice.reverse_charge = reverse_charge invoice.save() return invoice
def build_invoice(invoice: Invoice) -> Invoice: lp = invoice.order.payments.last() open_payment = None if lp and lp.state not in (OrderPayment.PAYMENT_STATE_CONFIRMED, OrderPayment.PAYMENT_STATE_REFUNDED): open_payment = lp with language(invoice.locale): invoice.invoice_from = invoice.event.settings.get('invoice_address_from') invoice.invoice_from_name = invoice.event.settings.get('invoice_address_from_name') invoice.invoice_from_zipcode = invoice.event.settings.get('invoice_address_from_zipcode') invoice.invoice_from_city = invoice.event.settings.get('invoice_address_from_city') invoice.invoice_from_country = invoice.event.settings.get('invoice_address_from_country') invoice.invoice_from_tax_id = invoice.event.settings.get('invoice_address_from_tax_id') invoice.invoice_from_vat_id = invoice.event.settings.get('invoice_address_from_vat_id') introductory = invoice.event.settings.get('invoice_introductory_text', as_type=LazyI18nString) additional = invoice.event.settings.get('invoice_additional_text', as_type=LazyI18nString) footer = invoice.event.settings.get('invoice_footer_text', as_type=LazyI18nString) if open_payment and open_payment.payment_provider: payment = open_payment.payment_provider.render_invoice_text(invoice.order) elif invoice.order.status == Order.STATUS_PAID: payment = pgettext('invoice', 'The payment for this invoice has already been received.') else: payment = "" invoice.introductory_text = str(introductory).replace('\n', '<br />') invoice.additional_text = str(additional).replace('\n', '<br />') invoice.footer_text = str(footer) invoice.payment_provider_text = str(payment).replace('\n', '<br />') try: ia = invoice.order.invoice_address addr_template = pgettext("invoice", """{i.company} {i.name} {i.street} {i.zipcode} {i.city} {country}""") invoice.invoice_to = addr_template.format( i=ia, country=ia.country.name if ia.country else ia.country_old ).strip() invoice.internal_reference = ia.internal_reference invoice.invoice_to_company = ia.company invoice.invoice_to_name = ia.name invoice.invoice_to_street = ia.street invoice.invoice_to_zipcode = ia.zipcode invoice.invoice_to_city = ia.city invoice.invoice_to_country = ia.country invoice.invoice_to_beneficiary = ia.beneficiary if ia.vat_id: invoice.invoice_to += "\n" + pgettext("invoice", "VAT-ID: %s") % ia.vat_id invoice.invoice_to_vat_id = ia.vat_id cc = str(ia.country) if cc in EU_CURRENCIES and EU_CURRENCIES[cc] != invoice.event.currency: invoice.foreign_currency_display = EU_CURRENCIES[cc] if settings.FETCH_ECB_RATES: gs = GlobalSettingsObject() rates_date = gs.settings.get('ecb_rates_date', as_type=date) rates_dict = gs.settings.get('ecb_rates_dict', as_type=dict) convert = ( rates_date and rates_dict and rates_date > (now() - timedelta(days=7)).date() and invoice.event.currency in rates_dict and invoice.foreign_currency_display in rates_dict ) if convert: invoice.foreign_currency_rate = ( Decimal(rates_dict[invoice.foreign_currency_display]) / Decimal(rates_dict[invoice.event.currency]) ).quantize(Decimal('0.0001'), ROUND_HALF_UP) invoice.foreign_currency_rate_date = rates_date except InvoiceAddress.DoesNotExist: ia = None invoice.invoice_to = "" invoice.file = None invoice.save() invoice.lines.all().delete() positions = list( invoice.order.positions.select_related('addon_to', 'item', 'tax_rule', 'subevent', 'variation').annotate( addon_c=Count('addons') ).order_by('positionid', 'id') ) reverse_charge = False positions.sort(key=lambda p: p.sort_key) for i, p in enumerate(positions): if not invoice.event.settings.invoice_include_free and p.price == Decimal('0.00') and not p.addon_c: continue desc = str(p.item.name) if p.variation: desc += " - " + str(p.variation.value) if p.addon_to_id: desc = " + " + desc if invoice.event.settings.invoice_attendee_name and p.attendee_name: desc += "<br />" + pgettext("invoice", "Attendee: {name}").format(name=p.attendee_name) if invoice.event.has_subevents: desc += "<br />" + pgettext("subevent", "Date: {}").format(p.subevent) InvoiceLine.objects.create( position=i, invoice=invoice, description=desc, gross_value=p.price, tax_value=p.tax_value, subevent=p.subevent, event_date_from=(p.subevent.date_from if p.subevent else invoice.event.date_from), tax_rate=p.tax_rate, tax_name=p.tax_rule.name if p.tax_rule else '' ) if p.tax_rule and p.tax_rule.is_reverse_charge(ia) and p.price and not p.tax_value: reverse_charge = True if reverse_charge: if invoice.additional_text: invoice.additional_text += "<br /><br />" invoice.additional_text += pgettext( "invoice", "Reverse Charge: According to Article 194, 196 of Council Directive 2006/112/EEC, VAT liability " "rests with the service recipient." ) invoice.reverse_charge = True invoice.save() offset = len(positions) for i, fee in enumerate(invoice.order.fees.all()): fee_title = _(fee.get_fee_type_display()) if fee.description: fee_title += " - " + fee.description InvoiceLine.objects.create( position=i + offset, invoice=invoice, description=fee_title, gross_value=fee.value, tax_value=fee.tax_value, tax_rate=fee.tax_rate, tax_name=fee.tax_rule.name if fee.tax_rule else '' ) return invoice