<s> import os <EOL> import errno <EOL> import logging <EOL> from collections import OrderedDict <EOL> import requests <EOL> from django import forms <EOL> from django . contrib import messages <EOL> from django . contrib . admin import helpers , site , TabularInline , ModelAdmin <EOL> from django . contrib . admin . actions import delete_selected as delete_selected_ <EOL> from django . contrib . admin . models import LogEntry , CHANGE <EOL> from django . contrib . contenttypes . models import ContentType <EOL> from django . db import connections <EOL> from django . utils . html import escape <EOL> from django_fsm import TransitionNotAllowed <EOL> from django . core . urlresolvers import reverse <EOL> from django . utils . translation import ugettext_lazy as _ <EOL> from django . utils import timezone <EOL> from django . shortcuts import render <EOL> from django . http import HttpResponse <EOL> from PyPDF2 import PdfFileReader , PdfFileMerger <EOL> from models import ( Plan , MeteredFeature , Subscription , Customer , Provider , <EOL> MeteredFeatureUnitsLog , Invoice , DocumentEntry , <EOL> ProductCode , Proforma , BillingLog , BillingDocument ) <EOL> from documents_generator import DocumentsGenerator <EOL> logger = logging . getLogger ( __name__ ) <EOL> def metadata ( obj ) : <EOL> d = u'<STR_LIT>' <EOL> if obj . meta : <EOL> d = u'<STR_LIT>' <EOL> for key , value in obj . meta . iteritems ( ) : <EOL> d += u'<STR_LIT>' % ( escape ( key ) , escape ( value ) ) <EOL> return d <EOL> metadata . allow_tags = True <EOL> def tax ( obj ) : <EOL> return ( "<STR_LIT>" . format ( obj . sales_tax_name , obj . sales_tax_percent ) <EOL> if obj . sales_tax_percent > <NUM_LIT:0> else '<STR_LIT>' ) <EOL> tax . admin_order_field = '<STR_LIT>' <EOL> class LiveModelAdmin ( ModelAdmin ) : <EOL> def get_queryset ( self , request ) : <EOL> qs = self . model . all_objects . get_queryset ( ) <EOL> ordering = self . get_ordering ( request ) <EOL> if ordering : <EOL> qs = qs . order_by ( * ordering ) <EOL> return qs <EOL> def delete_model ( self , request , obj ) : <EOL> if '<STR_LIT>' in dir ( obj ) : <EOL> obj . hard_delete ( ) <EOL> else : <EOL> super ( LiveModelAdmin , self ) . delete_model ( request , obj ) <EOL> def delete_selected ( self , request , queryset ) : <EOL> if '<STR_LIT>' in dir ( queryset ) : <EOL> queryset . delete = queryset . hard_delete <EOL> return delete_selected_ ( self , request , queryset ) <EOL> delete_selected . short_description = _ ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> actions = [ '<STR_LIT>' ] <EOL> class PlanForm ( forms . ModelForm ) : <EOL> class Meta : <EOL> model = Plan <EOL> fields = ( '<STR_LIT>' , '<STR_LIT:name>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) <EOL> def clean ( self ) : <EOL> metered_features = self . cleaned_data . get ( '<STR_LIT>' ) <EOL> Plan . validate_metered_features ( metered_features ) <EOL> return self . cleaned_data <EOL> class PlanAdmin ( ModelAdmin ) : <EOL> list_display = [ '<STR_LIT:name>' , '<STR_LIT:description>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> search_fields = [ '<STR_LIT:name>' ] <EOL> list_filter = [ '<STR_LIT>' ] <EOL> form = PlanForm <EOL> def interval_display ( self , obj ) : <EOL> return ( '<STR_LIT>' . format ( obj . interval_count , obj . interval ) <EOL> if obj . interval_count != <NUM_LIT:1> <EOL> else '<STR_LIT>' . format ( obj . interval_count , obj . interval ) ) <EOL> interval_display . short_description = '<STR_LIT>' <EOL> def description ( self , obj ) : <EOL> d = u'<STR_LIT>' . format ( obj . amount , <EOL> obj . currency ) <EOL> fmt = u'<STR_LIT>' <EOL> for f in obj . metered_features . all ( ) : <EOL> d += fmt . format ( <EOL> name = f . name , <EOL> price = f . price_per_unit , <EOL> currency = obj . currency , <EOL> ) <EOL> if f . included_units > <NUM_LIT:0> : <EOL> d += u'<STR_LIT>' . format ( f . included_units ) <EOL> d += u'<STR_LIT>' <EOL> return d <EOL> description . allow_tags = True <EOL> class MeteredFeatureUnitsLogInLine ( TabularInline ) : <EOL> model = MeteredFeatureUnitsLog <EOL> list_display = [ '<STR_LIT>' ] <EOL> readonly_fields = ( '<STR_LIT>' , '<STR_LIT>' , ) <EOL> extra = <NUM_LIT:0> <EOL> def get_formset ( self , request , obj = None , ** kwargs ) : <EOL> self . parent_obj = obj <EOL> return super ( MeteredFeatureUnitsLogInLine , self ) . get_formset ( <EOL> request , obj , ** kwargs ) <EOL> def formfield_for_foreignkey ( self , db_field , request = None , ** kwargs ) : <EOL> if db_field . name == '<STR_LIT>' and hasattr ( self , '<STR_LIT>' ) : <EOL> if self . parent_obj : <EOL> kwargs [ '<STR_LIT>' ] = db_field . rel . to . objects . filter ( ** { <EOL> '<STR_LIT>' : self . parent_obj . plan <EOL> } ) <EOL> return super ( MeteredFeatureUnitsLogInLine , <EOL> self ) . formfield_for_foreignkey ( db_field , request , <EOL> ** kwargs ) <EOL> class BillingLogInLine ( TabularInline ) : <EOL> model = BillingLog <EOL> fields = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> readonly_fields = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> verbose_name = '<STR_LIT>' <EOL> verbose_name_plural = verbose_name <EOL> def has_add_permission ( self , request ) : <EOL> return False <EOL> def has_delete_permission ( self , request , obj = None ) : <EOL> return False <EOL> def invoice_link ( self , obj ) : <EOL> return obj . invoice . admin_change_url if obj . invoice else '<STR_LIT:None>' <EOL> invoice_link . short_description = '<STR_LIT>' <EOL> invoice_link . allow_tags = True <EOL> def proforma_link ( self , obj ) : <EOL> return obj . proforma . admin_change_url if obj . proforma else '<STR_LIT:None>' <EOL> proforma_link . short_description = '<STR_LIT>' <EOL> proforma_link . allow_tags = True <EOL> class SubscriptionAdmin ( ModelAdmin ) : <EOL> list_display = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:state>' , metadata ] <EOL> list_filter = [ '<STR_LIT>' , '<STR_LIT:state>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> readonly_fields = [ '<STR_LIT:state>' , ] <EOL> actions = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:end>' ] <EOL> search_fields = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' ] <EOL> inlines = [ MeteredFeatureUnitsLogInLine , BillingLogInLine ] <EOL> def perform_action ( self , request , action , queryset ) : <EOL> try : <EOL> method = getattr ( Subscription , action ) <EOL> except AttributeError : <EOL> self . message_user ( request , '<STR_LIT>' , level = messages . ERROR ) <EOL> return <EOL> failed_count = <NUM_LIT:0> <EOL> queryset_count = queryset . count ( ) <EOL> for entry in queryset : <EOL> try : <EOL> method ( entry ) <EOL> entry . save ( ) <EOL> LogEntry . objects . log_action ( <EOL> user_id = request . user . id , <EOL> content_type_id = ContentType . objects . get_for_model ( entry ) . pk , <EOL> object_id = entry . id , <EOL> object_repr = unicode ( entry ) , <EOL> action_flag = CHANGE , <EOL> change_message = '<STR_LIT>' . format ( <EOL> action = action . replace ( '<STR_LIT:_>' , '<STR_LIT:U+0020>' ) . strip ( ) . capitalize ( ) <EOL> ) <EOL> ) <EOL> except TransitionNotAllowed : <EOL> failed_count += <NUM_LIT:1> <EOL> if failed_count : <EOL> if failed_count == queryset_count : <EOL> self . message_user ( request , '<STR_LIT>' , <EOL> level = messages . ERROR ) <EOL> else : <EOL> self . message_user ( request , '<STR_LIT>' % <EOL> ( queryset_count - failed_count , failed_count ) , <EOL> level = messages . WARNING ) <EOL> else : <EOL> self . message_user ( request , '<STR_LIT>' % <EOL> queryset_count ) <EOL> def activate ( self , request , queryset ) : <EOL> self . perform_action ( request , '<STR_LIT>' , queryset ) <EOL> activate . short_description = '<STR_LIT>' <EOL> def reactivate ( self , request , queryset ) : <EOL> self . perform_action ( request , '<STR_LIT>' , queryset ) <EOL> reactivate . short_description = '<STR_LIT>' <EOL> def cancel_now ( self , request , queryset ) : <EOL> self . perform_action ( request , '<STR_LIT>' , queryset ) <EOL> cancel_now . short_description = '<STR_LIT>' <EOL> def cancel_at_end_of_cycle ( self , request , queryset ) : <EOL> self . perform_action ( request , '<STR_LIT>' , queryset ) <EOL> cancel_at_end_of_cycle . short_description = '<STR_LIT>' '<STR_LIT>' '<STR_LIT>' <EOL> def end ( self , request , queryset ) : <EOL> self . perform_action ( request , '<STR_LIT:end>' , queryset ) <EOL> end . short_description = '<STR_LIT>' <EOL> class CustomerAdmin ( LiveModelAdmin ) : <EOL> fields = [ '<STR_LIT>' , '<STR_LIT:name>' , '<STR_LIT>' , '<STR_LIT:email>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:state>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> list_display = [ '<STR_LIT>' , '<STR_LIT>' , <EOL> tax , '<STR_LIT>' , metadata ] <EOL> search_fields = [ '<STR_LIT>' , '<STR_LIT:name>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:state>' , <EOL> '<STR_LIT:email>' , '<STR_LIT>' ] <EOL> actions = [ '<STR_LIT>' ] <EOL> exclude = [ '<STR_LIT>' ] <EOL> def generate_all_documents ( self , request , queryset ) : <EOL> if request . POST . get ( '<STR_LIT>' ) : <EOL> billing_date = timezone . now ( ) . date ( ) <EOL> DocumentsGenerator ( ) . generate ( billing_date = billing_date , <EOL> customers = queryset , <EOL> force_generate = True ) <EOL> msg = '<STR_LIT>' <EOL> if queryset . count ( ) > <NUM_LIT:1> : <EOL> msg = msg . format ( term = '<STR_LIT>' ) <EOL> else : <EOL> msg = msg . format ( term = '<STR_LIT>' ) <EOL> self . message_user ( request , msg ) <EOL> return None <EOL> active_subs = [ ] <EOL> canceled_subs = [ ] <EOL> for customer in queryset : <EOL> subs = customer . subscriptions . all ( ) <EOL> for sub in subs : <EOL> if sub . state == Subscription . STATES . ACTIVE : <EOL> active_subs . append ( sub ) <EOL> elif sub . state == Subscription . STATES . CANCELED : <EOL> canceled_subs . append ( sub ) <EOL> if len ( active_subs ) + len ( canceled_subs ) == <NUM_LIT:0> : <EOL> msg = '<STR_LIT>' <EOL> self . message_user ( request , msg , level = messages . WARNING ) <EOL> return None <EOL> context = { <EOL> '<STR_LIT:title>' : _ ( '<STR_LIT>' ) , <EOL> '<STR_LIT>' : active_subs , <EOL> '<STR_LIT>' : canceled_subs , <EOL> '<STR_LIT>' : queryset , <EOL> '<STR_LIT>' : helpers . ACTION_CHECKBOX_NAME , <EOL> '<STR_LIT>' : self . model . _meta <EOL> } <EOL> return render ( request , '<STR_LIT>' , context ) <EOL> generate_all_documents . short_description = '<STR_LIT>' <EOL> class ProviderAdmin ( LiveModelAdmin ) : <EOL> fields = [ '<STR_LIT>' , '<STR_LIT:name>' , '<STR_LIT:email>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT:state>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' ] <EOL> list_display = [ '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , metadata ] <EOL> search_fields = [ '<STR_LIT>' , '<STR_LIT:name>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:state>' , <EOL> '<STR_LIT:email>' , '<STR_LIT>' ] <EOL> actions = [ '<STR_LIT>' ] <EOL> exclude = [ '<STR_LIT>' ] <EOL> def invoice_series_list_display ( self , obj ) : <EOL> return '<STR_LIT>' . format ( obj . invoice_series , obj . invoice_starting_number ) <EOL> invoice_series_list_display . short_description = '<STR_LIT>' <EOL> def proforma_series_list_display ( self , obj ) : <EOL> return '<STR_LIT>' . format ( obj . proforma_series , <EOL> obj . proforma_starting_number ) <EOL> proforma_series_list_display . short_description = '<STR_LIT>' <EOL> def _compute_monthly_totals ( self , model_klass , provider , documents ) : <EOL> klass_name_plural = model_klass . __name__ + '<STR_LIT:s>' <EOL> totals = { } <EOL> totals [ klass_name_plural ] = OrderedDict ( ) <EOL> all_documents = documents . filter ( provider = provider ) <EOL> paid_documents = documents . filter ( <EOL> provider = provider , <EOL> state = BillingDocument . STATES . PAID <EOL> ) <EOL> documents_months = documents . order_by ( ) . filter ( <EOL> provider = provider <EOL> ) . values ( <EOL> '<STR_LIT>' <EOL> ) . distinct ( ) <EOL> total_draft = sum ( <EOL> doc . total for doc in ( <EOL> documents . filter ( <EOL> provider = provider , <EOL> state = BillingDocument . STATES . DRAFT <EOL> ) <EOL> ) <EOL> ) <EOL> totals [ klass_name_plural ] [ '<STR_LIT>' ] = str ( total_draft ) <EOL> totals [ klass_name_plural ] [ '<STR_LIT>' ] = OrderedDict ( ) <EOL> documents_months = sorted ( [ month [ '<STR_LIT>' ] <EOL> for month in documents_months <EOL> if month [ '<STR_LIT>' ] ] ) <EOL> for month_value in documents_months : <EOL> if month_value is None : <EOL> continue <EOL> display_date = month_value . strftime ( '<STR_LIT>' ) <EOL> totals [ klass_name_plural ] [ '<STR_LIT>' ] [ display_date ] = OrderedDict ( ) <EOL> all_documents_from_month = all_documents . filter ( <EOL> issue_date__month = month_value . month , <EOL> issue_date__year = month_value . year <EOL> ) <EOL> paid_documents_from_month = paid_documents . filter ( <EOL> issue_date__month = month_value . month , <EOL> issue_date__year = month_value . year <EOL> ) <EOL> total = sum ( invoice . total for invoice in all_documents_from_month ) <EOL> total_paid = sum ( invoice . total for invoice in paid_documents_from_month ) <EOL> totals [ klass_name_plural ] [ '<STR_LIT>' ] [ display_date ] [ '<STR_LIT>' ] = str ( total ) <EOL> totals [ klass_name_plural ] [ '<STR_LIT>' ] [ display_date ] [ '<STR_LIT>' ] = str ( total_paid ) <EOL> totals [ klass_name_plural ] [ '<STR_LIT>' ] [ display_date ] [ '<STR_LIT>' ] = str ( total - total_paid ) <EOL> return totals <EOL> def generate_monthly_totals ( self , request , queryset ) : <EOL> totals = { } <EOL> invoices = Invoice . objects . extra ( <EOL> select = { <EOL> '<STR_LIT>' : connections [ Invoice . objects . db ] . ops . date_trunc_sql ( <EOL> '<STR_LIT>' , '<STR_LIT>' <EOL> ) <EOL> } <EOL> ) . filter ( <EOL> provider__in = queryset , <EOL> state__in = [ BillingDocument . STATES . DRAFT , <EOL> BillingDocument . STATES . ISSUED , <EOL> BillingDocument . STATES . PAID ] <EOL> ) <EOL> proformas = Proforma . objects . extra ( <EOL> select = { <EOL> '<STR_LIT>' : connections [ Invoice . objects . db ] . ops . date_trunc_sql ( <EOL> '<STR_LIT>' , '<STR_LIT>' <EOL> ) <EOL> } <EOL> ) . filter ( <EOL> provider__in = queryset , <EOL> state__in = [ BillingDocument . STATES . DRAFT , <EOL> BillingDocument . STATES . ISSUED , <EOL> BillingDocument . STATES . PAID ] <EOL> ) <EOL> for provider in queryset : <EOL> totals [ provider . name ] = OrderedDict ( ) <EOL> invoices_total = self . _compute_monthly_totals ( Invoice , provider , <EOL> invoices ) <EOL> totals [ provider . name ] . update ( invoices_total ) <EOL> proformas_total = self . _compute_monthly_totals ( Proforma , provider , <EOL> proformas ) <EOL> totals [ provider . name ] . update ( proformas_total ) <EOL> context = { <EOL> '<STR_LIT:title>' : _ ( '<STR_LIT>' ) , <EOL> '<STR_LIT>' : totals , <EOL> '<STR_LIT>' : queryset , <EOL> '<STR_LIT>' : self . model . _meta <EOL> } <EOL> return render ( request , '<STR_LIT>' , context ) <EOL> generate_monthly_totals . short_description = '<STR_LIT>' <EOL> class DocumentEntryForm ( forms . ModelForm ) : <EOL> class Meta : <EOL> model = DocumentEntry <EOL> fields = ( '<STR_LIT:description>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) <EOL> widgets = { <EOL> '<STR_LIT:description>' : forms . Textarea ( attrs = { '<STR_LIT>' : <NUM_LIT:50> , '<STR_LIT>' : <NUM_LIT:3> } ) <EOL> } <EOL> class DocumentEntryInline ( TabularInline ) : <EOL> model = DocumentEntry <EOL> form = DocumentEntryForm <EOL> extra = <NUM_LIT:0> <EOL> class BillingDocumentForm ( forms . ModelForm ) : <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> instance = kwargs . get ( '<STR_LIT>' ) <EOL> self . initial_number = instance . number if instance else None <EOL> self . initial_series = instance . series if instance else None <EOL> self . provider = instance . provider if instance else None <EOL> super ( BillingDocumentForm , self ) . __init__ ( * args , ** kwargs ) <EOL> def save ( self , commit = True , * args , ** kwargs ) : <EOL> obj = super ( BillingDocumentForm , self ) . save ( commit = False ) <EOL> if self . provider != obj . provider : <EOL> obj . number = None <EOL> else : <EOL> if self . initial_number and not obj . number : <EOL> if ( obj . series and self . initial_series and <EOL> obj . series == self . initial_series ) : <EOL> obj . number = self . initial_number <EOL> if commit : <EOL> obj . save ( ) <EOL> return obj <EOL> class InvoiceForm ( BillingDocumentForm ) : <EOL> class Meta : <EOL> model = Invoice <EOL> fields = ( ) <EOL> class ProformaForm ( BillingDocumentForm ) : <EOL> class Meta : <EOL> model = Proforma <EOL> fields = ( ) <EOL> class BillingDocumentAdmin ( ModelAdmin ) : <EOL> list_display = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:state>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , tax , '<STR_LIT>' ] <EOL> list_filter = ( '<STR_LIT>' , '<STR_LIT:state>' ) <EOL> common_fields = [ '<STR_LIT>' , '<STR_LIT:email>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:name>' , '<STR_LIT:state>' ] <EOL> customer_search_fields = [ '<STR_LIT>' . format ( field = field ) <EOL> for field in common_fields ] <EOL> provider_search_fields = [ '<STR_LIT>' . format ( field = field ) <EOL> for field in common_fields ] <EOL> search_fields = ( customer_search_fields + provider_search_fields + <EOL> [ '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> date_hierarchy = '<STR_LIT>' <EOL> fields = ( ( '<STR_LIT>' , '<STR_LIT>' ) , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:state>' , '<STR_LIT>' ) <EOL> readonly_fields = ( '<STR_LIT:state>' , '<STR_LIT>' ) <EOL> inlines = [ DocumentEntryInline ] <EOL> actions = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> @ property <EOL> def _model ( self ) : <EOL> raise NotImplementedError <EOL> @ property <EOL> def _model_name ( self ) : <EOL> raise NotImplementedError <EOL> def perform_action ( self , request , queryset , action ) : <EOL> method = getattr ( self . _model , action , None ) <EOL> if not method : <EOL> self . message_user ( request , '<STR_LIT>' , level = messages . ERROR ) <EOL> return <EOL> exist_failed_changes = False <EOL> exist_failed_actions = False <EOL> failed_changes = [ ] <EOL> failed_actions = [ ] <EOL> results = [ ] <EOL> for entry in queryset : <EOL> try : <EOL> result = method ( entry ) <EOL> if result : <EOL> results . append ( result ) <EOL> entry . save ( ) <EOL> LogEntry . objects . log_action ( <EOL> user_id = request . user . id , <EOL> content_type_id = ContentType . objects . get_for_model ( entry ) . pk , <EOL> object_id = entry . id , <EOL> object_repr = unicode ( entry ) , <EOL> action_flag = CHANGE , <EOL> change_message = '<STR_LIT>' . format ( <EOL> action = action . replace ( '<STR_LIT:_>' , '<STR_LIT:U+0020>' ) . strip ( ) . capitalize ( ) <EOL> ) <EOL> ) <EOL> except TransitionNotAllowed : <EOL> exist_failed_changes = True <EOL> failed_changes . append ( entry . number ) <EOL> except ValueError as error : <EOL> exist_failed_actions = True <EOL> failed_actions . append ( error . message ) <EOL> if exist_failed_actions : <EOL> msg = "<STR_LIT:\n>" . join ( failed_actions ) <EOL> self . message_user ( request , msg , level = messages . ERROR ) <EOL> if exist_failed_changes : <EOL> failed_ids = '<STR_LIT:U+0020>' . join ( map ( str , failed_changes ) ) <EOL> msg = "<STR_LIT>" "<STR_LIT>" . format ( model_name = self . _model_name . lower ( ) , <EOL> ids = failed_ids ) <EOL> self . message_user ( request , msg , level = messages . ERROR ) <EOL> if not exist_failed_actions and not exist_failed_changes : <EOL> qs_count = queryset . count ( ) <EOL> if action == '<STR_LIT>' : <EOL> results = '<STR_LIT:U+002CU+0020>' . join ( result . series_number for result in results ) <EOL> msg = '<STR_LIT>' '<STR_LIT>' . format ( <EOL> model_name = self . _model_name . lower ( ) , count = qs_count , <EOL> results = results <EOL> ) <EOL> else : <EOL> msg = '<STR_LIT>' . format ( <EOL> model_name = self . _model_name . lower ( ) , count = qs_count <EOL> ) <EOL> self . message_user ( request , msg ) <EOL> def has_delete_permission ( self , request , obj = None ) : <EOL> if request . user . is_superuser : <EOL> return True <EOL> return False <EOL> def get_actions ( self , request ) : <EOL> actions = super ( BillingDocumentAdmin , self ) . get_actions ( request ) <EOL> if not request . user . is_superuser : <EOL> if '<STR_LIT>' in actions : <EOL> del actions [ '<STR_LIT>' ] <EOL> return actions <EOL> def total ( self , obj ) : <EOL> return '<STR_LIT>' . format ( obj . total , <EOL> currency = obj . currency ) <EOL> def _download_pdf ( self , url , base_path ) : <EOL> local_file_path = os . path . join ( base_path , '<STR_LIT>' ) <EOL> response = requests . get ( url , stream = True ) <EOL> should_wipe_bad_headers = True <EOL> with open ( local_file_path , '<STR_LIT:wb>' ) as out_file : <EOL> for chunk in response . iter_content ( chunk_size = <NUM_LIT> ) : <EOL> if chunk : <EOL> if should_wipe_bad_headers : <EOL> pdf_header_pos = chunk . find ( '<STR_LIT>' ) <EOL> if pdf_header_pos > <NUM_LIT:0> : <EOL> chunk = chunk [ pdf_header_pos : ] <EOL> should_wipe_bad_headers = False <EOL> out_file . write ( chunk ) <EOL> out_file . flush ( ) <EOL> return local_file_path <EOL> def download_selected_documents ( self , request , queryset ) : <EOL> now = timezone . now ( ) <EOL> queryset = queryset . filter ( <EOL> state__in = [ BillingDocument . STATES . ISSUED , <EOL> BillingDocument . STATES . CANCELED , <EOL> BillingDocument . STATES . PAID ] <EOL> ) <EOL> base_path = '<STR_LIT>' <EOL> merger = PdfFileMerger ( ) <EOL> for document in queryset : <EOL> if document . pdf : <EOL> local_file_path = self . _download_pdf ( document . pdf . url , base_path ) <EOL> try : <EOL> reader = PdfFileReader ( file ( local_file_path , '<STR_LIT:rb>' ) ) <EOL> merger . append ( reader ) <EOL> logging_ctx = { <EOL> '<STR_LIT>' : document . series_number , <EOL> '<STR_LIT:status>' : '<STR_LIT>' <EOL> } <EOL> except Exception as e : <EOL> logging_ctx = { <EOL> '<STR_LIT>' : document . series_number , <EOL> '<STR_LIT:status>' : '<STR_LIT>' , <EOL> '<STR_LIT:error>' : e <EOL> } <EOL> logger . debug ( '<STR_LIT>' , logging_ctx ) <EOL> try : <EOL> os . remove ( local_file_path ) <EOL> except OSError as e : <EOL> if e . errno != errno . ENOENT : <EOL> raise <EOL> response = HttpResponse ( content_type = '<STR_LIT>' ) <EOL> filename = '<STR_LIT>' . format ( now = now ) <EOL> content_disposition = '<STR_LIT>' . format ( fn = filename ) <EOL> response [ '<STR_LIT>' ] = content_disposition <EOL> merger . write ( response ) <EOL> merger . close ( ) <EOL> return response <EOL> download_selected_documents . short_description = '<STR_LIT>' <EOL> class InvoiceAdmin ( BillingDocumentAdmin ) : <EOL> form = InvoiceForm <EOL> list_display = BillingDocumentAdmin . list_display + [ <EOL> '<STR_LIT>' , '<STR_LIT>' <EOL> ] <EOL> list_display_links = BillingDocumentAdmin . list_display_links <EOL> search_fields = BillingDocumentAdmin . search_fields <EOL> fields = BillingDocumentAdmin . fields + ( '<STR_LIT>' , ) <EOL> readonly_fields = BillingDocumentAdmin . readonly_fields + ( <EOL> '<STR_LIT>' , <EOL> ) <EOL> inlines = BillingDocumentAdmin . inlines <EOL> actions = BillingDocumentAdmin . actions <EOL> def issue ( self , request , queryset ) : <EOL> self . perform_action ( request , queryset , '<STR_LIT>' ) <EOL> issue . short_description = '<STR_LIT>' <EOL> def pay ( self , request , queryset ) : <EOL> self . perform_action ( request , queryset , '<STR_LIT>' ) <EOL> pay . short_description = '<STR_LIT>' <EOL> def cancel ( self , request , queryset ) : <EOL> self . perform_action ( request , queryset , '<STR_LIT>' ) <EOL> cancel . short_description = '<STR_LIT>' <EOL> def clone ( self , request , queryset ) : <EOL> self . perform_action ( request , queryset , '<STR_LIT>' ) <EOL> clone . short_description = '<STR_LIT>' <EOL> def invoice_pdf ( self , invoice ) : <EOL> if invoice . pdf : <EOL> url = reverse ( '<STR_LIT>' , kwargs = { '<STR_LIT>' : invoice . id } ) <EOL> return '<STR_LIT>' . format ( url = url ) <EOL> else : <EOL> return '<STR_LIT>' <EOL> invoice_pdf . allow_tags = True <EOL> @ property <EOL> def _model ( self ) : <EOL> return Invoice <EOL> @ property <EOL> def _model_name ( self ) : <EOL> return "<STR_LIT>" <EOL> def related_proforma ( self , obj ) : <EOL> return obj . proforma . admin_change_url if obj . proforma else '<STR_LIT:None>' <EOL> related_proforma . short_description = '<STR_LIT>' <EOL> related_proforma . allow_tags = True <EOL> class ProformaAdmin ( BillingDocumentAdmin ) : <EOL> form = ProformaForm <EOL> list_display = BillingDocumentAdmin . list_display + [ <EOL> '<STR_LIT>' , '<STR_LIT>' <EOL> ] <EOL> list_display_links = BillingDocumentAdmin . list_display_links <EOL> search_fields = BillingDocumentAdmin . search_fields <EOL> fields = BillingDocumentAdmin . fields + ( '<STR_LIT>' , ) <EOL> readonly_fields = BillingDocumentAdmin . readonly_fields + ( <EOL> '<STR_LIT>' , <EOL> ) <EOL> inlines = BillingDocumentAdmin . inlines <EOL> actions = BillingDocumentAdmin . actions + [ '<STR_LIT>' ] <EOL> def issue ( self , request , queryset ) : <EOL> self . perform_action ( request , queryset , '<STR_LIT>' ) <EOL> issue . short_description = '<STR_LIT>' <EOL> def create_invoice ( self , request , queryset ) : <EOL> self . perform_action ( request , queryset , '<STR_LIT>' ) <EOL> create_invoice . short_description = '<STR_LIT>' <EOL> def pay ( self , request , queryset ) : <EOL> self . perform_action ( request , queryset , '<STR_LIT>' ) <EOL> pay . short_description = '<STR_LIT>' <EOL> def cancel ( self , request , queryset ) : <EOL> self . perform_action ( request , queryset , '<STR_LIT>' ) <EOL> cancel . short_description = '<STR_LIT>' <EOL> def clone ( self , request , queryset ) : <EOL> self . perform_action ( request , queryset , '<STR_LIT>' ) <EOL> clone . short_description = '<STR_LIT>' <EOL> def proforma_pdf ( self , proforma ) : <EOL> if proforma . pdf : <EOL> url = reverse ( '<STR_LIT>' , kwargs = { '<STR_LIT>' : proforma . id } ) <EOL> return '<STR_LIT>' . format ( url = url ) <EOL> else : <EOL> return '<STR_LIT>' <EOL> proforma_pdf . allow_tags = True <EOL> @ property <EOL> def _model ( self ) : <EOL> return Proforma <EOL> @ property <EOL> def _model_name ( self ) : <EOL> return "<STR_LIT>" <EOL> def related_invoice ( self , obj ) : <EOL> return obj . invoice . admin_change_url if obj . invoice else '<STR_LIT:None>' <EOL> related_invoice . short_description = '<STR_LIT>' <EOL> related_invoice . allow_tags = True <EOL> site . register ( Plan , PlanAdmin ) <EOL> site . register ( Subscription , SubscriptionAdmin ) <EOL> site . register ( Customer , CustomerAdmin ) <EOL> site . register ( Provider , ProviderAdmin ) <EOL> site . register ( Invoice , InvoiceAdmin ) <EOL> site . register ( Proforma , ProformaAdmin ) <EOL> site . register ( ProductCode ) <EOL> site . register ( MeteredFeature ) </s>
