class InvoiceDetail(APIView): """ Retrieve, update or delete a casting request of client. """ def get_object(self, pk): try: return Invoice.objects.get(pk=pk) except Invoice.DoesNotExist: raise Http404 @swagger_auto_schema(responses={200: InvoiceSerializer(many=False)}) def get(self, request, pk, format=None): invoice = self.get_object(pk) serializer = InvoiceSerializer(invoice) return Response(serializer.data) @swagger_auto_schema(responses={200: InvoiceSerializer(many=False)}) def put(self, request, pk, format=None): invoice = self.get_object(pk) serializer = InvoiceSerializer(invoice, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response({'error': serializer.errors}, status=status.HTTP_400_BAD_REQUEST) @swagger_auto_schema(responses={200: 'OK'}) def delete(self, request, pk, format=None): invoice = self.get_object(pk) invoice.delete() return Response({'id': int(pk)}, status=status.HTTP_200_OK)
def invoice_detail(request, pk): """ get ,delete ,put inovice by id """ if request.method == 'GET': invoice = Invoice.objects.filter(id=pk) transactions = Transaction.objects.filter(invoice_id=pk) if invoice: invoice[0].transactions = transactions else: return Response({'error': 'no data found'}, status=status.HTTP_201_CREATED) serializer = InvoiceGetSerializer(invoice, many=True) return Response(serializer.data, status=status.HTTP_201_CREATED) elif request.method == 'DELETE': transactions = Transaction.objects.filter(invoice_id=pk) transactions.delete() invoice = Invoice.objects.filter(id=pk) invoice.delete() return Response({'deleted': 'success'}, status=status.HTTP_201_CREATED) elif request.method == 'PUT': serializer = InvoiceSerializer(data=request.data) data = request.data if serializer.is_valid(): save = InvoiceSerializer(data=data) save.create(request.data, request.method) return Response(serializer.data, status=status.HTTP_201_CREATED)
def invoice_list(request): """ list of all invoice or create new invoice """ if request.method == 'GET': invoices = Invoice.objects.all() for invoice in invoices: transactions = Transaction.objects.filter(invoice_id=invoice.id) invoice.transactions = transactions serializer = InvoiceGetSerializer(invoices, many=True) return Response(serializer.data, status=status.HTTP_201_CREATED) elif request.method == 'POST': serializer = InvoiceSerializer(data=request.data) data = request.data if serializer.is_valid(): save = InvoiceSerializer(data=data) save.create(request.data, request.method) return Response(serializer.data, status=status.HTTP_201_CREATED) else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def post(self, request, format=None): serializer = InvoiceSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def put(self, request, pk, format=None): invoice = self.get_object(pk) serializer = InvoiceSerializer(invoice, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response({'error': serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
def put(self, request, invoice_id, format=None): invoice = Invoice.objects.get(id=invoice_id) serializer = InvoiceSerializer(invoice, data=request.data) if serializer.is_valid(): serializer.save() return Response('') return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class InvoiceBulkCreate(APIView): """ Create invoices for each casting_request_talent """ # def get_object(self, user): # try: # user = User.objects.get(pk=user.pk) # client = Client.objects.get(user=user.id) # return client # except Client.DoesNotExist: # raise Http404 @swagger_auto_schema(request_body=InvoiceCreateSerializer(many=True), responses={200: InvoiceSerializer(many=True)}) def post(self, request, format=None): # client = self.get_object(request.user) serializer = InvoiceCreateSerializer(data=request.data, many=True) if serializer.is_valid(): new_crt_ids = [] for invoice_data in serializer.validated_data: new_invoice = Invoice(**invoice_data) new_invoice.save() new_crt_ids.append(new_invoice.id) new_invoices = Invoice.objects.all().filter(id__in=new_crt_ids) new_serializer = InvoiceSerializer(new_invoices, many=True) return Response(new_serializer.data, status=status.HTTP_201_CREATED) return Response({'error': serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
def test_partial_update_invoice_items_success(self): data = { "invoice_items": [{ "name": "item 1", "description": "foo", "quantity": 10, "price": 100, "amount": 1000 }, { "name": "item 2", "description": "bar", "quantity": 5, "price": 100, "amount": 500 }, { "name": "item 3", "description": "foo bar", "quantity": 15, "price": 100, "amount": 1500 }] } self.assertEqual(len(self.invoice.invoice_items.all()), 2) response = self.client.patch(path=self.url, data=data, format='json', HTTP_ACCEPT='application/json') api_response = json.loads(response.content) self.invoice.refresh_from_db() expected_response = json.loads( JsonResponse(InvoiceSerializer(self.invoice).data).content) self.assertEqual(api_response, expected_response) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(api_response['invoice_items']), 3)
def test_digitized_invoice(self): response = self.client.get(path=self.url, HTTP_ACCEPT='application/json') api_response = json.loads(response.content) expected_response = json.loads( JsonResponse(InvoiceSerializer(self.invoice).data).content) self.assertEqual(api_response, expected_response) self.assertEqual(api_response['digitized'], True)
class InvoiceList(APIView): """ Retrieve all invoices of client. """ @swagger_auto_schema(responses={200: InvoiceSerializer(many=True)}) def get(self, request, format=None): user = User.objects.get(pk=request.user.pk) invoices = Invoice.objects.all serializer = InvoiceSerializer(invoices, many=True) return Response(serializer.data)
def test_retrieve_superuser(self): invoice = Invoice.objects.get(invoice_number='INV12345') url = reverse('invoices-detail', args=(invoice.pk, )) self.user.is_superuser = True self.user.save() response = self.client.get(path=url, HTTP_ACCEPT='application/json') api_response = json.loads(response.content) expected_response = json.loads( JsonResponse(InvoiceSerializer(invoice).data).content) self.assertEqual(api_response, expected_response) self.assertEqual(api_response['digitized'], False)
def handle(self, *args, **options): sent_invoices = Invoice.objects.filter(status='sent') paid_invoices = Invoice.objects.filter(status='paid') for invoice in sent_invoices: data = InvoiceSerializer(invoice).data summarized = [{"id": appt.get('id')} \ for appt \ in data.get('context',{}).get('appointments')] data.update({"context": { "appointments": summarized } }) publish(settings.PUBLISHKEYS.invoice_sent, data) for invoice in paid_invoices: data = InvoiceSerializer(invoice).data summarized = [{"id": appt.get('id')} \ for appt \ in data.get('context',{}).get('appointments')] data.update({"context": { "appointments": summarized } }) publish(settings.PUBLISHKEYS.invoice_paid, data)
def test_upload_api(self): invoice = SimpleUploadedFile("invoice.pdf", b"file_content", content_type="application/pdf") data = {'invoice': invoice} response = self.client.post(path=self.url, data=data, format='multipart', HTTP_ACCEPT='application/json') invoice_object = Invoice.objects.first() self.assertEqual( response.content, JsonResponse(InvoiceSerializer(invoice_object).data).content)
def test_partial_update_invoice_number_success(self): data = {'invoice_number': 'TestInvoice123'} response = self.client.patch(path=self.url, data=data, format='json', HTTP_ACCEPT='application/json') api_response = json.loads(response.content) self.invoice.refresh_from_db() expected_response = json.loads( JsonResponse(InvoiceSerializer(self.invoice).data).content) self.assertEqual(api_response, expected_response) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(api_response['invoice_number'], 'TestInvoice123')
def test_create_invoice_success(self): response = self.client.post(path=self.url, data=self.data, format='json', HTTP_ACCEPT='application/json') api_response = json.loads(response.content) invoice = Invoice.objects.get(invoice_number='TestInvoice123') expected_response = json.loads( JsonResponse(InvoiceSerializer(invoice).data).content) self.assertEqual(api_response, expected_response) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(len(api_response['invoice_items']), 2) self.assertEqual(api_response['total'], 1500)
def test_update_invoice_success(self): response = self.client.put(path=self.url, data=self.data, format='json', HTTP_ACCEPT='application/json') api_response = json.loads(response.content) self.invoice.refresh_from_db() expected_response = json.loads( JsonResponse(InvoiceSerializer(self.invoice).data).content) self.assertEqual(api_response, expected_response) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(api_response['invoice_items']), 3) self.assertEqual(api_response['total'], 3000)
def invoice_list_api(request): if request.method == 'GET': invoices = Invoice.objects.all() serializer = InvoiceSerializer(invoices, many=True) return Response(serializer.data) elif request.method == 'POST': serializer = InvoiceSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class OrderSerializer(serializers.ModelSerializer): Invoice = InvoiceSerializer(many=True, required=False) class Meta: model = Order fields = ( "id", "date", "contract_number", "sum", "company", "user", "Invoice", )
def create(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) if not serializer.is_valid(): return Response( [str(serializer.errors)], status=status.HTTP_400_BAD_REQUEST, ) invoice = self.perform_create(serializer, request.user) return Response( InvoiceSerializer(invoice).data, status=status.HTTP_201_CREATED, )
def post(self, request, format=None): # client = self.get_object(request.user) serializer = InvoiceCreateSerializer(data=request.data, many=True) if serializer.is_valid(): new_crt_ids = [] for invoice_data in serializer.validated_data: new_invoice = Invoice(**invoice_data) new_invoice.save() new_crt_ids.append(new_invoice.id) new_invoices = Invoice.objects.all().filter(id__in=new_crt_ids) new_serializer = InvoiceSerializer(new_invoices, many=True) return Response(new_serializer.data, status=status.HTTP_201_CREATED) return Response({'error': serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
def invoice_detail_api(request, pk): try: invoice = Invoice.objects.get(pk=pk) except invoice.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) if request.method == 'GET': serializer = InvoiceSerializer(invoices) return Response(serializer.data) elif request.method == 'PUT': serializer = InvoiceSerializer(status, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class EnrollmentSerializer(serializers.ModelSerializer): invoice_list = InvoiceSerializer(read_only=True, many=True) class Meta: model = Enrollment fields = ( "id", "student", "course", "payment_list", "enrollment_balance", "sessions_left", "last_paid_session_datetime", ) read_only_fields = [ "id", "enrollment_balance", "sessions_left", "last_paid_session_datetime", ]
def update(self, instance, validated_data): # update the sales sales agent validated_data['sales_agent'] = self.context['request'].user order_hierarchy = { "ordered": 0, "accepted": 1, "delivered": 2, "cancelled": 2 } status = validated_data['status'] if instance.status not in order_hierarchy or status not in order_hierarchy: exc_msg = f"Cannot update the order status to {status}" raise exceptions.ValidationError(exc_msg) if order_hierarchy[status] - order_hierarchy[instance.status] != 1: exc_msg = f"Cannot update the order status from {instance.status} to {status}" raise exceptions.ValidationError(exc_msg) # If changing an order status to accepted, add an invoice and a financial ledger if status in ["accepted"]: # create an invoice invoice_data = { "order": instance.id, "customer": instance.customer.id, "sales_agent": self.context['request'].user.id, "invoice_total": sum([a.total_cost for a in instance.order_items.all()]) } invoice_ser = InvoiceSerializer(data=invoice_data) invoice_ser.is_valid(raise_exception=True) inv = invoice_ser.save() # create a financial ledger # get previous balance for the customer ledgers = FinancialLedger.objects.filter( customer=instance.customer).order_by('-id') if not ledgers: previous_balance = 0 else: previous_balance = ledgers[0].balance ledger_data = { "order": instance.id, "customer": instance.customer.id, "amount": inv.invoice_total, "balance": previous_balance + inv.invoice_total } fl_ser = FinancialLedgerSerializer(data=ledger_data) fl_ser.is_valid(raise_exception=True) fl_ser.save() # TODO: send an SMS to the customer asynchronously print("SMS sent") # if updating an order status to cancelled from accepted, # add a reverse financial ledger entry if instance.status == "accepted" and status == "cancelled": # create a reverse financial ledger # get previous balance for the customer ledgers = FinancialLedger.objects.filter( customer=instance.customer).order_by('-id') if not ledgers: previous_balance = 0 else: previous_balance = ledgers[0].balance amount = -1 * sum( [a.total_cost for a in instance.order_items.all()]) ledger_data = { "order": instance.id, "customer": instance.customer.id, "amount": amount, "balance": previous_balance + amount } fl_ser = FinancialLedgerSerializer(data=ledger_data) fl_ser.is_valid(raise_exception=True) fl_ser.save() return super(OrderSerializer, self).update(instance, validated_data)
def get(self, request, format=None): user = User.objects.get(pk=request.user.pk) invoices = Invoice.objects.all serializer = InvoiceSerializer(invoices, many=True) return Response(serializer.data)
def get(self, request, pk, format=None): invoice = self.get_object(pk) serializer = InvoiceSerializer(invoice) return Response(serializer.data)
def get(self, request, invoice_id, format=None): invoice = Invoice.objects.get(id=invoice_id) invoice_serializer = InvoiceSerializer(invoice) return Response(invoice_serializer.data, status=status.HTTP_200_OK)
def get(self, request, format=None): invoice_list = Invoice.objects.all() invoice_list_serializer = InvoiceSerializer(invoice_list, many=True) return Response(invoice_list_serializer.data, status=status.HTTP_200_OK)
def mutate(root, info, **validated_data): data = validated_data if data.get("pay_now", False) and data["method"] != "credit_card": # only admins may create a cash/check invoice to be paid now if not Admin.objects.filter(user__id=info.context.user.id).exists(): raise GraphQLError( "Failed Mutation. Only Admins may create cash/check invoices to be paid now." ) # update invoice if data.get("invoice_id"): # only admins may update an invoice if not Admin.objects.filter(user__id=info.context.user.id).exists(): raise GraphQLError("Failed Mutation. Only Admins may update Invoices.") # can only update method or payment_status updatedData = { key: data[key] for key in ("method", "payment_status") if key in data } # update invoice = Invoice.objects.get(id=data.pop("invoice_id")) Invoice.objects.filter(id=invoice.id).update(**updatedData) invoice.refresh_from_db() operation = CHANGE else: # compute price quote data.update(price_quote_total(data)) discounts = data.pop("discounts") data["deductions"] = [] for discount in discounts: data["deductions"].append( {"discount": discount["id"], "amount": discount["amount"]} ) serializer = InvoiceSerializer( data=data, context={"user_id": info.context.user.id} ) serializer.is_valid(raise_exception=True) invoice = serializer.save() operation = ADDITION # log operation LogEntry.objects.log_action( user_id=info.context.user.id, content_type_id=ContentType.objects.get_for_model(Invoice).pk, object_id=invoice.id, object_repr=f"{invoice.parent.user.first_name} {invoice.parent.user.last_name}, {invoice.method}", action_flag=operation, ) # stripe integration stripe_checkout_id = None if data.get("pay_now", False) and data["method"] == "credit_card": invoice.payment_due_date = arrow.utcnow().date() invoice.save() stripe.api_key = settings.STRIPE_API_KEY line_items = [] for registration in invoice.registration_set.all(): enrollment = registration.enrollment course = enrollment.course line_items.append( { "name": course.title, "amount": round( course.total_tuition * registration.num_sessions / course.num_sessions ), "currency": "usd", "quantity": 1, } ) session = stripe.checkout.Session.create( payment_method_types=["card"], line_items=line_items, success_url=f"http://localhost:3000/registration/receipt/{invoice.id}/", cancel_url="http://localhost:3000/registration/cart/", stripe_account="acct_1HqSAYETk4EmXsx3", ) stripe_checkout_id = session.id elif data.get("pay_now", False) and ( data["method"] == "cash" or data["method"] == "check" ): invoice.payment_status = "paid" invoice.payment_method = data["method"] invoice.save() else: # unpaid flow invoice.payment_due_date = arrow.utcnow().shift(days=5).date() invoice.save() return CreateInvoice( invoice=invoice, stripe_connected_account="acct_1HqSAYETk4EmXsx3", stripe_checkout_id=stripe_checkout_id, created=True, )