from django.db import models
from ledgers.models import *
from customers.models import Customer, GroupMembership
from ledgers.models import SystemTransactions, OrganisationSubAccount, Currencies
from organisations.models import *
from users.models import Staff
from django.conf import settings
from .data import blocking_type_options


# Create your models here.
class SavingsProduct(models.Model):
    product_name = models.CharField(max_length=255)
    opening_balance = models.FloatField(null=False, default=0)
    max_balance = models.FloatField(null=False, default=0)
    min_balance = models.FloatField(null=False, default=0)
    currency = models.ForeignKey(
        Currencies,
        on_delete=models.CASCADE,
        related_name="savings_product_currency",
        null=False,
        blank=False,
        default=1,
    )
    dormancy_period = models.IntegerField(null=False, default=24)
    deactivation_period = models.IntegerField(null=False, default=12)
    activation_period = models.IntegerField(null=False, default=12)
    account_closure_fee = models.FloatField(null=False, default=0)
    default_charge_type = models.CharField(max_length=50, default="flat")
    ledger_fees_frequency = models.CharField(max_length=50, default="annually")
    max_withdraws = models.FloatField(null=False, default=0)
    min_withdraws = models.FloatField(null=False, default=0)
    max_withdraw_per_day = models.IntegerField(null=False, default=0)
    no_of_withdraws = models.IntegerField(null=False, default=0)
    no_of_withdraws_per = models.CharField(max_length=50, default="monthly")
    deposit_custom_charge = models.BooleanField(default=False)
    withdraw_custom_charge = models.BooleanField(default=False)
    transfer_custom_charge = models.BooleanField(default=False)
    accounts_chart = models.ForeignKey(
        OrganisationSubAccount,
        on_delete=models.CASCADE,
        related_name="savings_product_account",
        null=True,
        blank=True,
    )
    saving_product_org = models.ForeignKey(
        Organisation,
        on_delete=models.CASCADE,
        related_name="organisation_savings_product",
        null=True,
        blank=True,
    )
    saving_product_added_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="saving_product_added_by",
        null=True,
    )
    is_active = models.BooleanField(default=True)
    deleted = models.BooleanField(default=False)
    deleted_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_records_savings_1')
    deleted_at = models.DateTimeField(null=True, blank=True)
    date_added = models.DateTimeField(default=timezone.now)
    last_updated = models.DateTimeField(default=timezone.now)
    max_withdraw_limit_charge_type = models.CharField(max_length=50, default="flat")

    class Meta:
        db_table = 'public"."savings_product'

    def __str__(self):
        return self.product_name


class SavingProductCharge(models.Model):
    charge_key = models.CharField(max_length=255)
    charge_name = models.CharField(max_length=255)
    charge = models.FloatField(null=False)
    saving_product = models.ForeignKey(
        SavingsProduct,
        on_delete=models.CASCADE,
        related_name="product_charge_savings_product",
        null=True,
        blank=True,
    )
    charge_added_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="charge_added_by",
    )
    charge_last_updated_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="charge_last_updated_by",
        null=True,
        blank=True,
    )
    is_active = models.BooleanField(default=True)
    deleted = models.BooleanField(default=False)
    deleted_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_records_savings_2')
    deleted_at = models.DateTimeField(null=True, blank=True)
    date_added = models.DateTimeField(default=timezone.now)
    last_updated = models.DateTimeField(default=timezone.now)
    accounts_chart = models.ForeignKey(
        OrganisationSubAccount,
        on_delete=models.CASCADE,
        related_name="product_charge_account",
        null=True,
        blank=True,
    )

    class Meta:
        db_table = 'public"."savings_product_charge'


