def application_fee_checkout(self, request, *args, **kwargs): try: instance = self.get_object() product_lines = [] application_submission = u'Application submitted by {} confirmation WC{}'.format( u'{} {}'.format(instance.submitter.first_name, instance.submitter.last_name), instance.id) set_session_application(request.session, instance) product_lines.append({ 'ledger_description': '{}'.format(instance.licence_type_name), 'quantity': 1, 'price_incl_tax': str(instance.application_fee), 'price_excl_tax': str(calculate_excl_gst(instance.application_fee)), 'oracle_code': '' }) checkout_result = checkout(request, instance, lines=product_lines, invoice_text=application_submission) return checkout_result except serializers.ValidationError: print(traceback.print_exc()) raise except ValidationError as e: if hasattr(e,'error_dict'): raise serializers.ValidationError(repr(e.error_dict)) else: raise serializers.ValidationError(repr(e[0].encode('utf-8'))) except Exception as e: print(traceback.print_exc()) raise serializers.ValidationError(str(e))
def __footer_line(self): canvas = self.canv current_y, current_x = self.current_y, self.current_x current_y -= 2 * inch canvas.setFont(DEFAULT_FONTNAME, LARGE_FONTSIZE) canvas.setFillColor(colors.black) canvas.drawString(current_x, current_y, 'Invoice Number') canvas.drawString(PAGE_WIDTH / 4, current_y, 'Invoice Date') canvas.drawString((PAGE_WIDTH / 4) * 2, current_y, 'GST included') canvas.drawString((PAGE_WIDTH / 4) * 3, current_y, 'Invoice Total') current_y -= 20 canvas.setFont(DEFAULT_FONTNAME, MEDIUM_FONTSIZE) canvas.drawString(current_x, current_y, self.invoice.reference) canvas.drawString(PAGE_WIDTH / 4, current_y, self.invoice.created.strftime(DATE_FORMAT)) canvas.drawString( (PAGE_WIDTH / 4) * 2, current_y, currency(self.invoice.amount - calculate_excl_gst(self.invoice.amount) if not _is_gst_exempt(self.proposal, self.invoice) else 0.0)) canvas.drawString((PAGE_WIDTH / 4) * 3, current_y, currency(self.invoice.amount))
def create_fee_lines(proposal, invoice_text=None, vouchers=[], internal=False): """ Create the ledger lines - line item for application fee sent to payment system """ db_processes_after_success = {} if proposal.application_type.name == ApplicationType.APIARY: line_items, db_processes_after_success = create_fee_lines_apiary( proposal ) # This function returns line items and db_processes as a tuple # line_items, db_processes_after_success = create_fee_lines_apiary(proposal) # This function returns line items and db_processes as a tuple elif proposal.application_type.name == ApplicationType.SITE_TRANSFER: line_items, db_processes_after_success = create_fee_lines_site_transfer( proposal ) # This function returns line items and db_processes as a tuple else: now = datetime.now().strftime('%Y-%m-%d %H:%M') # Non 'Apiary' proposal application_price = proposal.application_type.application_fee line_items = [ { 'ledger_description': 'Application Fee - {} - {}'.format(now, proposal.lodgement_number), 'oracle_code': proposal.application_type.oracle_code_application, 'price_incl_tax': application_price, 'price_excl_tax': application_price if proposal.application_type.is_gst_exempt else calculate_excl_gst(application_price), 'quantity': 1, }, ] logger.info('{}'.format(line_items)) return line_items, db_processes_after_success
def get_fee_product_lines_for(a_return): """ Gets the checkout product lines for a return which includes the fees. """ from ledger.checkout.utils import calculate_excl_gst product_lines = [] oracle_code = a_return.return_type.oracle_account_code product_lines.append({ 'ledger_description': 'submission fee for {0}'.format(a_return.lodgement_number), 'quantity': 1, 'price_incl_tax': str(a_return.return_fee), 'price_excl_tax': str(calculate_excl_gst(a_return.return_fee)), 'oracle_code': oracle_code }) return product_lines
def _create_header(canvas, doc, draw_page_number=True): canvas.saveState() canvas.setTitle('Invoice') canvas.setFont(BOLD_FONTNAME, LARGE_FONTSIZE) current_y = PAGE_HEIGHT - HEADER_MARGIN dpaw_header_logo = ImageReader(DPAW_HEADER_LOGO) dpaw_header_logo_size = dpaw_header_logo.getSize() canvas.drawImage(dpaw_header_logo, PAGE_WIDTH / 3, current_y - (dpaw_header_logo_size[1] / 2), width=dpaw_header_logo_size[0] / 2, height=dpaw_header_logo_size[1] / 2, mask='auto') current_y -= 70 canvas.drawCentredString(PAGE_WIDTH / 2, current_y - LARGE_FONTSIZE, 'TAX INVOICE') current_y -= 20 canvas.drawCentredString(PAGE_WIDTH / 2, current_y - LARGE_FONTSIZE, 'ABN: 38 052 249 024') # Invoice address details invoice_details_offset = 37 current_y -= 10 invoice = doc.invoice proposal = doc.proposal bi = proposal.bookings.filter( invoices__invoice_reference=invoice.reference) licence_number = proposal.approval.lodgement_number if proposal.approval else None # TODO need to fix, since individual parks can be exempt, Below calculation assumes NO PARK IS exempt #is_gst_exempt = proposal.application_type.is_gst_exempt if proposal.fee_invoice_reference == invoice.reference else False canvas.setFont(BOLD_FONTNAME, SMALL_FONTSIZE) current_x = PAGE_MARGIN + 5 if proposal.org_applicant: canvas.drawString(current_x, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER), proposal.applicant) canvas.drawString(current_x, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 2, invoice.owner.get_full_name()) canvas.drawString(current_x, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 3, invoice.owner.email) current_x += 435 #write Invoice details canvas.drawString(current_x, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER), 'Date') canvas.drawString( current_x + invoice_details_offset, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER), to_local_tz(invoice.created).strftime(DATE_FORMAT) + ' (AWST)') canvas.drawString(current_x, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 2, 'Page') canvas.drawString(current_x + invoice_details_offset, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 2, str(canvas.getPageNumber())) if licence_number: canvas.drawRightString( current_x + 20, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 3, 'Licence Number') canvas.drawString( current_x + invoice_details_offset, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 3, licence_number) else: canvas.drawRightString( current_x + 20, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 3, 'Proposal Number') canvas.drawString( current_x + invoice_details_offset, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 3, proposal.lodgement_number) canvas.drawRightString( current_x + 20, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 4, 'Invoice Number') canvas.drawString(current_x + invoice_details_offset, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 4, invoice.reference) canvas.drawRightString( current_x + 20, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 5, 'Total (AUD)') canvas.drawString(current_x + invoice_details_offset, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 5, currency(invoice.amount)) canvas.drawRightString( current_x + 20, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 6, 'GST included (AUD)') canvas.drawString( current_x + invoice_details_offset, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 6, currency(invoice.amount - calculate_excl_gst(invoice.amount) if not _is_gst_exempt(proposal, invoice) else 0.0)) canvas.drawRightString( current_x + 20, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 7, 'Paid (AUD)') canvas.drawString(current_x + invoice_details_offset, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 7, currency(invoice.payment_amount)) canvas.drawRightString( current_x + 20, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 8, 'Outstanding (AUD)') canvas.drawString(current_x + invoice_details_offset, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 8, currency(invoice.balance)) if bi and bi[0].deferred_payment_date and invoice.payment_method in [ invoice.PAYMENT_METHOD_MONTHLY_INVOICING, invoice.PAYMENT_METHOD_BPAY ]: canvas.drawRightString( current_x + 20, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 9, 'Payment Due Date') canvas.drawString( current_x + invoice_details_offset, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 9, bi[0].deferred_payment_date.strftime(DATE_FORMAT)) canvas.restoreState()
def _create_header(canvas, doc, draw_page_number=True): canvas.saveState() canvas.setTitle('Invoice') canvas.setFont(BOLD_FONTNAME, LARGE_FONTSIZE) current_y = PAGE_HEIGHT - HEADER_MARGIN dpaw_header_logo = ImageReader(DPAW_HEADER_LOGO) dpaw_header_logo_size = dpaw_header_logo.getSize() canvas.drawImage(dpaw_header_logo, PAGE_WIDTH / 3, current_y - (dpaw_header_logo_size[1] / 2), width=dpaw_header_logo_size[0] / 2, height=dpaw_header_logo_size[1] / 2, mask='auto') current_y -= 70 canvas.drawCentredString(PAGE_WIDTH / 2, current_y - LARGE_FONTSIZE, 'TAX INVOICE') current_y -= 20 canvas.drawCentredString(PAGE_WIDTH / 2, current_y - LARGE_FONTSIZE, 'ABN: 38 052 249 024') # Invoice address details invoice_details_offset = 37 current_y -= 20 invoice = doc.invoice canvas.setFont(BOLD_FONTNAME, SMALL_FONTSIZE) current_x = PAGE_MARGIN + 5 canvas.drawString(current_x, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER), invoice.owner.get_full_name()) canvas.drawString(current_x, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 2, invoice.owner.username) current_x += 452 #write Invoice details canvas.drawString(current_x, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER), 'Date') canvas.drawString(current_x + invoice_details_offset, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER), invoice.created.strftime(DATE_FORMAT)) canvas.drawString(current_x, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 2, 'Page') canvas.drawString(current_x + invoice_details_offset, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 2, str(canvas.getPageNumber())) canvas.drawRightString( current_x + 20, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 3, 'Invoice Number') canvas.drawString(current_x + invoice_details_offset, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 3, invoice.reference) canvas.drawRightString( current_x + 20, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 4, 'Total (AUD)') canvas.drawString(current_x + invoice_details_offset, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 4, currency(invoice.amount)) canvas.drawRightString( current_x + 20, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 5, 'GST included (AUD)') canvas.drawString( current_x + invoice_details_offset, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 5, currency(invoice.amount - calculate_excl_gst(invoice.amount))) canvas.drawRightString( current_x + 20, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 6, 'Paid (AUD)') canvas.drawString(current_x + invoice_details_offset, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 6, currency(invoice.payment_amount)) canvas.drawRightString( current_x + 20, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 7, 'Outstanding (AUD)') canvas.drawString(current_x + invoice_details_offset, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 7, currency(invoice.balance)) canvas.restoreState()
def post(self, request, *args, **kwargs): # approval = self.get_object() data = request.POST.get('data') data = json.loads(data) ids = data['sticker_action_detail_ids'] # 1. Validate data # raise forms.ValidationError('Validation error') # 2. Store detais in the session sticker_action_fee = StickerActionFee.objects.create( created_by=request.user, payment_type=StickerActionFee.PAYMENT_TYPE_TEMPORARY) current_datetime = datetime.datetime.now(pytz.timezone(TIME_ZONE)) try: with transaction.atomic(): sticker_action_details = StickerActionDetail.objects.filter( id__in=ids) sticker_action_details.update( sticker_action_fee=sticker_action_fee) set_session_sticker_action_invoice(request.session, sticker_action_fee) # lines, db_processes_after_success = create_fee_lines(proposal) target_datetime_str = current_datetime.astimezone( pytz.timezone(TIME_ZONE)).strftime('%d/%m/%Y %I:%M %p') application_type = ApplicationType.objects.get( code=settings.APPLICATION_TYPE_REPLACEMENT_STICKER['code']) fee_item = FeeItemStickerReplacement.get_fee_item_by_date( current_datetime.date()) lines = [] for sticker_action_detail in sticker_action_details: line = { 'ledger_description': 'Sticker Replacement Fee, sticker: {} @{}'.format( sticker_action_detail.sticker, target_datetime_str), 'oracle_code': application_type.get_oracle_code_by_date( current_datetime.date()), 'price_incl_tax': fee_item.amount, 'price_excl_tax': calculate_excl_gst(fee_item.amount) if fee_item.incur_gst else fee_item.amount, 'quantity': 1, } lines.append(line) # request.session['db_processes'] = db_processes_after_success checkout_response = checkout( request, request.user, lines, return_url_ns='sticker_replacement_fee_success', return_preload_url_ns='sticker_replacement_fee_success', invoice_text='{}'.format(application_type.description), ) logger.info( '{} built payment line item(s) {} for Sticker Replacement Fee and handing over to payment gateway' .format( 'User {} with id {}'.format( request.user.get_full_name(), request.user.id), sticker_action_fee)) return checkout_response except Exception as e: logger.error('Error handling StickerActionFee: {}'.format(e)) if sticker_action_fee: sticker_action_fee.delete() raise
def post(self, request, *args, **kwargs): #def get(self, request, format='json'): try: if request.user.is_superuser or request.user.groups.filter( name__in=['Mooring Licensing - Payment Officers' ]).exists(): money_from = request.POST.get('money_from', []) money_to = request.POST.get('money_to', []) bpoint_trans_split = request.POST.get('bpoint_trans_split', []) refund_method = request.POST.get('refund_method', None) booking_id = request.POST.get('booking_id', None) newest_booking_id = request.POST.get('newest_booking_id', None) booking = Proposal.objects.get(pk=newest_booking_id) money_from_json = json.loads(money_from) money_to_json = json.loads(money_to) bpoint_trans_split_json = json.loads(bpoint_trans_split) failed_refund = False json_obj = { 'found': False, 'code': money_from, 'money_to': money_to, 'failed_refund': failed_refund } lines = [] if int(refund_method) == 1: lines = [] for mf in money_from_json: if Decimal(mf['line-amount']) > 0: money_from_total = (Decimal(mf['line-amount']) - Decimal(mf['line-amount']) - Decimal(mf['line-amount'])) lines.append({ 'ledger_description': str(mf['line-text']), "quantity": 1, "price_incl_tax": money_from_total, "price_excl_tax": calculate_excl_gst(money_from_total), "oracle_code": str(mf['oracle-code']), "line_status": 3 }) for bp_txn in bpoint_trans_split_json: bpoint_id = BpointTransaction.objects.get( txn_number=bp_txn['txn_number']) info = { 'amount': Decimal('{:.2f}'.format( float(bp_txn['line-amount']))), 'details': 'Refund via system' } if info['amount'] > 0: lines.append({ 'ledger_description': str("Temp fund transfer " + bp_txn['txn_number']), "quantity": 1, "price_incl_tax": Decimal('{:.2f}'.format( float(bp_txn['line-amount']))), "price_excl_tax": calculate_excl_gst( Decimal('{:.2f}'.format( float(bp_txn['line-amount'])))), "oracle_code": str(settings.UNALLOCATED_ORACLE_CODE), 'line_status': 1 }) order = utils.allocate_refund_to_invoice( request, booking, lines, invoice_text=None, internal=False, order_total='0.00', user=booking.submitter, system_invoice=True) new_invoice = Invoice.objects.get( order_number=order.number) update_payments(new_invoice.reference) #order = utils.allocate_refund_to_invoice(request, booking, lines, invoice_text=None, internal=False, order_total='0.00',user=booking.customer) #new_order = Order.objects.get(basket=basket) #new_invoice = Invoice.objects.get(order_number=order.number) for bp_txn in bpoint_trans_split_json: bpoint_id = None try: bpoint_id = BpointTransaction.objects.get( txn_number=bp_txn['txn_number']) info = { 'amount': Decimal('{:.2f}'.format( float(bp_txn['line-amount']))), 'details': 'Refund via system' } except Exception as e: print(e) info = { 'amount': Decimal('{:.2f}'.format('0.00')), 'details': 'Refund via system' } refund = None lines = [] if info['amount'] > 0: lines = [] #lines.append({'ledger_description':str("Temp fund transfer "+bp_txn['txn_number']),"quantity":1,"price_incl_tax":Decimal('{:.2f}'.format(float(bp_txn['line-amount']))),"oracle_code":str(settings.UNALLOCATED_ORACLE_CODE), 'line_status': 1}) try: bpoint_money_to = ( Decimal('{:.2f}'.format( float(bp_txn['line-amount']))) - Decimal('{:.2f}'.format( float(bp_txn['line-amount']))) - Decimal('{:.2f}'.format( float(bp_txn['line-amount'])))) lines.append({ 'ledger_description': str("Payment Gateway Refund to " + bp_txn['txn_number']), "quantity": 1, "price_incl_tax": bpoint_money_to, "price_excl_tax": calculate_excl_gst(bpoint_money_to), "oracle_code": str(settings.UNALLOCATED_ORACLE_CODE), 'line_status': 3 }) bpoint = BpointTransaction.objects.get( txn_number=bp_txn['txn_number']) refund = bpoint.refund(info, request.user) except Exception as e: failed_refund = True bpoint_failed_amount = Decimal( bp_txn['line-amount']) lines = [] lines.append({ 'ledger_description': str("Refund failed for txn " + bp_txn['txn_number']), "quantity": 1, "price_incl_tax": '0.00', "price_excl_tax": '0.00', "oracle_code": str(settings.UNALLOCATED_ORACLE_CODE), 'line_status': 1 }) order = utils.allocate_refund_to_invoice( request, booking, lines, invoice_text=None, internal=False, order_total='0.00', user=booking.submitter, system_invoice=False) new_invoice = Invoice.objects.get( order_number=order.number) if refund: bpoint_refund = BpointTransaction.objects.get( txn_number=refund.txn_number) bpoint_refund.crn1 = new_invoice.reference bpoint_refund.save() new_invoice.settlement_date = None new_invoice.save() update_payments(new_invoice.reference) else: lines = [] for mf in money_from_json: if Decimal(mf['line-amount']) > 0: money_from_total = (Decimal(mf['line-amount']) - Decimal(mf['line-amount']) - Decimal(mf['line-amount'])) lines.append({ 'ledger_description': str(mf['line-text']), "quantity": 1, "price_incl_tax": money_from_total, "price_excl_tax": calculate_excl_gst(money_from_total), "oracle_code": str(mf['oracle-code']), 'line_status': 3 }) for mt in money_to_json: lines.append({ 'ledger_description': mt['line-text'], "quantity": 1, "price_incl_tax": mt['line-amount'], "price_excl_tax": calculate_excl_gst(mt['line-amount']), "oracle_code": mt['oracle-code'], 'line_status': 1 }) order = utils.allocate_refund_to_invoice( request, booking, lines, invoice_text=None, internal=False, order_total='0.00', user=booking.submitter, system_invoice=False) new_invoice = Invoice.objects.get( order_number=order.number) update_payments(new_invoice.reference) json_obj['failed_refund'] = failed_refund return Response(json_obj) else: raise serializers.ValidationError('Permission Denied.') except Exception as e: print(traceback.print_exc()) raise
def create_fee_lines_for_dcv_admission(dcv_admission, invoice_text=None, vouchers=[], internal=False): db_processes_after_success = {} target_datetime = datetime.now(pytz.timezone(TIME_ZONE)) target_date = target_datetime.date() target_datetime_str = target_datetime.astimezone( pytz.timezone(TIME_ZONE)).strftime('%d/%m/%Y %I:%M %p') db_processes_after_success[ 'datetime_for_calculating_fee'] = target_datetime.__str__() application_type = ApplicationType.objects.get( code=settings.APPLICATION_TYPE_DCV_ADMISSION['code']) vessel_length = 1 # any number greater than 0 proposal_type = None oracle_code = application_type.get_oracle_code_by_date( target_date=target_date) line_items = [] for dcv_admission_arrival in dcv_admission.dcv_admission_arrivals.all(): fee_constructor = FeeConstructor.get_fee_constructor_by_application_type_and_date( application_type, dcv_admission_arrival.arrival_date) if not fee_constructor: raise Exception( 'FeeConstructor object for the ApplicationType: {} and the Season: {}' .format(application_type, dcv_admission_arrival.arrival_date)) fee_items = [] number_of_people_str = [] total_amount = 0 for number_of_people in dcv_admission_arrival.numberofpeople_set.all(): if number_of_people.number: # When more than 1 people, fee_item = fee_constructor.get_fee_item( vessel_length, proposal_type, dcv_admission_arrival.arrival_date, number_of_people.age_group, number_of_people.admission_type) fee_item.number_of_people = number_of_people.number fee_items.append(fee_item) number_of_people_str.append('[{}-{}: {}]'.format( number_of_people.age_group, number_of_people.admission_type, number_of_people.number)) # total_amount += fee_item.amount * number_of_people.number total_amount += fee_item.get_absolute_amount( ) * number_of_people.number line_item = { 'ledger_description': '{} Fee: {} (Arrival: {}, Private: {}, {})'.format( fee_constructor.application_type.description, dcv_admission.lodgement_number, dcv_admission_arrival.arrival_date, dcv_admission_arrival.private_visit, ', '.join(number_of_people_str), ), 'oracle_code': oracle_code, 'price_incl_tax': total_amount, 'price_excl_tax': calculate_excl_gst(total_amount) if fee_constructor.incur_gst else total_amount, 'quantity': 1, } line_items.append(line_item) logger.info('{}'.format(line_items)) return line_items, db_processes_after_success
def create_fee_lines(proposal, invoice_text=None, vouchers=[], internal=False): """ Create the ledger lines - line item for application fee sent to payment system """ now = datetime.now().strftime('%Y-%m-%d %H:%M') application_price = proposal.application_type.application_fee licence_price = proposal.licence_fee_amount if proposal.application_type.name == 'T Class': if proposal.org_applicant.apply_application_discount: application_discount = min( proposal.org_applicant.application_discount, application_price) if proposal.org_applicant.apply_licence_discount: licence_discount = min(proposal.org_applicant.licence_discount, licence_price) line_items = [{ 'ledger_description': 'Application Fee - {} - {}'.format(now, proposal.lodgement_number), 'oracle_code': proposal.application_type.oracle_code_application, 'price_incl_tax': application_price, 'price_excl_tax': application_price if proposal.application_type.is_gst_exempt else calculate_excl_gst(application_price), 'quantity': 1, }, { 'ledger_description': 'Licence Charge {} - {} - {}'.format( proposal.other_details.get_preferred_licence_period_display(), now, proposal.lodgement_number), 'oracle_code': proposal.application_type.oracle_code_licence, 'price_incl_tax': licence_price, 'price_excl_tax': licence_price if proposal.application_type.is_gst_exempt else calculate_excl_gst(licence_price), 'quantity': 1, }] if proposal.application_type.name == 'T Class' and proposal.org_applicant: if proposal.org_applicant.apply_application_discount: line_items += [{ 'ledger_description': 'Application Fee Waiver - {} - {}'.format( now, proposal.lodgement_number), 'oracle_code': proposal.application_type.oracle_code_application, 'price_incl_tax': -application_discount, 'price_excl_tax': -application_discount, 'quantity': 1, }] if proposal.org_applicant.apply_licence_discount: line_items += [{ 'ledger_description': 'Licence Charge Waiver - {} - {}'.format( now, proposal.lodgement_number), 'oracle_code': proposal.application_type.oracle_code_application, 'price_incl_tax': -licence_discount, 'price_excl_tax': -licence_discount, 'quantity': 1, }] logger.info('{}'.format(line_items)) return line_items
def _create_header(canvas, doc, draw_page_number=True): canvas.saveState() canvas.setTitle('Invoice') canvas.setFont(BOLD_FONTNAME, LARGE_FONTSIZE) current_y = PAGE_HEIGHT - HEADER_MARGIN dpaw_header_logo = ImageReader(DPAW_HEADER_LOGO) dpaw_header_logo_size = dpaw_header_logo.getSize() canvas.drawImage(dpaw_header_logo, PAGE_WIDTH / 3, current_y - (dpaw_header_logo_size[1]/2),width=dpaw_header_logo_size[0]/2, height=dpaw_header_logo_size[1]/2, mask='auto') current_y -= 70 canvas.drawCentredString(PAGE_WIDTH / 2, current_y - LARGE_FONTSIZE, 'TAX INVOICE') current_y -= 20 canvas.drawCentredString(PAGE_WIDTH / 2, current_y - LARGE_FONTSIZE, 'ABN: 38 052 249 024') # Invoice address details invoice_details_offset = 37 current_y -= 20 invoice = doc.invoice canvas.setFont(BOLD_FONTNAME, SMALL_FONTSIZE) current_x = PAGE_MARGIN + 5 canvas.drawString(current_x, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER),invoice.owner.get_full_name()) canvas.drawString(current_x, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 2,invoice.owner.username) current_x += 452 #write Invoice details canvas.drawString(current_x, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER),'Date') canvas.drawString(current_x + invoice_details_offset, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER),invoice.created.strftime(DATE_FORMAT)) canvas.drawString(current_x, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 2, 'Page') canvas.drawString(current_x + invoice_details_offset, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 2, str(canvas.getPageNumber())) canvas.drawRightString(current_x + 20, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 3, 'Invoice Number') canvas.drawString(current_x + invoice_details_offset, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 3, invoice.reference) canvas.drawRightString(current_x + 20, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 4, 'Total (AUD)') canvas.drawString(current_x + invoice_details_offset, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 4, currency(invoice.amount)) canvas.drawRightString(current_x + 20, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 5, 'GST included (AUD)') canvas.drawString(current_x + invoice_details_offset, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 5, currency(invoice.amount - calculate_excl_gst(invoice.amount))) canvas.drawRightString(current_x + 20, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 6, 'Paid (AUD)') canvas.drawString(current_x + invoice_details_offset, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 6, currency(invoice.payment_amount)) canvas.drawRightString(current_x + 20, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 7, 'Outstanding (AUD)') canvas.drawString(current_x + invoice_details_offset, current_y - (SMALL_FONTSIZE + HEADER_SMALL_BUFFER) * 7, currency(invoice.balance)) canvas.restoreState()
def __footer_line(self): canvas = self.canv current_y, current_x = self.current_y, self.current_x current_y -= 2 * inch canvas.setFont(DEFAULT_FONTNAME, LARGE_FONTSIZE) canvas.setFillColor(colors.black) canvas.drawString(current_x, current_y, 'Invoice Number') canvas.drawString(PAGE_WIDTH/4, current_y, 'Invoice Date') canvas.drawString((PAGE_WIDTH/4) * 2, current_y, 'GST included') canvas.drawString((PAGE_WIDTH/4) * 3, current_y, 'Invoice Total') current_y -= 20 canvas.setFont(DEFAULT_FONTNAME, MEDIUM_FONTSIZE) canvas.drawString(current_x, current_y, self.invoice.reference) canvas.drawString(PAGE_WIDTH/4, current_y, self.invoice.created.strftime(DATE_FORMAT)) canvas.drawString((PAGE_WIDTH/4) * 2, current_y, currency(self.invoice.amount - calculate_excl_gst(self.invoice.amount))) canvas.drawString((PAGE_WIDTH/4) * 3, current_y, currency(self.invoice.amount))
def generate_line_items_for_annual_rental_fee(approval, today_now, period, apiary_sites): oracle_code_obj = ApiaryGlobalSettings.objects.get( key=ApiaryGlobalSettings.KEY_ORACLE_CODE_APIARY_SITE_ANNUAL_RENTAL_FEE) num_of_days_in_period = period[1] - (period[0] - timedelta(days=1)) # Retrieve summarised payment data per charge_period apiary_sites_charged, invoice_period = calculate_total_annual_rental_fee( approval, period, apiary_sites) line_items = [] if apiary_sites_charged: for charge_period, apiary_sites in apiary_sites_charged.items(): if not len(apiary_sites): continue fee_applied = ApiaryAnnualRentalFee.get_fee_at_target_date( charge_period[0] ) # TODO fee might be changed during the period fees_applied = ApiaryAnnualRentalFee.get_fees_by_period( charge_period[0], charge_period[1]) # num_of_days_charged = charge_period[1] - (charge_period[0] - timedelta(days=1)) # amount_per_site = fee_applied.amount * num_of_days_charged.days / num_of_days_in_period.days amount_per_site = 0 for fee_for_site in fees_applied: amount_per_site += fee_for_site.get( 'amount_per_year') * fee_for_site.get( 'num_of_days').days / num_of_days_in_period.days total_amount = amount_per_site * len(apiary_sites) total_amount = total_amount if total_amount >= 0 else 0 total_amount = round_amount_according_to_env(total_amount) line_item = {} line_item[ 'ledger_description'] = 'Annual Site Fee: {}, Issued: {} {}, Period: {} to {}, Site(s): {}'.format( approval.lodgement_number, today_now.strftime("%d/%m/%Y"), today_now.strftime("%I:%M %p"), charge_period[0].strftime("%d/%m/%Y"), charge_period[1].strftime("%d/%m/%Y"), ', '.join( ['site: ' + str(site.id) for site in apiary_sites])) if len(line_item['ledger_description']) >= 250: # description too long, shorten it line_item[ 'ledger_description'] = 'Annual Site Fee: {}, Issued: {} {}, Period: {} to {}, Number of sites: {}'.format( approval.lodgement_number, today_now.strftime("%d/%m/%Y"), today_now.strftime("%I:%M %p"), charge_period[0].strftime("%d/%m/%Y"), charge_period[1].strftime("%d/%m/%Y"), len(apiary_sites)) line_item['oracle_code'] = oracle_code_obj.value line_item['price_incl_tax'] = total_amount line_item[ 'price_excl_tax'] = total_amount if ANNUAL_RENTAL_FEE_GST_EXEMPT else calculate_excl_gst( total_amount) line_item['quantity'] = 1 line_items.append(line_item) return line_items, apiary_sites_charged, invoice_period
def create_fee_lines_apiary(proposal): now = datetime.now().strftime('%Y-%m-%d %H:%M') today_local = datetime.now(pytz.timezone(TIME_ZONE)).date() MIN_NUMBER_OF_SITES_TO_RENEW = 5 MIN_NUMBER_OF_SITES_TO_NEW = 5 line_items = [] # Once payment success, data is updated based on this variable # This variable is stored in the session db_process_after_success = { 'site_remainder_used': [], 'site_remainder_to_be_added': [], } # Calculate total number of sites applied per category # summary, db_process_after_success['apiary_sites'], temp = _sum_apiary_sites_per_category(proposal.proposal_apiary.apiary_sites.all(), proposal.proposal_apiary.vacant_apiary_sites.all()) db_process_after_success['apiary_site_ids'], db_process_after_success[ 'vacant_apiary_site_ids'], temp = _sum_apiary_sites_per_category2( proposal.proposal_apiary) # db_process_after_success['vacant_apiary_site_ids'] = [site.id for site in proposal.proposal_apiary.vacant_apiary_sites.all()] db_process_after_success[ 'proposal_apiary_id'] = proposal.proposal_apiary.id # Calculate number of sites to calculate the fee # for site_category_id, number_of_sites_applied in summary.items(): for site_category_name, data_in_category in temp.items(): site_category = SiteCategory.objects.get(name=site_category_name) for new_or_renewal, relations in data_in_category.items(): if not len(relations) > 0: # No apiary sites for this 'site_cateogyr' and 'new_or_renewal' continue site_fee_remainders = _get_site_fee_remainders( site_category, new_or_renewal, proposal.applicant, proposal.proxy_applicant) # Calculate deduction and set date_used field # number_of_sites_after_deduction = len(apiary_sites) number_of_sites_after_deduction = len([ relation for relation in relations if not relation.application_fee_paid ]) for site_left in site_fee_remainders: if number_of_sites_after_deduction == 0: break number_of_sites_after_deduction -= 1 site_remainder_used = { 'id': site_left.id, 'date_used': today_local.strftime('%Y-%m-%d') } db_process_after_success['site_remainder_used'].append( site_remainder_used) if new_or_renewal == ApiarySiteFeeType.FEE_TYPE_APPLICATION: min_num_of_sites_to_pay = MIN_NUMBER_OF_SITES_TO_NEW ledger_desc = 'New Apiary Site Fee - {} - {} - {}'.format( now, proposal.lodgement_number, site_category.display_name) elif new_or_renewal == ApiarySiteFeeType.FEE_TYPE_RENEWAL: min_num_of_sites_to_pay = MIN_NUMBER_OF_SITES_TO_RENEW ledger_desc = 'Renewal Fee - {} - {} - {}'.format( now, proposal.lodgement_number, site_category.display_name) else: # Should not reach here min_num_of_sites_to_pay = 5 ledger_desc = '' quotient, remainder = divmod(number_of_sites_after_deduction, min_num_of_sites_to_pay) number_of_sites_calculate = quotient * min_num_of_sites_to_pay + min_num_of_sites_to_pay if remainder else quotient * min_num_of_sites_to_pay number_of_sites_to_add_as_remainder = number_of_sites_calculate - number_of_sites_after_deduction application_price = site_category.retrieve_current_fee_per_site_by_type( new_or_renewal) # Avoid ledger error # ledger doesn't accept quantity=0). Alternatively, set quantity=1 and price=0 if number_of_sites_calculate == 0: number_of_sites_calculate = len(relations) application_price = 0 line_item = { 'ledger_description': ledger_desc, 'oracle_code': proposal.application_type.oracle_code_application, 'price_incl_tax': application_price, 'price_excl_tax': application_price if proposal.application_type.is_gst_exempt else calculate_excl_gst(application_price), 'quantity': number_of_sites_calculate, } line_items.append(line_item) # Add remainders site_remainder_to_be_added = _get_remainders_obj( number_of_sites_to_add_as_remainder, site_category.id, proposal, new_or_renewal) db_process_after_success['site_remainder_to_be_added'].extend( site_remainder_to_be_added) return line_items, db_process_after_success
def create_fee_lines(instance, invoice_text=None, vouchers=[], internal=False): """ Create the ledger lines - line item for application fee sent to payment system """ # Any changes to the DB should be made after the success of payment process db_processes_after_success = {} if isinstance(instance, Proposal): application_type = instance.application_type vessel_length = instance.vessel_details.vessel_applicable_length proposal_type = instance.proposal_type elif isinstance(instance, DcvPermit): application_type = ApplicationType.objects.get( code=settings.APPLICATION_TYPE_DCV_PERMIT['code']) vessel_length = 1 # any number greater than 0 proposal_type = None target_datetime = datetime.now(pytz.timezone(TIME_ZONE)) target_date = target_datetime.date() target_datetime_str = target_datetime.astimezone( pytz.timezone(TIME_ZONE)).strftime('%d/%m/%Y %I:%M %p') # Retrieve FeeItem object from FeeConstructor object if isinstance(instance, Proposal): fee_constructor = FeeConstructor.get_fee_constructor_by_application_type_and_date( application_type, target_date) if not fee_constructor: # Fees have not been configured for this application type and date raise Exception( 'FeeConstructor object for the ApplicationType: {} not found for the date: {}' .format(application_type, target_date)) elif isinstance(instance, DcvPermit): fee_constructor = FeeConstructor.get_fee_constructor_by_application_type_and_season( application_type, instance.fee_season) if not fee_constructor: # Fees have not been configured for this application type and date raise Exception( 'FeeConstructor object for the ApplicationType: {} and the Season: {}' .format(application_type, instance.fee_season)) else: raise Exception('Something went wrong when calculating the fee') fee_item = fee_constructor.get_fee_item(vessel_length, proposal_type, target_date) db_processes_after_success['fee_item_id'] = fee_item.id db_processes_after_success['fee_constructor_id'] = fee_constructor.id db_processes_after_success[ 'season_start_date'] = fee_constructor.fee_season.start_date.__str__() db_processes_after_success[ 'season_end_date'] = fee_constructor.fee_season.end_date.__str__() db_processes_after_success[ 'datetime_for_calculating_fee'] = target_datetime.__str__() line_items = [ { 'ledger_description': '{} Fee: {} (Season: {} to {}) @{}'.format( fee_constructor.application_type.description, instance.lodgement_number, fee_constructor.fee_season.start_date.strftime('%d/%m/%Y'), fee_constructor.fee_season.end_date.strftime('%d/%m/%Y'), target_datetime_str, ), # 'oracle_code': application_type.oracle_code, 'oracle_code': ApplicationType.get_current_oracle_code_by_application( application_type.code), 'price_incl_tax': fee_item.amount, 'price_excl_tax': calculate_excl_gst(fee_item.amount) if fee_constructor.incur_gst else fee_item.amount, 'quantity': 1, }, ] logger.info('{}'.format(line_items)) return line_items, db_processes_after_success
def create_filming_fee_lines(proposal, invoice_text=None, vouchers=[], internal=False): if 'motion_film' in proposal.filming_activity.film_type: # Filming (and perhaps Photography) desc = 'Filming/Photography' if proposal.filming_licence_charge_type == proposal.HALF_DAY_CHARGE: licence_fee = proposal.application_type.filming_fee_half_day licence_text = 'Half day' elif proposal.filming_licence_charge_type == proposal.FULL_DAY_CHARGE: licence_fee = proposal.application_type.filming_fee_full_day licence_text = 'Full day' elif proposal.filming_licence_charge_type == proposal.TWO_DAYS_CHARGE: licence_fee = proposal.application_type.filming_fee_2days licence_text = 'Two days' elif proposal.filming_licence_charge_type == proposal.THREE_OR_MORE_DAYS_CHARGE: licence_fee = proposal.application_type.filming_fee_3days licence_text = 'Three days or more' elif proposal.filming_licence_charge_type == proposal.NON_STANDARD_CHARGE: licence_fee = proposal.filming_non_standard_charge licence_text = 'Non-standard charge' else: raise Exception('Unknown filming charge type') else: # Photography desc = 'Photography' if proposal.filming_licence_charge_type == proposal.HALF_DAY_CHARGE: licence_fee = proposal.application_type.photography_fee_half_day licence_text = 'Half day' elif proposal.filming_licence_charge_type == proposal.FULL_DAY_CHARGE: licence_fee = proposal.application_type.photography_fee_full_day licence_text = 'Full day' elif proposal.filming_licence_charge_type == proposal.TWO_DAYS_CHARGE: licence_fee = proposal.application_type.photography_fee_2days licence_text = 'Two days' elif proposal.filming_licence_charge_type == proposal.THREE_OR_MORE_DAYS_CHARGE: licence_fee = proposal.application_type.photography_fee_3days licence_text = 'Three days or more' elif proposal.filming_licence_charge_type == proposal.NON_STANDARD_CHARGE: licence_fee = proposal.filming_non_standard_charge licence_text = 'Non-standard charge' else: raise Exception('Unknown filming charge type') application_fee = proposal.application_type.application_fee filming_period = '{} - {}'.format( proposal.filming_activity.commencement_date, proposal.filming_activity.completion_date) lines = [ { 'ledger_description': '{} Application Fee - {}'.format(desc, proposal.lodgement_number), 'oracle_code': proposal.application_type.oracle_code_licence, 'price_incl_tax': str(application_fee), 'price_excl_tax': str(application_fee) if proposal.application_type.is_gst_exempt else str(calculate_excl_gst(application_fee)), 'quantity': 1 }, { 'ledger_description': '{} Licence Fee ({} - {}) - {}'.format(desc, licence_text, filming_period, proposal.lodgement_number), 'oracle_code': proposal.application_type.oracle_code_licence, 'price_incl_tax': str(licence_fee), 'price_excl_tax': str(licence_fee) if proposal.application_type.is_gst_exempt else str(calculate_excl_gst(licence_fee)), 'quantity': 1 }, ] return lines