import json import random import datetime from django.shortcuts import redirect from django.contrib import messages from django.utils import timezone from django_ledger.models.entity import UnitOfMeasureModel from django_ledger.models.journal_entry import JournalEntryModel from django_ledger.models.ledger import LedgerModel from django_ledger.models.transactions import TransactionModel import requests from inventory import models from django.conf import settings from django.core.mail import send_mail from django.utils.translation import gettext_lazy as _ from inventory.utilities.financials import get_financial_value from django_ledger.models.items import ItemModel from django_ledger.models import InvoiceModel, EstimateModel,BillModel from decimal import Decimal def get_jwt_token(): url = "https://carapi.app/api/auth/login" headers = { "accept": "text/plain", "Content-Type": "application/json", } data = { "api_token": "f5204a00-6f31-4de2-96d8-ed998e0d230c", "api_secret": "8c11320781a5b8f4f327b6937e6f8241", } try: response = requests.post(url, headers=headers, json=data) response.raise_for_status() return response.text except requests.exceptions.RequestException as e: print(f"Error obtaining JWT token: {e}") return None def localize_some_words(): success = _("success") error = _("error") forget = _("Forgot Password?") return None def get_calculations(quotation): context = {} qc_len = quotation.quotation_cars.count() cars = [x.car for x in quotation.quotation_cars.all()] finances = models.CarFinance.objects.filter(car__in=cars) services = ItemModel.objects.filter(additional_finances__in=finances).all() data = [ { "name": x.name, "price": x.default_amount, "total_price": x.default_amount * qc_len, "vated": float(x.default_amount) * 0.15 * float(qc_len), "total_price_vat": float(x.default_amount) + (float(x.default_amount) * 0.15 * float(qc_len)), } for x in services ] context["services"] = data context["total_cost"] = 0 context["total_vat"] = 0 context["total_cost_vat"] = 0 for k in context["services"]: context["total_cost"] += k["total_price"] context["total_vat"] += k["vated"] context["total_cost_vat"] = float(context["total_cost"]) + float( context["total_vat"] ) return context def send_email(from_, to_, subject, message): subject = subject message = message from_email = from_ recipient_list = [to_] send_mail(subject, message, from_email, recipient_list) def get_user_type(request): dealer = "" if hasattr(request.user, "dealer"): dealer = request.user.dealer elif hasattr(request.user, "staff"): dealer = request.user.staff.dealer return dealer def get_dealer_from_instance(instance): if instance.dealer.staff: return instance.dealer else: return instance.dealer def reserve_car(car, request): try: reserved_until = timezone.now() + timezone.timedelta(hours=24) models.CarReservation.objects.create( car=car, reserved_by=request.user, reserved_until=reserved_until ) car.status = models.CarStatusChoices.RESERVED car.save() messages.success(request, _("Car reserved successfully.")) except Exception as e: messages.error(request, f"Error reserving car: {e}") return redirect("car_detail", pk=car.pk) def calculate_vat_amount(amount): vat = models.VatRate.objects.filter(is_active=True).first() if vat: return ((amount * Decimal(vat.rate)).quantize(Decimal("0.01")), vat.rate) return amount def get_financial_values(model): vat = models.VatRate.objects.filter(is_active=True).first() if not model.get_itemtxs_data()[0].exists(): return { "vat_amount": 0, "total": 0, "grand_total": 0, "discount_amount": 0, "vat": 0, "car_and_item_info": [], "additional_services": [], } data = model.get_itemtxs_data()[0].all() if isinstance(model, InvoiceModel): data = model.ce_model.get_itemtxs_data()[0].all() car_and_item_info = [ { "car": models.Car.objects.get(vin=x.item_model.name), "total": models.Car.objects.get( vin=x.item_model.name ).finances.selling_price * Decimal(x.ce_quantity), "itemmodel": x, } for x in data ] total = sum( Decimal(models.Car.objects.get(vin=x.item_model.name).finances.total) * Decimal(x.ce_quantity) for x in data ) discount_amount = sum( models.CarFinance.objects.get(car__vin=i.item_model.name).discount_amount for i in data ) additional_services = [] for i in data: cf = models.CarFinance.objects.get(car__vin=i.item_model.name) if cf.additional_services.exists(): additional_services.extend( [ {"name": x.name, "price": x.price} for x in cf.additional_services.all() ] ) grand_total = Decimal(total) - Decimal(discount_amount) vat_amount = round(Decimal(grand_total) * Decimal(vat.rate), 2) return { "car_and_item_info": car_and_item_info, "total": total, "discount_amount": discount_amount, "additional_services": additional_services, "grand_total": grand_total + vat_amount, "vat_amount": vat_amount, "vat": vat.rate, } def set_invoice_payment(dealer, entity, invoice, amount, payment_method): vat_amount = 0 total_amount = 0 if invoice.terms == "on_receipt": for x in invoice.get_itemtxs_data()[0].all(): vat_amount += models.Car.objects.get( vin=x.item_model.name ).finances.vat_amount * Decimal(x.quantity) total_amount += Decimal(x.unit_cost) * Decimal(x.quantity) grand_total = total_amount - Decimal(vat_amount) ledger = LedgerModel.objects.filter( name__icontains=str(invoice.pk), entity=entity ).first() journal = JournalEntryModel.objects.create( posted=False, description=f"Payment for Invoice {invoice.invoice_number}", ledger=ledger, locked=False, origin="Payment", ) credit_account = entity.get_default_coa_accounts().get(name="Sales Revenue") debit_account = None if payment_method == "cash": debit_account = entity.get_default_coa_accounts().get(name="Cash", active=True) elif payment_method == "credit": debit_account = entity.get_default_coa_accounts().get( name="Accounts Receivable", active=True ) else: debit_account = entity.get_default_coa_accounts().get( name="Cash in Bank", active=True ) vat_payable_account = entity.get_default_coa_accounts().get( name="VAT Payable", active=True ) TransactionModel.objects.create( journal_entry=journal, account=debit_account, # Debit Cash amount=amount, # Payment amount tx_type="debit", description="Payment Received", ) TransactionModel.objects.create( journal_entry=journal, account=credit_account, # Credit Accounts Receivable amount=grand_total, # Payment amount tx_type="credit", description="Payment Received", ) if vat_amount > 0: TransactionModel.objects.create( journal_entry=journal, account=vat_payable_account, # Credit VAT Payable amount=vat_amount, tx_type="credit", description="VAT Payable on Invoice", ) invoice.make_payment(amount) invoice.save() def set_bill_payment(dealer, entity, bill, amount, payment_method): total_amount = 0 for x in bill.get_itemtxs_data()[0].all(): total_amount += Decimal(x.unit_cost) * Decimal(x.quantity) journal = JournalEntryModel.objects.create( posted=False, description=f"Payment for bill {bill.bill_number}", ledger=bill.ledger, locked=False, origin="Payment", ) cash_account = entity.get_default_coa_accounts().get(name="Cash", active=True) account_payable = entity.get_default_coa_accounts().get( name="Accounts Payable", active=True ) TransactionModel.objects.create( journal_entry=journal, account=cash_account, # Debit Cash amount=amount, # Payment amount tx_type="debit", description="Payment Received", ) TransactionModel.objects.create( journal_entry=journal, account=account_payable, # Credit Accounts Receivable amount=amount, # Payment amount tx_type="credit", description="Payment Received", ) bill.make_payment(amount) bill.save() def transfer_to_dealer(request,cars, to_dealer, remarks=None): dealer = get_user_type(request) if not cars: raise ValueError("No cars selected for transfer.") from_dealer = cars[0].dealer # Assume all cars are from the same dealer # Validate that all cars are from the same dealer for car in cars: if car.dealer != from_dealer: raise ValueError("All cars must be from the same dealer.") if from_dealer == to_dealer: raise ValueError("Cannot transfer cars to the same dealer.") # Log the transfer transfer_log = models.CarTransferLog.objects.create( from_dealer=from_dealer, to_dealer=to_dealer, remarks=remarks, ) transfer_log.cars.set(cars) # Associate the cars with the transfer log # Update the dealer for all cars for car in cars: car.dealer = to_dealer car.save() def transfer_car(car,transfer): from_dealer = transfer.from_dealer to_dealer = transfer.to_dealer # add transfer.to_dealer as customer in transfer.from_dealer entity instance = models.Customer.objects.filter( dealer=from_dealer, email=to_dealer.user.email, ).first() if not instance: instance = models.Customer.objects.create( dealer=from_dealer, title=models.Title.MR, email=to_dealer.user.email, first_name=to_dealer.user.first_name, last_name=to_dealer.user.last_name, phone_number=f"05685412{random.randint(10, 99)}", address=to_dealer.address, national_id=f"{random.randint(100, 9999)}", dob="1990-01-01", ) # create invoice from transfer.from_dealer to transfer.to_dealer name = f"{instance.first_name} {instance.middle_name} {instance.last_name}" customer = from_dealer.entity.get_customers().filter(customer_name=name).first() invoice = from_dealer.entity.create_invoice( customer_model=customer, terms=InvoiceModel.TERMS_NET_30, cash_account=from_dealer.entity.get_default_coa_accounts().get(name="Cash", active=True), prepaid_account=from_dealer.entity.get_default_coa_accounts().get(name="Accounts Receivable", active=True), coa_model=from_dealer.entity.get_default_coa(), ) ledger = from_dealer.entity.create_ledger(name=str(invoice.pk)) invoice.ledgar = ledger ledger.invoicemodel = invoice ledger.save() invoice.save() item = from_dealer.entity.get_items_products().filter(name=car.vin).first() if not item: return invoice_itemtxs = { item.item_number: { "unit_cost": car.finances.cost_price, "quantity": transfer.quantity, "total_amount": transfer.total_price, } } invoice_itemtxs = invoice.migrate_itemtxs( itemtxs=invoice_itemtxs, commit=True, operation=InvoiceModel.ITEMIZE_APPEND, ) invoice.mark_as_review() invoice.mark_as_approved(from_dealer.entity.slug, from_dealer.entity.admin) invoice.mark_as_paid(from_dealer.entity.slug, from_dealer.entity.admin) invoice.save() #create car item product in to_dealer entity uom = to_dealer.entity.get_uom_all().filter(name=item.uom.name).first() product = to_dealer.entity.create_item_product( name=item.name, uom_model=uom, item_type=item.item_type, coa_model=to_dealer.entity.get_default_coa(), ) car_dict = vars(car).copy() del car_dict["_state"] for key, value in car_dict.items(): if isinstance(value, datetime.datetime): car_dict[key] = value.strftime('%Y-%m-%d %H:%M:%S') product.additional_info = json.dumps({"car_info": car_dict}) product.save() #add the sender as vendor and create a bill for it vendor_instance, created = models.Vendor.objects.get_or_create( dealer=to_dealer, crn=from_dealer.crn, vrn=from_dealer.vrn, name=from_dealer.name, email=from_dealer.user.email, arabic_name=from_dealer.arabic_name, address=from_dealer.address, phone_number=from_dealer.phone_number, contact_person='', ) #transfer the car to to_dealer and create items record vendor = to_dealer.entity.get_vendors().filter(vendor_name=vendor_instance.name).first() bill = to_dealer.entity.create_bill( vendor_model=vendor, terms=BillModel.TERMS_NET_30, cash_account=to_dealer.entity.get_default_coa_accounts().get(name="Cash", active=True), prepaid_account=to_dealer.entity.get_default_coa_accounts().get(name="Prepaid Expenses", active=True), coa_model=to_dealer.entity.get_default_coa(), ) bill_itemtxs = { item.item_number: { "unit_cost": car.finances.cost_price, "quantity": transfer.quantity, "total_amount": transfer.total_price, } } bill_itemtxs = bill.migrate_itemtxs(itemtxs=bill_itemtxs, commit=True, operation=BillModel.ITEMIZE_REPLACE) car.dealer = to_dealer car.vendor = vendor_instance car.receiving_date = datetime.datetime.now() car.finances.additional_services.clear() if hasattr(car, "custom_cards"): car.custom_cards.delete() # car.finances.cost_price = 0 car.finances.selling_price = 0 car.finances.discount_amount = 0 car.finances.save() car.location.owner = to_dealer car.location.showroom = to_dealer car.location.description = "" car.location.save() # car.reservations.all().delete() car.status = models.CarStatusChoices.AVAILABLE transfer.status = models.CarTransferStatusChoices.success transfer.active = False transfer.save() car.save() return True #pay the pill # set_bill_payment(to_dealer,to_dealer.entity,bill,transfer.total_price,"credit")