class SavingProductCustomCharge(models.Model):
    TRANSACTION_TYPES = (
        ("deposit_charge", "Charge On Deposit"),
        ("withdraw_charge", "Charge On Withdraw"),
        ("transfer_charge", "Charge On Transfer"),
        ("mm_deposit_charge", "Charge On Mobile Money Deposit"),
        ("mm_withdraw_charge", "Charge On Mobile Money Withdraw"),
    )
    CHARGE_TYPE = (
        ("percentage", "Percentage"),
        ("flat", "Flat"),
    )
    charge_name = models.CharField(max_length=155)
    transaction_type = models.CharField(max_length=155, choices=TRANSACTION_TYPES)
    charge = models.FloatField(default=0.0)
    min_value = models.FloatField(default=0.0)
    max_value = models.FloatField(default=0.0)
    charge_type = models.CharField(max_length=100, choices=CHARGE_TYPE)
    date_added = models.DateTimeField(default=timezone.now)
    last_updated = models.DateTimeField(default=timezone.now)
    saving_product = models.ForeignKey(
        SavingsProduct,
        on_delete=models.CASCADE,
        related_name="product_custom_charge_savings_product",
        null=True,
        blank=True,
    )
    charge_added_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="custom_charge_added_by",
    )
    last_updated_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="custom_charge_last_updated_by",
        null=True,
        blank=True,
    )
    deleted = models.BooleanField(default=False)
    deleted_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_records_savings_3')
    deleted_at = models.DateTimeField(null=True, blank=True)
    charge_chart = models.ForeignKey(
        OrganisationSubAccount,
        on_delete=models.CASCADE,
        related_name="product_charge_chart",
        null=True,
        blank=True,
    )

    class Meta:
        db_table = 'public"."savings_product_custom_charge'


class SavingProductInterest(models.Model):
    int_rate = models.FloatField(null=False)
    tax_on_int = models.FloatField(null=False)
    frequency = models.IntegerField(null=False, default=0)
    frequency_type = models.CharField(max_length=10)
    is_active = models.BooleanField(default=True)
    send_sms = models.BooleanField(default=False)
    deleted = models.BooleanField(default=False)
    deleted_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_records_savings_4')
    deleted_at = models.DateTimeField(null=True, blank=True)
    date_added = models.DateTimeField(default=timezone.now)
    last_updated = models.DateTimeField(default=timezone.now)
    min_balance = models.FloatField(null=False, default=0)
    start_date = models.DateTimeField(default=timezone.now)
    saving_product = models.ForeignKey(
        SavingsProduct,
        on_delete=models.CASCADE,
        related_name="product_interest_savings_product",
        null=True,
        blank=True,
    )
    accounts_chart = models.ForeignKey(
        OrganisationSubAccount,
        on_delete=models.CASCADE,
        related_name="product_interest_account",
        null=True,
        blank=True,
    )
    tax_chart = models.ForeignKey(
        OrganisationSubAccount,
        on_delete=models.CASCADE,
        related_name="product_interest_tax_chart",
        null=True,
        blank=True,
    )
    interest_added_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="interest_added_by",
    )
    interest_last_updated_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="interest_last_updated_by",
        null=True,
        blank=True,
    )

    class Meta:
        db_table = 'public"."savings_product_interest'


class SavingAccount(models.Model):
    ACCOUNT_STATUSES = (
        ("active", "Active"),
        ("inactive", "In Active"),
        ("dormant", "Dormant"),
        ("pending", "Pending"),
        ("closure_pending", "Closure Pending"),
        ("closed", "Closed"),
    )
    account_no = models.CharField(max_length=50, null=False)
    open_date = models.DateTimeField(default=timezone.now)
    date_added = models.DateTimeField(default=timezone.now)
    last_updated = models.DateTimeField(default=timezone.now)
    dormancy_date = models.DateTimeField(null=True)
    status = models.CharField(max_length=50, choices=ACCOUNT_STATUSES, default="active")
    is_active = models.BooleanField(default=True)
    deleted = models.BooleanField(default=False)
    deleted_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_records_savings_5')
    deleted_at = models.DateTimeField(null=True, blank=True)
    account_customer = models.ForeignKey(
        Customer, on_delete=models.CASCADE, related_name="account_customer"
    )
    account_product = models.ForeignKey(
        SavingsProduct,
        on_delete=models.CASCADE,
        related_name="saving_account_account_product",
        null=False,
        blank=False,
    )
    customer_branch = models.ForeignKey(
        OrganisationBranch,
        on_delete=models.CASCADE,
        related_name="saving_account_account_product",
        null=False,
        blank=False,
    )
    opened_by = models.ForeignKey(
        Staff,
        on_delete=models.CASCADE,
        related_name="saving_account_opened_by",
        null=True,
        blank=True,
    )
    saving_account_added_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="saving_account_added_by",
    )
    saving_account_last_updated_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="saving_account_last_updated_by",
        null=False,
        blank=False,
    )
    is_aml_withdrawal_blocked = models.BooleanField(default=False)
    aml_is_flagged = models.BooleanField(default=False)
    aml_blocked_at = models.DateTimeField(null=True, blank=True)
    aml_flagged_at = models.DateTimeField(null=True, blank=True)
    aml_threshold_amount = models.FloatField(default=0)
    aml_trigger_amount = models.FloatField(default=0)
    aml_trigger_transaction = models.ForeignKey(
        SystemTransactions,
        on_delete=models.SET_NULL,
        related_name="aml_triggered_saving_accounts",
        null=True,
        blank=True,
    )
    aml_block_reason = models.TextField(null=True, blank=True)

    class Meta:
        db_table = 'public"."saving_account'


