refactor: Redo workflows
This commit is contained in:
parent
05c2198569
commit
da6bc1a13e
@ -19,6 +19,7 @@
|
|||||||
"party_type",
|
"party_type",
|
||||||
"party",
|
"party",
|
||||||
"party_name",
|
"party_name",
|
||||||
|
"book_advance_payments_in_separate_party_account",
|
||||||
"column_break_11",
|
"column_break_11",
|
||||||
"bank_account",
|
"bank_account",
|
||||||
"party_bank_account",
|
"party_bank_account",
|
||||||
@ -735,12 +736,21 @@
|
|||||||
"fieldname": "get_outstanding_orders",
|
"fieldname": "get_outstanding_orders",
|
||||||
"fieldtype": "Button",
|
"fieldtype": "Button",
|
||||||
"label": "Get Outstanding Orders"
|
"label": "Get Outstanding Orders"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fetch_from": "company.book_advance_payments_in_separate_party_account",
|
||||||
|
"fieldname": "book_advance_payments_in_separate_party_account",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"hidden": 1,
|
||||||
|
"label": "Book Advance Payments in Separate Party Account",
|
||||||
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-06-19 11:38:04.387219",
|
"modified": "2023-06-23 18:07:38.023010",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Payment Entry",
|
"name": "Payment Entry",
|
||||||
|
|||||||
@ -21,7 +21,11 @@ from erpnext.accounts.doctype.journal_entry.journal_entry import get_default_ban
|
|||||||
from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import (
|
from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import (
|
||||||
get_party_tax_withholding_details,
|
get_party_tax_withholding_details,
|
||||||
)
|
)
|
||||||
from erpnext.accounts.general_ledger import make_gl_entries, process_gl_map
|
from erpnext.accounts.general_ledger import (
|
||||||
|
make_gl_entries,
|
||||||
|
make_reverse_gl_entries,
|
||||||
|
process_gl_map,
|
||||||
|
)
|
||||||
from erpnext.accounts.party import get_party_account
|
from erpnext.accounts.party import get_party_account
|
||||||
from erpnext.accounts.utils import get_account_currency, get_balance_on, get_outstanding_invoices
|
from erpnext.accounts.utils import get_account_currency, get_balance_on, get_outstanding_invoices
|
||||||
from erpnext.controllers.accounts_controller import (
|
from erpnext.controllers.accounts_controller import (
|
||||||
@ -88,17 +92,14 @@ class PaymentEntry(AccountsController):
|
|||||||
if self.difference_amount:
|
if self.difference_amount:
|
||||||
frappe.throw(_("Difference Amount must be zero"))
|
frappe.throw(_("Difference Amount must be zero"))
|
||||||
self.make_gl_entries()
|
self.make_gl_entries()
|
||||||
|
self.make_advance_gl_entries()
|
||||||
self.update_outstanding_amounts()
|
self.update_outstanding_amounts()
|
||||||
self.update_advance_paid()
|
self.update_advance_paid()
|
||||||
self.update_payment_schedule()
|
self.update_payment_schedule()
|
||||||
self.set_status()
|
self.set_status()
|
||||||
|
|
||||||
def set_liability_account(self):
|
def set_liability_account(self):
|
||||||
book_advance_payments_as_liability = frappe.get_value(
|
if not self.book_advance_payments_in_separate_party_account:
|
||||||
"Company", {"company_name": self.company}, "book_advance_payments_as_liability"
|
|
||||||
)
|
|
||||||
|
|
||||||
if not book_advance_payments_as_liability:
|
|
||||||
return
|
return
|
||||||
|
|
||||||
account_type = frappe.get_value(
|
account_type = frappe.get_value(
|
||||||
@ -139,6 +140,7 @@ class PaymentEntry(AccountsController):
|
|||||||
"Repost Payment Ledger Items",
|
"Repost Payment Ledger Items",
|
||||||
)
|
)
|
||||||
self.make_gl_entries(cancel=1)
|
self.make_gl_entries(cancel=1)
|
||||||
|
self.make_advance_gl_entries(cancel=1)
|
||||||
self.update_outstanding_amounts()
|
self.update_outstanding_amounts()
|
||||||
self.update_advance_paid()
|
self.update_advance_paid()
|
||||||
self.delink_advance_entry_references()
|
self.delink_advance_entry_references()
|
||||||
@ -212,7 +214,8 @@ class PaymentEntry(AccountsController):
|
|||||||
"party_account": self.paid_from if self.payment_type == "Receive" else self.paid_to,
|
"party_account": self.paid_from if self.payment_type == "Receive" else self.paid_to,
|
||||||
"get_outstanding_invoices": True,
|
"get_outstanding_invoices": True,
|
||||||
"get_orders_to_be_billed": True,
|
"get_orders_to_be_billed": True,
|
||||||
}
|
},
|
||||||
|
validate=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Group latest_references by (voucher_type, voucher_no)
|
# Group latest_references by (voucher_type, voucher_no)
|
||||||
@ -417,6 +420,13 @@ class PaymentEntry(AccountsController):
|
|||||||
elif self.party_type == "Employee":
|
elif self.party_type == "Employee":
|
||||||
ref_party_account = ref_doc.payable_account
|
ref_party_account = ref_doc.payable_account
|
||||||
|
|
||||||
|
if ref_party_account != self.party_account:
|
||||||
|
frappe.throw(
|
||||||
|
_("{0} {1} is associated with {2}, but Party Account is {3}").format(
|
||||||
|
d.reference_doctype, d.reference_name, ref_party_account, self.party_account
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
if ref_doc.doctype == "Purchase Invoice" and ref_doc.get("on_hold"):
|
if ref_doc.doctype == "Purchase Invoice" and ref_doc.get("on_hold"):
|
||||||
frappe.throw(
|
frappe.throw(
|
||||||
_("{0} {1} is on hold").format(d.reference_doctype, d.reference_name),
|
_("{0} {1} is on hold").format(d.reference_doctype, d.reference_name),
|
||||||
@ -952,7 +962,7 @@ class PaymentEntry(AccountsController):
|
|||||||
else:
|
else:
|
||||||
against_account = self.paid_from
|
against_account = self.paid_from
|
||||||
|
|
||||||
party_dict = self.get_gl_dict(
|
party_gl_dict = self.get_gl_dict(
|
||||||
{
|
{
|
||||||
"account": self.party_account,
|
"account": self.party_account,
|
||||||
"party_type": self.party_type,
|
"party_type": self.party_type,
|
||||||
@ -968,32 +978,21 @@ class PaymentEntry(AccountsController):
|
|||||||
"credit" if erpnext.get_party_account_type(self.party_type) == "Receivable" else "debit"
|
"credit" if erpnext.get_party_account_type(self.party_type) == "Receivable" else "debit"
|
||||||
)
|
)
|
||||||
|
|
||||||
is_advance = self.is_advance_entry()
|
|
||||||
|
|
||||||
for d in self.get("references"):
|
for d in self.get("references"):
|
||||||
gle = party_dict.copy()
|
cost_center = self.cost_center
|
||||||
book_advance_payments_as_liability = frappe.get_value(
|
if d.reference_doctype == "Sales Invoice" and not cost_center:
|
||||||
"Company", {"company_name": self.company}, "book_advance_payments_as_liability"
|
cost_center = frappe.db.get_value(d.reference_doctype, d.reference_name, "cost_center")
|
||||||
)
|
|
||||||
if (
|
gle = party_gl_dict.copy()
|
||||||
d.reference_doctype in ["Sales Invoice", "Purchase Invoice"]
|
|
||||||
and book_advance_payments_as_liability
|
|
||||||
and is_advance
|
|
||||||
):
|
|
||||||
self.make_invoice_liability_entry(gl_entries, d)
|
|
||||||
against_voucher_type = "Payment Entry"
|
|
||||||
against_voucher = self.name
|
|
||||||
else:
|
|
||||||
against_voucher_type = d.reference_doctype
|
|
||||||
against_voucher = d.reference_name
|
|
||||||
|
|
||||||
allocated_amount_in_company_currency = self.calculate_base_allocated_amount_for_reference(d)
|
allocated_amount_in_company_currency = self.calculate_base_allocated_amount_for_reference(d)
|
||||||
gle.update(
|
gle.update(
|
||||||
{
|
{
|
||||||
dr_or_cr: allocated_amount_in_company_currency,
|
dr_or_cr: allocated_amount_in_company_currency,
|
||||||
dr_or_cr + "_in_account_currency": d.allocated_amount,
|
dr_or_cr + "_in_account_currency": d.allocated_amount,
|
||||||
"against_voucher_type": against_voucher_type,
|
"against_voucher_type": d.reference_doctype,
|
||||||
"against_voucher": against_voucher,
|
"against_voucher": d.reference_name,
|
||||||
|
"cost_center": cost_center,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
gl_entries.append(gle)
|
gl_entries.append(gle)
|
||||||
@ -1002,25 +1001,44 @@ class PaymentEntry(AccountsController):
|
|||||||
exchange_rate = self.get_exchange_rate()
|
exchange_rate = self.get_exchange_rate()
|
||||||
base_unallocated_amount = self.unallocated_amount * exchange_rate
|
base_unallocated_amount = self.unallocated_amount * exchange_rate
|
||||||
|
|
||||||
gle = party_dict.copy()
|
gle = party_gl_dict.copy()
|
||||||
gle.update(
|
gle.update(
|
||||||
{
|
{
|
||||||
dr_or_cr + "_in_account_currency": self.unallocated_amount,
|
dr_or_cr + "_in_account_currency": self.unallocated_amount,
|
||||||
dr_or_cr: base_unallocated_amount,
|
dr_or_cr: base_unallocated_amount,
|
||||||
"against_voucher_type": "Payment Entry",
|
|
||||||
"against_voucher": self.name,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
gl_entries.append(gle)
|
gl_entries.append(gle)
|
||||||
|
|
||||||
def is_advance_entry(self):
|
def make_advance_gl_entries(self, against_voucher_type=None, against_voucher=None, cancel=0):
|
||||||
for d in self.get("references"):
|
if self.book_advance_payments_in_separate_party_account:
|
||||||
if d.reference_doctype in ("Sales Order", "Purchase Order"):
|
gl_entries = []
|
||||||
return True
|
for d in self.get("references"):
|
||||||
if self.unallocated_amount > 0:
|
if d.reference_doctype in ("Sales Invoice", "Purchase Invoice"):
|
||||||
return True
|
if not (against_voucher_type and against_voucher) or (
|
||||||
return False
|
d.reference_doctype == against_voucher_type and d.reference_name == against_voucher
|
||||||
|
):
|
||||||
|
self.make_invoice_liability_entry(gl_entries, d)
|
||||||
|
|
||||||
|
if cancel:
|
||||||
|
for entry in gl_entries:
|
||||||
|
frappe.db.set_value(
|
||||||
|
"GL Entry",
|
||||||
|
{
|
||||||
|
"voucher_no": self.name,
|
||||||
|
"voucher_type": self.doctype,
|
||||||
|
"voucher_detail_no": entry.voucher_detail_no,
|
||||||
|
"against_voucher_type": entry.against_voucher_type,
|
||||||
|
"against_voucher": entry.against_voucher,
|
||||||
|
},
|
||||||
|
"is_cancelled",
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
|
||||||
|
make_reverse_gl_entries(gl_entries=gl_entries, partial_cancel=True)
|
||||||
|
else:
|
||||||
|
make_gl_entries(gl_entries)
|
||||||
|
|
||||||
def make_invoice_liability_entry(self, gl_entries, invoice):
|
def make_invoice_liability_entry(self, gl_entries, invoice):
|
||||||
args_dict = {
|
args_dict = {
|
||||||
@ -1030,6 +1048,7 @@ class PaymentEntry(AccountsController):
|
|||||||
"cost_center": self.cost_center,
|
"cost_center": self.cost_center,
|
||||||
"voucher_type": "Payment Entry",
|
"voucher_type": "Payment Entry",
|
||||||
"voucher_no": self.name,
|
"voucher_no": self.name,
|
||||||
|
"voucher_detail_no": invoice.name,
|
||||||
}
|
}
|
||||||
|
|
||||||
dr_or_cr = "credit" if invoice.reference_doctype == "Sales Invoice" else "debit"
|
dr_or_cr = "credit" if invoice.reference_doctype == "Sales Invoice" else "debit"
|
||||||
@ -1391,7 +1410,7 @@ def validate_inclusive_tax(tax, doc):
|
|||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_outstanding_reference_documents(args):
|
def get_outstanding_reference_documents(args, validate=False):
|
||||||
if isinstance(args, str):
|
if isinstance(args, str):
|
||||||
args = json.loads(args)
|
args = json.loads(args)
|
||||||
|
|
||||||
@ -1511,13 +1530,14 @@ def get_outstanding_reference_documents(args):
|
|||||||
elif args.get("get_orders_to_be_billed"):
|
elif args.get("get_orders_to_be_billed"):
|
||||||
ref_document_type = "orders"
|
ref_document_type = "orders"
|
||||||
|
|
||||||
frappe.msgprint(
|
if not validate:
|
||||||
_(
|
frappe.msgprint(
|
||||||
"No outstanding {0} found for the {1} {2} which qualify the filters you have specified."
|
_(
|
||||||
).format(
|
"No outstanding {0} found for the {1} {2} which qualify the filters you have specified."
|
||||||
ref_document_type, _(args.get("party_type")).lower(), frappe.bold(args.get("party"))
|
).format(
|
||||||
|
ref_document_type, _(args.get("party_type")).lower(), frappe.bold(args.get("party"))
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|||||||
@ -12,16 +12,12 @@ import erpnext
|
|||||||
from erpnext.accounts.doctype.process_payment_reconciliation.process_payment_reconciliation import (
|
from erpnext.accounts.doctype.process_payment_reconciliation.process_payment_reconciliation import (
|
||||||
is_any_doc_running,
|
is_any_doc_running,
|
||||||
)
|
)
|
||||||
from erpnext.accounts.general_ledger import make_gl_entries
|
|
||||||
from erpnext.accounts.utils import (
|
from erpnext.accounts.utils import (
|
||||||
QueryPaymentLedger,
|
QueryPaymentLedger,
|
||||||
get_outstanding_invoices,
|
get_outstanding_invoices,
|
||||||
reconcile_against_document,
|
reconcile_against_document,
|
||||||
)
|
)
|
||||||
from erpnext.controllers.accounts_controller import (
|
from erpnext.controllers.accounts_controller import get_advance_payment_entries
|
||||||
get_advance_payment_entries,
|
|
||||||
make_advance_liability_entry,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class PaymentReconciliation(Document):
|
class PaymentReconciliation(Document):
|
||||||
@ -355,15 +351,6 @@ class PaymentReconciliation(Document):
|
|||||||
for row in self.get("allocation"):
|
for row in self.get("allocation"):
|
||||||
reconciled_entry = []
|
reconciled_entry = []
|
||||||
if row.invoice_number and row.allocated_amount:
|
if row.invoice_number and row.allocated_amount:
|
||||||
if (
|
|
||||||
row.invoice_type in ["Sales Invoice", "Purchase Invoice"]
|
|
||||||
and row.reference_type == "Payment Entry"
|
|
||||||
):
|
|
||||||
gl_entries = []
|
|
||||||
make_advance_liability_entry(
|
|
||||||
gl_entries, row.reference_name, row.allocated_amount, row.invoice_number, self.party_type
|
|
||||||
)
|
|
||||||
make_gl_entries(gl_entries)
|
|
||||||
if row.reference_type in ["Sales Invoice", "Purchase Invoice"]:
|
if row.reference_type in ["Sales Invoice", "Purchase Invoice"]:
|
||||||
reconciled_entry = dr_or_cr_notes
|
reconciled_entry = dr_or_cr_notes
|
||||||
else:
|
else:
|
||||||
|
|||||||
@ -33,10 +33,7 @@ from erpnext.accounts.utils import get_account_currency, get_fiscal_year
|
|||||||
from erpnext.assets.doctype.asset.asset import get_asset_account, is_cwip_accounting_enabled
|
from erpnext.assets.doctype.asset.asset import get_asset_account, is_cwip_accounting_enabled
|
||||||
from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account
|
from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account
|
||||||
from erpnext.buying.utils import check_on_hold_or_closed_status
|
from erpnext.buying.utils import check_on_hold_or_closed_status
|
||||||
from erpnext.controllers.accounts_controller import (
|
from erpnext.controllers.accounts_controller import validate_account_head
|
||||||
check_advance_liability_entry,
|
|
||||||
validate_account_head,
|
|
||||||
)
|
|
||||||
from erpnext.controllers.buying_controller import BuyingController
|
from erpnext.controllers.buying_controller import BuyingController
|
||||||
from erpnext.stock import get_warehouse_account_map
|
from erpnext.stock import get_warehouse_account_map
|
||||||
from erpnext.stock.doctype.purchase_receipt.purchase_receipt import (
|
from erpnext.stock.doctype.purchase_receipt.purchase_receipt import (
|
||||||
@ -576,15 +573,6 @@ class PurchaseInvoice(BuyingController):
|
|||||||
gl_entries = []
|
gl_entries = []
|
||||||
|
|
||||||
self.make_supplier_gl_entry(gl_entries)
|
self.make_supplier_gl_entry(gl_entries)
|
||||||
|
|
||||||
check_advance_liability_entry(
|
|
||||||
gl_entries,
|
|
||||||
company=self.company,
|
|
||||||
advances=self.advances,
|
|
||||||
invoice=self.name,
|
|
||||||
party_type="Supplier",
|
|
||||||
)
|
|
||||||
|
|
||||||
self.make_item_gl_entries(gl_entries)
|
self.make_item_gl_entries(gl_entries)
|
||||||
self.make_precision_loss_gl_entry(gl_entries)
|
self.make_precision_loss_gl_entry(gl_entries)
|
||||||
|
|
||||||
|
|||||||
@ -1664,10 +1664,17 @@ class TestPurchaseInvoice(unittest.TestCase, StockTestMixin):
|
|||||||
|
|
||||||
self.assertTrue(return_pi.docstatus == 1)
|
self.assertTrue(return_pi.docstatus == 1)
|
||||||
|
|
||||||
def test_advance_entries_as_liability(self):
|
def test_advance_entries_as_asset(self):
|
||||||
from erpnext.accounts.doctype.payment_entry.test_payment_entry import create_payment_entry
|
from erpnext.accounts.doctype.payment_entry.test_payment_entry import create_payment_entry
|
||||||
|
|
||||||
set_advance_flag(company="_Test Company", flag=1, default_account="Debtors - _TC")
|
account = create_account(
|
||||||
|
parent_account="Current Assets - _TC",
|
||||||
|
account_name="Advances Paid",
|
||||||
|
company="_Test Company",
|
||||||
|
account_type="Receivable",
|
||||||
|
)
|
||||||
|
|
||||||
|
set_advance_flag(company="_Test Company", flag=1, default_account=account)
|
||||||
|
|
||||||
pe = create_payment_entry(
|
pe = create_payment_entry(
|
||||||
company="_Test Company",
|
company="_Test Company",
|
||||||
@ -1701,13 +1708,15 @@ class TestPurchaseInvoice(unittest.TestCase, StockTestMixin):
|
|||||||
|
|
||||||
# Check GL Entry against payment doctype
|
# Check GL Entry against payment doctype
|
||||||
expected_gle = [
|
expected_gle = [
|
||||||
|
["Advances Paid - _TC", 0.0, 500, nowdate()],
|
||||||
["Cash - _TC", 0.0, 500, nowdate()],
|
["Cash - _TC", 0.0, 500, nowdate()],
|
||||||
["Creditors - _TC", 500, 0.0, nowdate()],
|
["Creditors - _TC", 500, 0.0, nowdate()],
|
||||||
["Creditors - _TC", 500, 0.0, nowdate()],
|
["Creditors - _TC", 500, 0.0, nowdate()],
|
||||||
["Debtors - _TC", 0.0, 500, nowdate()],
|
|
||||||
]
|
]
|
||||||
|
|
||||||
check_gl_entries(self, pe.name, expected_gle, nowdate(), voucher_type="Payment Entry")
|
check_gl_entries(self, pe.name, expected_gle, nowdate(), voucher_type="Payment Entry")
|
||||||
|
|
||||||
|
pi.load_from_db()
|
||||||
self.assertEqual(pi.outstanding_amount, 500)
|
self.assertEqual(pi.outstanding_amount, 500)
|
||||||
|
|
||||||
set_advance_flag(company="_Test Company", flag=0, default_account="")
|
set_advance_flag(company="_Test Company", flag=0, default_account="")
|
||||||
@ -1733,7 +1742,7 @@ def set_advance_flag(company, flag, default_account):
|
|||||||
"Company",
|
"Company",
|
||||||
company,
|
company,
|
||||||
{
|
{
|
||||||
"book_advance_payments_as_liability": flag,
|
"book_advance_payments_in_separate_party_account": flag,
|
||||||
"default_advance_paid_account": default_account,
|
"default_advance_paid_account": default_account,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
@ -32,10 +32,7 @@ from erpnext.assets.doctype.asset.depreciation import (
|
|||||||
reset_depreciation_schedule,
|
reset_depreciation_schedule,
|
||||||
reverse_depreciation_entry_made_after_disposal,
|
reverse_depreciation_entry_made_after_disposal,
|
||||||
)
|
)
|
||||||
from erpnext.controllers.accounts_controller import (
|
from erpnext.controllers.accounts_controller import validate_account_head
|
||||||
check_advance_liability_entry,
|
|
||||||
validate_account_head,
|
|
||||||
)
|
|
||||||
from erpnext.controllers.selling_controller import SellingController
|
from erpnext.controllers.selling_controller import SellingController
|
||||||
from erpnext.projects.doctype.timesheet.timesheet import get_projectwise_timesheet_data
|
from erpnext.projects.doctype.timesheet.timesheet import get_projectwise_timesheet_data
|
||||||
from erpnext.setup.doctype.company.company import update_company_current_month_sales
|
from erpnext.setup.doctype.company.company import update_company_current_month_sales
|
||||||
@ -1055,21 +1052,12 @@ class SalesInvoice(SellingController):
|
|||||||
elif self.docstatus == 2 and cint(self.update_stock) and cint(auto_accounting_for_stock):
|
elif self.docstatus == 2 and cint(self.update_stock) and cint(auto_accounting_for_stock):
|
||||||
make_reverse_gl_entries(voucher_type=self.doctype, voucher_no=self.name)
|
make_reverse_gl_entries(voucher_type=self.doctype, voucher_no=self.name)
|
||||||
|
|
||||||
def get_gl_entries(self, warehouse_account=None):
|
def get_gl_entries(self):
|
||||||
from erpnext.accounts.general_ledger import merge_similar_entries
|
from erpnext.accounts.general_ledger import merge_similar_entries
|
||||||
|
|
||||||
gl_entries = []
|
gl_entries = []
|
||||||
|
|
||||||
self.make_customer_gl_entry(gl_entries)
|
self.make_customer_gl_entry(gl_entries)
|
||||||
|
|
||||||
check_advance_liability_entry(
|
|
||||||
gl_entries,
|
|
||||||
company=self.company,
|
|
||||||
advances=self.advances,
|
|
||||||
invoice=self.name,
|
|
||||||
party_type="Customer",
|
|
||||||
)
|
|
||||||
|
|
||||||
self.make_tax_gl_entries(gl_entries)
|
self.make_tax_gl_entries(gl_entries)
|
||||||
self.make_exchange_gain_loss_gl_entries(gl_entries)
|
self.make_exchange_gain_loss_gl_entries(gl_entries)
|
||||||
self.make_internal_transfer_gl_entries(gl_entries)
|
self.make_internal_transfer_gl_entries(gl_entries)
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import unittest
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.model.dynamic_links import get_dynamic_link_map
|
from frappe.model.dynamic_links import get_dynamic_link_map
|
||||||
from frappe.model.naming import make_autoname
|
|
||||||
from frappe.tests.utils import change_settings
|
from frappe.tests.utils import change_settings
|
||||||
from frappe.utils import add_days, flt, getdate, nowdate, today
|
from frappe.utils import add_days, flt, getdate, nowdate, today
|
||||||
|
|
||||||
@ -35,7 +34,6 @@ from erpnext.stock.doctype.serial_and_batch_bundle.test_serial_and_batch_bundle
|
|||||||
get_serial_nos_from_bundle,
|
get_serial_nos_from_bundle,
|
||||||
make_serial_batch_bundle,
|
make_serial_batch_bundle,
|
||||||
)
|
)
|
||||||
from erpnext.stock.doctype.serial_no.serial_no import SerialNoWarehouseError
|
|
||||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import (
|
from erpnext.stock.doctype.stock_entry.test_stock_entry import (
|
||||||
get_qty_after_transaction,
|
get_qty_after_transaction,
|
||||||
make_stock_entry,
|
make_stock_entry,
|
||||||
@ -3314,7 +3312,14 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
def test_advance_entries_as_liability(self):
|
def test_advance_entries_as_liability(self):
|
||||||
from erpnext.accounts.doctype.payment_entry.test_payment_entry import create_payment_entry
|
from erpnext.accounts.doctype.payment_entry.test_payment_entry import create_payment_entry
|
||||||
|
|
||||||
set_advance_flag(company="_Test Company", flag=1, default_account="Creditors - _TC")
|
account = create_account(
|
||||||
|
parent_account="Current Liabilities - _TC",
|
||||||
|
account_name="Advances Received",
|
||||||
|
company="_Test Company",
|
||||||
|
account_type="Receivable",
|
||||||
|
)
|
||||||
|
|
||||||
|
set_advance_flag(company="_Test Company", flag=1, default_account=account)
|
||||||
|
|
||||||
pe = create_payment_entry(
|
pe = create_payment_entry(
|
||||||
company="_Test Company",
|
company="_Test Company",
|
||||||
@ -3347,13 +3352,15 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
|
|
||||||
# Check GL Entry against payment doctype
|
# Check GL Entry against payment doctype
|
||||||
expected_gle = [
|
expected_gle = [
|
||||||
|
["Advances Received - _TC", 500, 0.0, nowdate()],
|
||||||
["Cash - _TC", 1000, 0.0, nowdate()],
|
["Cash - _TC", 1000, 0.0, nowdate()],
|
||||||
["Creditors - _TC", 500, 0.0, nowdate()],
|
|
||||||
["Debtors - _TC", 0.0, 1000, nowdate()],
|
["Debtors - _TC", 0.0, 1000, nowdate()],
|
||||||
["Debtors - _TC", 0.0, 500, nowdate()],
|
["Debtors - _TC", 0.0, 500, nowdate()],
|
||||||
]
|
]
|
||||||
|
|
||||||
check_gl_entries(self, pe.name, expected_gle, nowdate(), voucher_type="Payment Entry")
|
check_gl_entries(self, pe.name, expected_gle, nowdate(), voucher_type="Payment Entry")
|
||||||
|
|
||||||
|
si.load_from_db()
|
||||||
self.assertEqual(si.outstanding_amount, 0)
|
self.assertEqual(si.outstanding_amount, 0)
|
||||||
|
|
||||||
set_advance_flag(company="_Test Company", flag=0, default_account="")
|
set_advance_flag(company="_Test Company", flag=0, default_account="")
|
||||||
@ -3364,7 +3371,7 @@ def set_advance_flag(company, flag, default_account):
|
|||||||
"Company",
|
"Company",
|
||||||
company,
|
company,
|
||||||
{
|
{
|
||||||
"book_advance_payments_as_liability": flag,
|
"book_advance_payments_in_separate_party_account": flag,
|
||||||
"default_advance_received_account": default_account,
|
"default_advance_received_account": default_account,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
@ -501,7 +501,12 @@ def get_round_off_account_and_cost_center(
|
|||||||
|
|
||||||
|
|
||||||
def make_reverse_gl_entries(
|
def make_reverse_gl_entries(
|
||||||
gl_entries=None, voucher_type=None, voucher_no=None, adv_adj=False, update_outstanding="Yes"
|
gl_entries=None,
|
||||||
|
voucher_type=None,
|
||||||
|
voucher_no=None,
|
||||||
|
adv_adj=False,
|
||||||
|
update_outstanding="Yes",
|
||||||
|
partial_cancel=False,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Get original gl entries of the voucher
|
Get original gl entries of the voucher
|
||||||
@ -528,7 +533,8 @@ def make_reverse_gl_entries(
|
|||||||
|
|
||||||
is_opening = any(d.get("is_opening") == "Yes" for d in gl_entries)
|
is_opening = any(d.get("is_opening") == "Yes" for d in gl_entries)
|
||||||
validate_against_pcv(is_opening, gl_entries[0]["posting_date"], gl_entries[0]["company"])
|
validate_against_pcv(is_opening, gl_entries[0]["posting_date"], gl_entries[0]["company"])
|
||||||
set_as_cancel(gl_entries[0]["voucher_type"], gl_entries[0]["voucher_no"])
|
if not partial_cancel:
|
||||||
|
set_as_cancel(gl_entries[0]["voucher_type"], gl_entries[0]["voucher_no"])
|
||||||
|
|
||||||
for entry in gl_entries:
|
for entry in gl_entries:
|
||||||
new_gle = copy.deepcopy(entry)
|
new_gle = copy.deepcopy(entry)
|
||||||
|
|||||||
@ -474,6 +474,7 @@ def reconcile_against_document(args, skip_ref_details_update_for_pe=False): # n
|
|||||||
doc = frappe.get_doc(entry.voucher_type, entry.voucher_no)
|
doc = frappe.get_doc(entry.voucher_type, entry.voucher_no)
|
||||||
gl_map = doc.build_gl_map()
|
gl_map = doc.build_gl_map()
|
||||||
create_payment_ledger_entry(gl_map, update_outstanding="No", cancel=0, adv_adj=1)
|
create_payment_ledger_entry(gl_map, update_outstanding="No", cancel=0, adv_adj=1)
|
||||||
|
doc.make_advance_gl_entries(entry.against_voucher_type, entry.against_voucher)
|
||||||
|
|
||||||
# Only update outstanding for newly linked vouchers
|
# Only update outstanding for newly linked vouchers
|
||||||
for entry in entries:
|
for entry in entries:
|
||||||
@ -731,8 +732,9 @@ def remove_ref_doc_link_from_pe(ref_type, ref_no):
|
|||||||
|
|
||||||
for pe in linked_pe:
|
for pe in linked_pe:
|
||||||
try:
|
try:
|
||||||
pe_doc = frappe.get_doc("Payment Entry", pe)
|
pe_doc = frappe.get_doc("Payment Entry", pe, cache=True)
|
||||||
pe_doc.set_amounts()
|
pe_doc.set_amounts()
|
||||||
|
pe_doc.make_advance_gl_entries(against_voucher_type=ref_type, against_voucher=ref_no, cancel=1)
|
||||||
pe_doc.clear_unallocated_reference_document_rows()
|
pe_doc.clear_unallocated_reference_document_rows()
|
||||||
pe_doc.validate_payment_type_with_outstanding()
|
pe_doc.validate_payment_type_with_outstanding()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@ -22,7 +22,8 @@ frappe.ui.form.on("Supplier", {
|
|||||||
let d = locals[cdt][cdn];
|
let d = locals[cdt][cdn];
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
"account_type": "Receivable",
|
"account_type": "Payable",
|
||||||
|
"root_type": "Asset",
|
||||||
"company": d.company,
|
"company": d.company,
|
||||||
"is_group": 0
|
"is_group": 0
|
||||||
}
|
}
|
||||||
|
|||||||
@ -756,6 +756,7 @@ class AccountsController(TransactionBase):
|
|||||||
"party": None,
|
"party": None,
|
||||||
"project": self.get("project"),
|
"project": self.get("project"),
|
||||||
"post_net_value": args.get("post_net_value"),
|
"post_net_value": args.get("post_net_value"),
|
||||||
|
"voucher_detail_no": args.get("voucher_detail_no"),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -2915,82 +2916,82 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
|
|||||||
parent.create_stock_reservation_entries()
|
parent.create_stock_reservation_entries()
|
||||||
|
|
||||||
|
|
||||||
def make_advance_liability_entry(
|
# def make_advance_liability_entry(
|
||||||
gl_entries, pe, allocated_amount, invoice, party_type, references=False
|
# gl_entries, pe, allocated_amount, invoice, party_type
|
||||||
):
|
# ):
|
||||||
pe = frappe.get_doc("Payment Entry", pe)
|
# pe = frappe.get_doc("Payment Entry", pe)
|
||||||
if party_type == "Customer":
|
# if party_type == "Customer":
|
||||||
invoice = frappe.get_doc("Sales Invoice", invoice)
|
# invoice = frappe.get_doc("Sales Invoice", invoice)
|
||||||
account = pe.paid_from
|
# account = pe.paid_from
|
||||||
dr_or_cr = "debit"
|
# dr_or_cr = "debit"
|
||||||
rev = "credit"
|
# rev = "credit"
|
||||||
against = invoice.debit_to
|
# against = invoice.debit_to
|
||||||
party = invoice.customer
|
# party = invoice.customer
|
||||||
else:
|
# else:
|
||||||
invoice = frappe.get_doc("Purchase Invoice", invoice)
|
# invoice = frappe.get_doc("Purchase Invoice", invoice)
|
||||||
account = pe.paid_to
|
# account = pe.paid_to
|
||||||
dr_or_cr = "credit"
|
# dr_or_cr = "credit"
|
||||||
rev = "debit"
|
# rev = "debit"
|
||||||
against = invoice.credit_to
|
# against = invoice.credit_to
|
||||||
party = invoice.supplier
|
# party = invoice.supplier
|
||||||
gl_entries.append(
|
# gl_entries.append(
|
||||||
pe.get_gl_dict(
|
# pe.get_gl_dict(
|
||||||
{
|
# {
|
||||||
"account": account,
|
# "account": account,
|
||||||
"party_type": party_type,
|
# "party_type": party_type,
|
||||||
"party": party,
|
# "party": party,
|
||||||
"due_date": invoice.due_date,
|
# "due_date": invoice.due_date,
|
||||||
"against": against,
|
# "against": against,
|
||||||
dr_or_cr: allocated_amount,
|
# dr_or_cr: allocated_amount,
|
||||||
dr_or_cr + "_in_account_currency": allocated_amount,
|
# dr_or_cr + "_in_account_currency": allocated_amount,
|
||||||
rev: 0,
|
# rev: 0,
|
||||||
rev + "_in_account_currency": 0,
|
# rev + "_in_account_currency": 0,
|
||||||
"cost_center": invoice.cost_center,
|
# "cost_center": invoice.cost_center,
|
||||||
"project": invoice.project,
|
# "project": invoice.project,
|
||||||
"against_voucher_type": "Payment Entry",
|
# "against_voucher_type": "Payment Entry",
|
||||||
"against_voucher": pe.name,
|
# "against_voucher": pe.name,
|
||||||
},
|
# },
|
||||||
invoice.party_account_currency,
|
# invoice.party_account_currency,
|
||||||
item=pe,
|
# item=pe,
|
||||||
)
|
# )
|
||||||
)
|
# )
|
||||||
|
|
||||||
(dr_or_cr, rev) = ("credit", "debit") if party_type == "Customer" else ("debit", "credit")
|
# (dr_or_cr, rev) = ("credit", "debit") if party_type == "Customer" else ("debit", "credit")
|
||||||
gl_entries.append(
|
# gl_entries.append(
|
||||||
pe.get_gl_dict(
|
# pe.get_gl_dict(
|
||||||
{
|
# {
|
||||||
"account": against,
|
# "account": against,
|
||||||
"party_type": party_type,
|
# "party_type": party_type,
|
||||||
"party": party,
|
# "party": party,
|
||||||
"due_date": invoice.due_date,
|
# "due_date": invoice.due_date,
|
||||||
dr_or_cr: allocated_amount,
|
# dr_or_cr: allocated_amount,
|
||||||
dr_or_cr + "_in_account_currency": allocated_amount,
|
# dr_or_cr + "_in_account_currency": allocated_amount,
|
||||||
rev: 0,
|
# rev: 0,
|
||||||
rev + "_in_account_currency": 0,
|
# rev + "_in_account_currency": 0,
|
||||||
"cost_center": invoice.cost_center,
|
# "cost_center": invoice.cost_center,
|
||||||
"project": invoice.project,
|
# "project": invoice.project,
|
||||||
"against_voucher_type": invoice.doctype,
|
# "against_voucher_type": invoice.doctype,
|
||||||
"against_voucher": invoice.name,
|
# "against_voucher": invoice.name,
|
||||||
},
|
# },
|
||||||
invoice.party_account_currency,
|
# invoice.party_account_currency,
|
||||||
item=pe,
|
# item=pe,
|
||||||
)
|
# )
|
||||||
)
|
# )
|
||||||
|
|
||||||
|
|
||||||
def check_advance_liability_entry(gl_entries, company, advances, invoice, party_type):
|
# def check_advance_liability_entry(gl_entries, company, advances, invoice, party_type):
|
||||||
advance_payments_as_liability = frappe.db.get_value(
|
# advance_payments_as_liability = frappe.db.get_value(
|
||||||
"Company", {"company_name": company}, "book_advance_payments_as_liability"
|
# "Company", {"company_name": company}, "book_advance_payments_as_liability"
|
||||||
)
|
# )
|
||||||
if advance_payments_as_liability:
|
# if advance_payments_as_liability:
|
||||||
for advance_entry in advances:
|
# for advance_entry in advances:
|
||||||
make_advance_liability_entry(
|
# make_advance_liability_entry(
|
||||||
gl_entries,
|
# gl_entries,
|
||||||
advance_entry.reference_name,
|
# advance_entry.reference_name,
|
||||||
advance_entry.allocated_amount,
|
# advance_entry.allocated_amount,
|
||||||
invoice=invoice,
|
# invoice=invoice,
|
||||||
party_type=party_type,
|
# party_type=party_type,
|
||||||
)
|
# )
|
||||||
|
|
||||||
|
|
||||||
@erpnext.allow_regional
|
@erpnext.allow_regional
|
||||||
|
|||||||
@ -39,7 +39,8 @@ frappe.ui.form.on("Customer", {
|
|||||||
let d = locals[cdt][cdn];
|
let d = locals[cdt][cdn];
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
"account_type": 'Payable',
|
"account_type": 'Receivable',
|
||||||
|
"root_type": "Liability",
|
||||||
"company": d.company,
|
"company": d.company,
|
||||||
"is_group": 0
|
"is_group": 0
|
||||||
}
|
}
|
||||||
|
|||||||
@ -227,8 +227,8 @@ erpnext.company.setup_queries = function(frm) {
|
|||||||
["asset_received_but_not_billed", {"account_type": "Asset Received But Not Billed"}],
|
["asset_received_but_not_billed", {"account_type": "Asset Received But Not Billed"}],
|
||||||
["unrealized_profit_loss_account", {"root_type": ["in", ["Liability", "Asset"]]}],
|
["unrealized_profit_loss_account", {"root_type": ["in", ["Liability", "Asset"]]}],
|
||||||
["default_provisional_account", {"root_type": ["in", ["Liability", "Asset"]]}],
|
["default_provisional_account", {"root_type": ["in", ["Liability", "Asset"]]}],
|
||||||
["default_advance_received_account", {"account_type": "Payable"}],
|
["default_advance_received_account", {"root_type": "Liability", "account_type": "Receivable"}],
|
||||||
["default_advance_paid_account", {"account_type": "Receivable"}],
|
["default_advance_paid_account", {"root_type": "Asset", "account_type": "Payable"}],
|
||||||
], function(i, v) {
|
], function(i, v) {
|
||||||
erpnext.company.set_custom_query(frm, v);
|
erpnext.company.set_custom_query(frm, v);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -71,7 +71,7 @@
|
|||||||
"cost_center",
|
"cost_center",
|
||||||
"default_finance_book",
|
"default_finance_book",
|
||||||
"advance_payments_section",
|
"advance_payments_section",
|
||||||
"book_advance_payments_as_liability",
|
"book_advance_payments_in_separate_party_account",
|
||||||
"column_break_fwcf",
|
"column_break_fwcf",
|
||||||
"default_advance_received_account",
|
"default_advance_received_account",
|
||||||
"default_advance_paid_account",
|
"default_advance_paid_account",
|
||||||
@ -700,20 +700,13 @@
|
|||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "Account"
|
"options": "Account"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"default": "0",
|
|
||||||
"description": "Enabling this option will allow you to record - <br><br> 1. Advances Received in a <b>Liability Account</b> instead of the <b>Receivable Account</b><br><br>2. Advances Paid in an <b>Asset Account</b> instead of the <b> Payable Account</b>",
|
|
||||||
"fieldname": "book_advance_payments_as_liability",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"label": "Book Advance Payments in Separate Party Account"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "advance_payments_section",
|
"fieldname": "advance_payments_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Advance Payments"
|
"label": "Advance Payments"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:doc.book_advance_payments_as_liability",
|
"depends_on": "eval:doc.book_advance_payments_in_separate_party_account",
|
||||||
"fieldname": "default_advance_received_account",
|
"fieldname": "default_advance_received_account",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Default Advance Received Account",
|
"label": "Default Advance Received Account",
|
||||||
@ -721,7 +714,7 @@
|
|||||||
"options": "Account"
|
"options": "Account"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:doc.book_advance_payments_as_liability",
|
"depends_on": "eval:doc.book_advance_payments_in_separate_party_account",
|
||||||
"fieldname": "default_advance_paid_account",
|
"fieldname": "default_advance_paid_account",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Default Advance Paid Account",
|
"label": "Default Advance Paid Account",
|
||||||
@ -731,6 +724,13 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "column_break_fwcf",
|
"fieldname": "column_break_fwcf",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"description": "Enabling this option will allow you to record - <br><br> 1. Advances Received in a <b>Liability Account</b> instead of the <b>Asset Account</b><br><br>2. Advances Paid in an <b>Asset Account</b> instead of the <b> Liability Account</b>",
|
||||||
|
"fieldname": "book_advance_payments_in_separate_party_account",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Book Advance Payments in Separate Party Account"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-building",
|
"icon": "fa fa-building",
|
||||||
@ -738,7 +738,7 @@
|
|||||||
"image_field": "company_logo",
|
"image_field": "company_logo",
|
||||||
"is_tree": 1,
|
"is_tree": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-06-16 13:32:48.790947",
|
"modified": "2023-06-23 18:22:27.219706",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Setup",
|
"module": "Setup",
|
||||||
"name": "Company",
|
"name": "Company",
|
||||||
|
|||||||
@ -41,6 +41,7 @@ frappe.ui.form.on("Customer Group", {
|
|||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
"root_type": 'Liability',
|
"root_type": 'Liability',
|
||||||
|
"account_type": "Receivable",
|
||||||
"company": locals[cdt][cdn].company,
|
"company": locals[cdt][cdn].company,
|
||||||
"is_group": 0
|
"is_group": 0
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,6 +41,7 @@ frappe.ui.form.on("Supplier Group", {
|
|||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
"root_type": 'Asset',
|
"root_type": 'Asset',
|
||||||
|
"account_type": "Payable",
|
||||||
"company": locals[cdt][cdn].company,
|
"company": locals[cdt][cdn].company,
|
||||||
"is_group": 0
|
"is_group": 0
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user