Skip to content

Commit

Permalink
feat: Advance Refund
Browse files Browse the repository at this point in the history
  • Loading branch information
Irfan778899 committed Dec 19, 2023
1 parent 5c55b9d commit 48a0cda
Show file tree
Hide file tree
Showing 2 changed files with 228 additions and 1 deletion.
105 changes: 105 additions & 0 deletions healthcare/healthcare/doctype/patient/patient.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ frappe.ui.form.on('Patient', {
}, __('Create'));
frm.toggle_enable(['customer'], 0);
}
frm.add_custom_button(__('Advance Refund'), function() {
get_advance_refund(frm);
}, __('Create'));
frappe.contacts.render_address_and_contact(frm);
erpnext.utils.set_party_dashboard_indicators(frm);
} else {
Expand Down Expand Up @@ -145,3 +148,105 @@ let invoice_registration = function (frm) {
}
});
};


let get_advance_refund = function (frm) {

const fields = [
{
label: 'Company',
fieldname: 'company',
fieldtype: 'Link',
options: 'Company',
default: frappe.defaults.get_user_default('Company')
},
{
label: 'Advance Amount',
fieldname: 'advance_amount',
fieldtype: 'Currency',
read_only: true,
},
{
label: 'Mode of Payment',
fieldname: 'mode_of_payment',
fieldtype: 'Link',
options: 'Mode of Payment',
reqd: 1
},
{
label: 'Refund Amount',
fieldname: 'refund_amount',
fieldtype: 'Currency',
}
];

let d = new frappe.ui.Dialog ({
title: "Advance Refund",
fields: fields,
primary_action_label: "Refund",
primary_action: function(values) {
if (values.refund_amount <= values.advance_amount) {
frappe.call({
doc: frm.doc,
method: 'advance_refund',
args: {
company: values.company,
party : frm.doc.customer,
mode_of_payment : values.mode_of_payment,
refund_amount : values.refund_amount
},
callback: function(response) {
if (response.message) {
frappe.msgprint(__("Advance refund successful"))
} else {
frappe.msgprint(__("Advance refund failed"))
}
d.hide();
}
})
} else {
frappe.throw(__("Refund amount cannot be greater than Advance amount"))
}
}
});

get_advance_amount(frm, d);

d.fields_dict['company'].df.onchange = () => {
get_advance_amount(frm, d)
}

}

let get_advance_amount = function(frm, d) {
let advanceAmount = 0;

frappe.db.get_list('Payment Entry', {
filters: {
'company' : d.get_value('company'),
'party': frm.doc.customer,
'docstatus' : ['!=', 2],
'unallocated_amount': ['>', 0]
},
fields: ['unallocated_amount']
}).then((res) => {
res.forEach((value) => {
advanceAmount += value.unallocated_amount;
});

d.set_values({
'advance_amount': advanceAmount
});

if (advanceAmount == 0) {
frappe.msgprint(__("There is no Advance amount to Refund"))
} else {
d.show();
}

})
.catch((error) => {
console.error(error);
frappe.msgprint(__('Error fetching data from Payment Entry'));
});
}
124 changes: 123 additions & 1 deletion healthcare/healthcare/doctype/patient/patient.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,17 @@
from frappe.contacts.doctype.contact.contact import get_default_contact
from frappe.model.document import Document
from frappe.model.naming import set_name_by_naming_series
from frappe.utils import cint, cstr, getdate
from frappe.utils import cint, cstr, flt, getdate
from frappe.utils.nestedset import get_root_of

import erpnext
from erpnext import get_default_currency
from erpnext.accounts.doctype.journal_entry.journal_entry import (
get_account_balance_and_party_type,
get_party_account_and_balance,
)
from erpnext.accounts.party import get_dashboard_info
from erpnext.accounts.utils import reconcile_against_document
from erpnext.selling.doctype.customer.customer import make_address

from healthcare.healthcare.doctype.healthcare_settings.healthcare_settings import (
Expand Down Expand Up @@ -293,6 +299,122 @@ def update_patient_based_on_existing_customer(self):
)
self.notify_update()

@frappe.whitelist()
def advance_refund(self, company, party, mode_of_payment, refund_amount):
new_je = self.create_journal_entry(company, party, mode_of_payment, refund_amount)

filters = {
"company": company,
"party": party,
"docstatus": ["!=", 2],
"unallocated_amount": [">", 0],
}

payment_entries = frappe.get_all("Payment Entry", filters=filters, pluck="name")
for pe in payment_entries:
get_pe = frappe.get_doc("Payment Entry", pe)

entry_list = []

payment_details = self.get_payment_details(company, party, new_je, get_pe, refund_amount)

entry_list.append(payment_details)

reconcile_against_document(entry_list, skip_ref_details_update_for_pe=False)

return {"message": "success"}

def create_journal_entry(self, company, party, mode_of_payment, refund_amount):

paid_to = frappe.get_cached_value(
"Mode of Payment Account", {"parent": mode_of_payment, "company": company}, "default_account"
)

paid_from = frappe.get_cached_value("Company", company, "default_receivable_account")

party_type = "Customer"

journal_entry = frappe.new_doc("Journal Entry")

journal_entry.voucher_type = "Journal Entry"
journal_entry.posting_date = frappe.utils.nowdate()

account_info = get_party_account_and_balance(company, party_type, party, cost_center=None)

journal_entry.append(
"accounts",
{
"account": paid_from,
"party_type": party_type,
"party": party,
"debit_in_account_currency": refund_amount,
"credit_in_account_currency": 0,
"balance": account_info["balance"],
"party_balance": account_info["party_balance"],
},
)

account_info_2 = get_account_balance_and_party_type(
account=paid_to, date=journal_entry.posting_date, company=company
)

journal_entry.append(
"accounts",
{
"account": paid_to,
"party_type": "",
"party": "",
"debit_in_account_currency": 0,
"credit_in_account_currency": refund_amount,
"balance": account_info_2["balance"],
},
)

journal_entry.save()
journal_entry.submit()

return journal_entry

def get_payment_details(self, company, party, new_je, get_pe, refund_amount):

defaultAccount = frappe.get_cached_value("Company", company, "default_receivable_account")

dr_or_cr = (
"credit_in_account_currency"
if erpnext.get_party_account_type(get_pe.party_type) == "Receivable"
else "debit_in_account_currency"
)

if get_pe.unallocated_amount > refund_amount:
allocated_amount = refund_amount
else:
allocated_amount = get_pe.unallocated_amount

difference_account = frappe.get_cached_value("Company", company, "exchange_gain_loss_account")

return frappe._dict(
{
"voucher_type": "Payment Entry",
"voucher_no": get_pe.name,
"voucher_detail_no": None,
"against_voucher_type": "Journal Entry",
"against_voucher": new_je.name,
"account": defaultAccount,
"exchange_rate": 0,
"party_type": "Customer",
"party": party,
"is_advance": None,
"dr_or_cr": dr_or_cr,
"unreconciled_amount": flt(get_pe.unallocated_amount),
"unadjusted_amount": flt(get_pe.unallocated_amount),
"allocated_amount": flt(allocated_amount),
"difference_amount": 0.0,
"difference_account": difference_account,
"difference_posting_date": frappe.utils.nowdate(),
"cost_center": None,
}
)


def create_customer(doc):
customer = frappe.get_doc(
Expand Down

0 comments on commit 48a0cda

Please sign in to comment.