class SavingsBlockedAmount(models.Model):
    amount = models.FloatField()
    block_type = models.CharField(max_length=50, choices=blocking_type_options)
    status = models.CharField(max_length=50, default="active")
    reason = models.TextField(null=False, blank=False)
    expiry_date = models.DateTimeField(default=timezone.now)
    manual_unblock = models.BooleanField(default=False)
    date_added = models.DateTimeField(default=timezone.now)
    last_updated = models.DateTimeField(default=timezone.now)
    deleted = models.BooleanField(default=False)
    deleted_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_records_savings_6')
    deleted_at = models.DateTimeField(null=True, blank=True)
    customer_account = models.ForeignKey(
        SavingAccount, on_delete=models.CASCADE, related_name="blocking_amount_customer"
    )
    customer_branch = models.ForeignKey(
        OrganisationBranch,
        on_delete=models.CASCADE,
        related_name="blocking_amount_branch",
        null=False,
        blank=False,
    )
    blocked_amount_added_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="blocked_amount_added_by",
    )
    blocked_amount_last_updated_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="blocked_amount_last_updated_by",
        null=False,
        blank=False,
    )

    class Meta:
        db_table = 'public"."savings_blocked_amount'


class SavingsAMLVerification(models.Model):
    saving_account = models.ForeignKey(
        SavingAccount,
        on_delete=models.CASCADE,
        related_name="aml_verifications",
    )
    source_of_income = models.TextField()
    supporting_document = models.URLField(
        max_length=555,
        null=True,
        blank=True,
    )
    threshold_amount = models.FloatField(default=0)
    trigger_amount = models.FloatField(default=0)
    block_reason = models.TextField(null=True, blank=True)
    blocked_at = models.DateTimeField(null=True, blank=True)
    trigger_transaction = models.ForeignKey(
        SystemTransactions,
        on_delete=models.SET_NULL,
        related_name="saving_account_aml_verifications",
        null=True,
        blank=True,
    )
    verified_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET_NULL,
        related_name="saving_account_aml_verified_by",
        null=True,
        blank=True,
    )
    verified_at = models.DateTimeField(default=timezone.now)

    class Meta:
        db_table = 'public"."saving_aml_verification'

    def __str__(self):
        return f"{self.saving_account.account_no} AML verification"


class SavingsProductInterestPayment(models.Model):
    STATUSES = (
        ("pending", "Pending"),
        ("processed", "Processed"),
        ("cancelled", "cancelled"),
    )

    FREQUENCY_TYPES = (
        ("d", "Days"),
        ("m", "Months"),
        ("w", "Weeks"),
        ("bw", "Bi-Weeks"),
        ("q", "Quarterly"),
        ("y", "Years"),
    )
    comment = models.TextField(null=True)
    int_rate = models.FloatField(null=False)
    tax_on_int = models.FloatField(null=False, default=0)
    frequency = models.IntegerField(null=False, default=0)
    frequency_type = models.CharField(
        max_length=50, choices=FREQUENCY_TYPES, default="d"
    )
    send_sms = models.BooleanField(default=False)
    deleted = models.BooleanField(default=False)
    deleted_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_records_savings_7')
    deleted_at = models.DateTimeField(null=True, blank=True)
    min_balance = models.FloatField(null=False, default=0)
    status = models.CharField(max_length=50, choices=STATUSES, default="pending")
    record_date = models.DateTimeField(default=timezone.now)
    exp_payment_date = models.DateTimeField(default=timezone.now)
    date_added = models.DateTimeField(default=timezone.now)
    last_updated = models.DateTimeField(default=timezone.now)
    last_updated_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="interest_payment_last_updated_by",
        null=True,
        blank=True,
    )
    product = models.ForeignKey(
        SavingsProduct,
        on_delete=models.CASCADE,
        related_name="interest_payment_product",
    )
    branch = models.ForeignKey(
        OrganisationBranch,
        on_delete=models.CASCADE,
        related_name="interest_payment_branch",
        null=False,
        blank=False,
    )
    from_date = models.DateTimeField(null=True, blank=True)
    to_date = models.DateTimeField(null=True, blank=True)
    processing_status = models.CharField(max_length=50, default="Ready")
    payment_status = models.CharField(max_length=50, null=True, blank=True)

    class Meta:
        db_table = 'public"."savings_product_interest_payment'


class SavingAccountTransactions(models.Model):
    TRANSACTION_TYPES = (
        ("deposit", "Deposit"),
        ("withdrawal", "Withdrawal"),
        ("transfer", "Transfer"),
        ("account_closure_fee", "Account Closure Fee"),
        ("deposit_charge", "Deposit Charge"),
        ("withdrawal_charge", "Withdrawal Charge"),
        ("transfer_charge", "Transfer Charge"),
        ("sms_charge", "Sms Charge"),
        ("bulk_savings_charges", "Bulk Ssavings Charges"),
        ("offset", "Offset"),
        ("fixed-deposit", "Fixed Deposit"),
        ("fixed-deposit_payment", "Fixed Deposit Payment"),
        ("savings-interest-tax", "Savings Interest Tax"),
        ("savings-interest-payment", "Savings Interest Payment"),
        ("over-draft", "Over Draft"),
        ("over-draft-principal-payment", "Over Draft Principal Payment"),
        ("over-draft-interest-payment", "Over Draft Interest Payment"),
        ("over-draft-penalty-payment", "Over Draft Penalty Payment"),
    )
    parent_id = models.BigIntegerField(default=0)
    transaction_type = models.CharField(
        max_length=50, choices=TRANSACTION_TYPES, default="deposit"
    )
    transaction = models.ForeignKey(
        SystemTransactions, on_delete=models.CASCADE, related_name="system_transactions"
    )
    customer_account = models.ForeignKey(
        SavingAccount, on_delete=models.CASCADE, related_name="customer_account"
    )
    date_added = models.DateTimeField(default=timezone.now)
    deleted = models.BooleanField(default=False)
    deleted_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_records_savings_8')
    deleted_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        db_table = 'public"."saving_account_transactions'


class GroupSavingTransaction(models.Model):
    TRANSACTION_STATUS = (("normal", "Normal"), ("reversed", "Reversed"))
    payment_status = models.CharField(
        max_length=50, choices=TRANSACTION_STATUS, default="normal"
    )
    savings = models.ForeignKey(
        SavingAccountTransactions,
        on_delete=models.CASCADE,
        related_name="savings_account_transaction",
    )
    membership = models.ForeignKey(
        GroupMembership, on_delete=models.CASCADE, related_name="group_membership"
    )
    date_added = models.DateTimeField(default=timezone.now)
    deleted = models.BooleanField(default=False)
    deleted_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_records_savings_9')
    deleted_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        db_table = 'public"."group_saving_transactions'


class InterestPaymentTransaction(models.Model):
    interest_payment = models.ForeignKey(
        SavingsProductInterestPayment,
        on_delete=models.CASCADE,
        related_name="interest_payment_transaction",
        null=False,
        blank=False,
    )
    savings = models.ForeignKey(
        SavingAccountTransactions,
        on_delete=models.CASCADE,
        related_name="savings_interest_transaction",
    )
    deleted = models.BooleanField(default=False)
    deleted_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_records_savings_10')
    deleted_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        db_table = 'public"."interest_payment_transaction'


class PendingWithdrawals(models.Model):
    STATUSES = (
        ("Approved", "Approved"),
        ("Pending", "Pending"),
        ("Declined", "Declined"),
    )
    receiver = models.CharField(max_length=255, null=True, blank=True)
    coment = models.TextField(null=True, blank=True)
    heading = models.TextField()
    amount = models.FloatField()
    charge = models.FloatField(default=0)
    cheque_no = models.CharField(max_length=50, null=True, blank=True)
    voucher_no = models.CharField(max_length=50, null=True, blank=True)
    status = models.CharField(max_length=50, choices=STATUSES, default="Pending")
    record_date = models.DateTimeField(default=timezone.now)
    date_added = models.DateTimeField(default=timezone.now)
    last_updated = models.DateTimeField(null=True, blank=True)
    send_sms = models.BooleanField(default=False)
    activate_charge = models.BooleanField(default=True)
    payment_method = models.CharField(max_length=50)
    customer_account = models.ForeignKey(
        SavingAccount, on_delete=models.CASCADE, related_name="customer_saving_account"
    )
    added_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="added_by",
        null=True,
        blank=True,
    )
    last_updated_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="approved_by",
        null=True,
        blank=True,
    )
    saving_account_transaction = models.ForeignKey(
        SavingAccountTransactions,
        on_delete=models.CASCADE,
        related_name="saving_account_transactions",
        null=True,
        blank=True,
    )
    credit_chart = models.ForeignKey(
        OrganisationSubAccount,
        on_delete=models.CASCADE,
        related_name="credit_chart",
        null=True,
        blank=True,
    )
    customer_branch = models.ForeignKey(
        OrganisationBranch,
        on_delete=models.CASCADE,
        related_name="customer_saving_branch",
        null=True,
        blank=True,
    )
    deleted = models.BooleanField(default=False)
    deleted_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_records_savings_11')
    deleted_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        db_table = 'public"."pending_withdrawals'


class SavingAccountClosure(models.Model):
    STATUSES = (
        ("initiated", "Initiated"),
        ("closed", "Closed"),
        ("cancelled", "Cancelled"),
    )

    saving_account = models.ForeignKey(
        SavingAccount,
        on_delete=models.CASCADE,
        related_name="saving_account_closures",
    )
    closure_fee = models.FloatField(default=0.0)
    amount_withdrawn = models.FloatField(default=0.0)
    status = models.CharField(max_length=50, choices=STATUSES, default="initiated")
    record_date = models.DateTimeField(default=timezone.now)
    closed_at = models.DateTimeField(null=True, blank=True)
    receiver = models.CharField(max_length=255, null=True, blank=True)
    payment_method = models.CharField(max_length=50, null=True, blank=True)
    voucher_no = models.CharField(max_length=100, null=True, blank=True)
    fee_collection_account = models.ForeignKey(
        OrganisationSubAccount,
        on_delete=models.SET_NULL,
        related_name="saving_account_closure_fee_account",
        null=True,
        blank=True,
    )
    withdrawal_destination_chart = models.ForeignKey(
        OrganisationSubAccount,
        on_delete=models.SET_NULL,
        related_name="saving_account_closure_destination_chart",
        null=True,
        blank=True,
    )
    fee_transaction = models.ForeignKey(
        SavingAccountTransactions,
        on_delete=models.SET_NULL,
        related_name="saving_account_closure_fee_transaction",
        null=True,
        blank=True,
    )
    withdrawal_transaction = models.ForeignKey(
        SavingAccountTransactions,
        on_delete=models.SET_NULL,
        related_name="saving_account_closure_withdrawal_transaction",
        null=True,
        blank=True,
    )
    closure_added_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="saving_account_closure_added_by",
    )
    closure_completed_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET_NULL,
        related_name="saving_account_closure_completed_by",
        null=True,
        blank=True,
    )
    deleted = models.BooleanField(default=False)
    deleted_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='deleted_records_savings_19',
    )
    deleted_at = models.DateTimeField(null=True, blank=True)
    date_added = models.DateTimeField(default=timezone.now)
    last_updated = models.DateTimeField(default=timezone.now)

    class Meta:
        db_table = 'public"."saving_account_closure'


class TransferTransactions(models.Model):
    sender_transaction = models.ForeignKey(
        SavingAccountTransactions,
        on_delete=models.CASCADE,
        related_name="sender_transaction",
    )
    reciever_transaction = models.ForeignKey(
        SavingAccountTransactions,
        on_delete=models.CASCADE,
        related_name="reciever_transaction",
    )
    deleted = models.BooleanField(default=False)
    deleted_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_records_savings_12')
    deleted_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        db_table = 'public"."transfer_transactions'


class AccountBookings(models.Model):
    TYPES = (("income", "Income"), ("assets", "Assets"), ("liabilities", "Liabilities"))
    amount = models.FloatField()
    heading = models.TextField()
    booking_type = models.CharField(max_length=50, choices=TYPES)
    chart = models.ForeignKey(
        OrganisationSubAccount, on_delete=models.CASCADE, related_name="booking_chart"
    )
    account = models.ForeignKey(
        SavingAccount, on_delete=models.CASCADE, related_name="booking_account"
    )
    record_date = models.DateTimeField(default=timezone.now)
    reversed = models.BooleanField(default=False)
    deleted = models.BooleanField(default=False)
    deleted_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_records_savings_13')
    deleted_at = models.DateTimeField(null=True, blank=True)
    date_added = models.DateTimeField(default=timezone.now)
    added_by = models.BigIntegerField(null=True, blank=True)

    class Meta:
        db_table = 'public"."account_booking'

    def __str__(self):
        return self.account.account_no


class AccountBookingPayments(models.Model):
    booking = models.ForeignKey(
        AccountBookings, on_delete=models.CASCADE, related_name="booking_payment"
    )
    reference_transaction = models.ForeignKey(
        SystemTransactions,
        on_delete=models.CASCADE,
        related_name="booking_payment_transaction",
    )
    date_added = models.DateTimeField(default=timezone.now)
    added_by = models.BigIntegerField(null=True, blank=True)
    deleted = models.BooleanField(default=False)
    deleted_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_records_savings_14')
    deleted_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        db_table = 'public"."account_booking_payments'

    def __str__(self):
        return self.reference_transaction.heading


class FixedDeposit(models.Model):
    STATUS = (
        ("pending", "Pending"),
        ("in-progress", "In Progress"),
        ("closed", "Closed"),
        ("Reversed", "reversed"),
    )

    PERIOD_TYPE = (
        ("d", "Days"),
        ("m", "Months"),
        ("w", "Weeks"),
        ("bw", "Bi-Weeks"),
        ("q", "Quarterly"),
        ("y", "Years"),
    )

    amount = models.FloatField(null=False)
    auto_close = models.BooleanField(default=False)
    auto_payments = models.BooleanField(default=False)
    withholding_tax = models.BooleanField(default=False)
    period = models.IntegerField(null=False, default=24)
    interest = models.FloatField(null=False, default=24.0)
    period_type = models.CharField(max_length=30, choices=PERIOD_TYPE)
    status = models.CharField(
        max_length=30, choices=STATUS, null=False, default="pending"
    )
    frequency = models.IntegerField(null=False)
    record_date = models.DateTimeField(default=timezone.now)
    date_added = models.DateTimeField(default=timezone.now)
    branch = models.ForeignKey(
        OrganisationBranch,
        on_delete=models.CASCADE,
        related_name="fixed_deposit_branch",
        null=False,
        blank=False,
    )
    saving_account = models.ForeignKey(
        SavingAccount,
        on_delete=models.CASCADE,
        related_name="fixed_deposit_saving_account",
    )
    fixed_deposit_added_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="fixed_deposit_added_by",
    )
    fixed_deposit_last_updated_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="fixed_deposit_last_updated_by",
        null=True,
        blank=True,
    )
    reference_transaction = models.ForeignKey(
        SystemTransactions,
        on_delete=models.CASCADE,
        related_name="fixed_deposit_transaction",
        null=False,
        blank=False,
    )
    closure_transaction = models.ForeignKey(
        SystemTransactions,
        on_delete=models.CASCADE,
        related_name="fixed_deposit_closure_transaction",
        null=True,
        blank=True,
    )
    deleted = models.BooleanField(default=False)
    deleted_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_records_savings_15')
    deleted_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        db_table = 'public"."fixed_deposit'


class FixedDepositScheduleQuerySet(models.QuerySet):
    def active(self):
        return self.filter(deleted=False)


class FixedDepositSchedule(models.Model):
    fixed_deposit = models.ForeignKey(
        FixedDeposit, on_delete=models.CASCADE, related_name="fixed_deposit"
    )
    interest = models.FloatField(default=0.0)
    expected_date = models.DateTimeField(null=True, blank=True)
    reference_transaction = models.ForeignKey(
        SystemTransactions,
        on_delete=models.CASCADE,
        related_name="fixed_deposit_schedule_transaction",
        null=True,
        blank=True,
    )
    fixed_deposit_added_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="fixed_deposit_schedule_added_by",
        null=True,
        blank=True,
    )
    date_added = models.DateTimeField(default=timezone.now)
    last_updated = models.DateTimeField(default=timezone.now)
    status = models.CharField(max_length=50, default="pending")
    deleted = models.BooleanField(default=False)
    deleted_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_records_savings_16')
    deleted_at = models.DateTimeField(null=True, blank=True)
    objects = FixedDepositScheduleQuerySet.as_manager()

    class Meta:
        db_table = 'public"."fixed_deposit_schedule'


class BulkSavingsChargeInitiation(models.Model):
    FREQUENCIES = (
        ("m", "Months"),
        ("w", "Weekly"),
        ("bw", "Bi-Weekly"),
        ("q", "Quarterly"),
        ("a", "Annually"),
    )
    heading = models.TextField()
    amount = models.FloatField(null=False)
    saving_product = models.ForeignKey(
        SavingsProduct,
        on_delete=models.CASCADE,
        related_name="bulk_charges_product",
        null=True,
        blank=True,
    )
    is_active = models.BooleanField(default=True)
    deleted = models.BooleanField(default=False)
    deleted_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_records_savings_17')
    deleted_at = models.DateTimeField(null=True, blank=True)
    book_account = models.BooleanField(default=True)
    send_sms = models.BooleanField(default=False)
    auto_payments = models.BooleanField(default=False)
    auto_charge = models.BooleanField(default=False)
    frequency = models.CharField(max_length=30, choices=FREQUENCIES, default="m")
    status = models.CharField(max_length=50, default="pending")
    record_date = models.DateTimeField(null=True, blank=True)
    start_date = models.DateTimeField(null=True, blank=True)
    end_date = models.DateTimeField(null=True, blank=True)
    date_added = models.DateTimeField(default=timezone.now)
    last_updated = models.DateTimeField(default=timezone.now)
    charge_added_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="bulk_charge_added_by",
    )
    last_updated_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="bulk_charge_last_updated_by",
        null=True,
        blank=True,
    )
    branch = models.ForeignKey(
        OrganisationBranch,
        on_delete=models.CASCADE,
        related_name="product_bulk_charge_branch",
        null=True,
        blank=True,
    )
    accounts_chart = models.ForeignKey(
        OrganisationSubAccount,
        on_delete=models.CASCADE,
        related_name="product_bulk_charge_account",
        null=True,
        blank=True,
    )

    class Meta:
        db_table = 'public"."bulk_savings_charge_initiation'


class BulkSavingsChargesTransactions(models.Model):
    FREQUENCIES = (
        ("pending", "Pending"),
        ("processed", "Processed"),
    )
    saving_transaction = models.ForeignKey(
        SavingAccountTransactions,
        on_delete=models.CASCADE,
        related_name="saving_transaction",
        null=True,
        blank=True,
    )
    initiation = models.ForeignKey(
        BulkSavingsChargeInitiation,
        on_delete=models.CASCADE,
        related_name="bulk_charge_initiation",
    )
    status = models.CharField(max_length=50, default="pending")
    deleted = models.BooleanField(default=False)
    deleted_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_bulk_savings_charge_transactions')
    deleted_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        db_table = 'public"."bulk_savings_charges_transactions'


class SchoolFeesPaymentTransactions(models.Model):
    transaction = models.ForeignKey(
        SystemTransactions,
        on_delete=models.CASCADE,
        related_name="school_system_transactions",
    )
    third_party_transaction_id = models.CharField(max_length=150)
    student_number = models.CharField(max_length=150)
    student_name = models.CharField(max_length=150)
    third_party_school_name = models.CharField(max_length=150)
    customer_account = models.ForeignKey(
        SavingAccount, on_delete=models.CASCADE, related_name="school_customer_account"
    )
    date_added = models.DateTimeField(default=timezone.now)
    branch = models.ForeignKey(
        OrganisationBranch,
        on_delete=models.CASCADE,
        related_name="school_transaction_branch",
    )
    deleted = models.BooleanField(default=False)
    deleted_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_records_savings_18')
    deleted_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        db_table = 'public"."school_fees_payments'


class SchoolFeesIntegrations(models.Model):
    school_code = models.CharField(max_length=150)
    school_name = models.CharField(max_length=150)
    date_added = models.DateTimeField(default=timezone.now)
    school_organisation = models.ForeignKey(
        Organisation, on_delete=models.CASCADE, related_name="school_organisation"
    )
    customer = models.ForeignKey(
        Customer, on_delete=models.CASCADE, related_name="school_fees_customer"
    )

    class Meta:
        db_table = 'public"."school_fees_integrations'


class SchoolFeesOrganIntegration(models.Model):
    organisation = models.ForeignKey(
        Organisation, on_delete=models.CASCADE, related_name="sch_organisation"
    )
    account_chart = models.ForeignKey(
        OrganisationSubAccount,
        on_delete=models.CASCADE,
        related_name="school_organisation_account",
    )
    name = models.CharField(max_length=255, default="Sure Pay")
    third_party = models.CharField(max_length=255, default="sure_pay")
    is_active = models.BooleanField(default=True)
    date_added = models.DateTimeField(default=timezone.now)
    added_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="sch_organisation_added_by",
        null=True,
        blank=True,
    )

    class Meta:
        db_table = 'public"."school_fees_organ_integrations'


class CustomerObligations(models.Model):
    name = models.CharField(max_length=200)
    narration = models.CharField(max_length=200, default="Monthly Savings")
    organisation = models.ForeignKey(
        Organisation, on_delete=models.CASCADE, related_name="org_obligations"
    )
    obligation_type = models.CharField(max_length=200)  # savings, shares, loans
    obligation_choice = models.CharField(max_length=100, default="voluntary")
    amount = models.FloatField(default=0.0)
    is_active = models.BooleanField(default=True)
    added_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="obligation_added_by",
    )
    date_added = models.DateTimeField(default=timezone.now)
    last_updated = models.DateTimeField(default=timezone.now)
    source_chart = models.ForeignKey(
        OrganisationSubAccount, on_delete=models.CASCADE, related_name="source_account"
    )
    destination_chart = models.ForeignKey(
        OrganisationSubAccount,
        on_delete=models.CASCADE,
        related_name="destination_chart",
        null=True,
        blank=True,
    )
    start_day = models.IntegerField(null=True, blank=True)
    end_day = models.IntegerField(null=True, blank=True)

    class Meta:
        db_table = 'public"."customer_obligations'


class CustomerObligationSubscription(models.Model):
    obligation = models.ForeignKey(
        CustomerObligations,
        on_delete=models.CASCADE,
        related_name="customer_obligations",
    )
    amount = models.FloatField(default=0.0)
    is_active = models.BooleanField(default=True)
    added_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="ocustomer_bligation_added_by",
    )
    date_added = models.DateTimeField(default=timezone.now)
    last_updated = models.DateTimeField(default=timezone.now)
    customer_source_chart = models.ForeignKey(
        OrganisationSubAccount,
        on_delete=models.CASCADE,
        related_name="customer_source_chart",
        null=True,
        blank=True,
    )
    customer = models.ForeignKey(
        Customer, on_delete=models.CASCADE, related_name="customer_obligation"
    )

    class Meta:
        db_table = 'public"."customer_obligation_subscription'


class CustomerObligationTransactions(models.Model):
    customer_transaction = models.ForeignKey(
        Customer, on_delete=models.CASCADE, related_name="customer_transaction"
    )
    customer_obligation = models.ForeignKey(
        CustomerObligations,
        on_delete=models.CASCADE,
        related_name="customer_obligation_tran",
    )
    amount = models.DecimalField(max_digits=12, decimal_places=2)
    date = models.DateTimeField(default=timezone.now)
    reference = models.CharField(
        max_length=100, blank=True, null=True
    )  # e.g., transaction ID
    description = models.TextField(blank=True, null=True)

    created_at = models.DateTimeField(default=timezone.now)
    updated_at = models.DateTimeField(default=timezone.now)

    class Meta:
        db_table = 'public"."customer_obligation_transactions'


class AccountMergeRequest(models.Model):
    MERGE_STATUSES = (
        ('pending', 'Pending Approval'),
        ('approved', 'Approved'),
        ('rejected', 'Rejected'),
        ('completed', 'Completed'),
        ('reversed', 'Reversed'),
    )
    TRANSFER_MODES = (
        ('all', 'Transfer All Transactions'),
        ('from_date', 'Transfer From Date'),
    )

    customer = models.ForeignKey(Customer, on_delete=models.CASCADE, related_name='account_merge_requests')
    source_account = models.ForeignKey(SavingAccount, on_delete=models.CASCADE, related_name='merge_source')
    destination_account = models.ForeignKey(SavingAccount, on_delete=models.CASCADE, related_name='merge_destination')
    transfer_mode = models.CharField(max_length=20, choices=TRANSFER_MODES)
    transfer_from_date = models.DateTimeField(null=True, blank=True)
    status = models.CharField(max_length=20, choices=MERGE_STATUSES, default='pending')
    reason = models.TextField(null=True, blank=True)
    rejection_reason = models.TextField(null=True, blank=True)
    is_cross_product = models.BooleanField(default=False)
    requested_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='merge_requested_by')
    approved_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name='merge_approved_by')
    organisation_branch = models.ForeignKey(OrganisationBranch, on_delete=models.CASCADE, related_name='merge_requests')
    date_added = models.DateTimeField(default=timezone.now)
    date_actioned = models.DateTimeField(null=True, blank=True)
    transferred_transaction_ids = models.JSONField(null=True, blank=True)

    class Meta:
        db_table = 'public"."account_merge_requests'
