mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-01 11:19:09 +00:00
Merge pull request #34161 from frappe/version-14-hotfix
chore: release v14
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
# the repo. Unless a later match takes precedence,
|
# the repo. Unless a later match takes precedence,
|
||||||
|
|
||||||
erpnext/accounts/ @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
|
erpnext/accounts/ @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
|
||||||
erpnext/assets/ @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
|
erpnext/assets/ @anandbaburajan @deepeshgarg007
|
||||||
erpnext/loan_management/ @nextchamp-saqib @deepeshgarg007
|
erpnext/loan_management/ @nextchamp-saqib @deepeshgarg007
|
||||||
erpnext/regional @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
|
erpnext/regional @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
|
||||||
erpnext/selling @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
|
erpnext/selling @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
|
||||||
@@ -16,6 +16,7 @@ erpnext/maintenance/ @rohitwaghchaure @s-aga-r
|
|||||||
erpnext/manufacturing/ @rohitwaghchaure @s-aga-r
|
erpnext/manufacturing/ @rohitwaghchaure @s-aga-r
|
||||||
erpnext/quality_management/ @rohitwaghchaure @s-aga-r
|
erpnext/quality_management/ @rohitwaghchaure @s-aga-r
|
||||||
erpnext/stock/ @rohitwaghchaure @s-aga-r
|
erpnext/stock/ @rohitwaghchaure @s-aga-r
|
||||||
|
erpnext/subcontracting @rohitwaghchaure @s-aga-r
|
||||||
|
|
||||||
erpnext/crm/ @NagariaHussain
|
erpnext/crm/ @NagariaHussain
|
||||||
erpnext/education/ @rutwikhdev
|
erpnext/education/ @rutwikhdev
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ frappe.provide("erpnext.journal_entry");
|
|||||||
frappe.ui.form.on("Journal Entry", {
|
frappe.ui.form.on("Journal Entry", {
|
||||||
setup: function(frm) {
|
setup: function(frm) {
|
||||||
frm.add_fetch("bank_account", "account", "account");
|
frm.add_fetch("bank_account", "account", "account");
|
||||||
frm.ignore_doctypes_on_cancel_all = ['Sales Invoice', 'Purchase Invoice', 'Journal Entry'];
|
frm.ignore_doctypes_on_cancel_all = ['Sales Invoice', 'Purchase Invoice', 'Journal Entry', "Repost Payment Ledger"];
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh: function(frm) {
|
refresh: function(frm) {
|
||||||
|
|||||||
@@ -89,7 +89,13 @@ class JournalEntry(AccountsController):
|
|||||||
from erpnext.accounts.utils import unlink_ref_doc_from_payment_entries
|
from erpnext.accounts.utils import unlink_ref_doc_from_payment_entries
|
||||||
|
|
||||||
unlink_ref_doc_from_payment_entries(self)
|
unlink_ref_doc_from_payment_entries(self)
|
||||||
self.ignore_linked_doctypes = ("GL Entry", "Stock Ledger Entry", "Payment Ledger Entry")
|
self.ignore_linked_doctypes = (
|
||||||
|
"GL Entry",
|
||||||
|
"Stock Ledger Entry",
|
||||||
|
"Payment Ledger Entry",
|
||||||
|
"Repost Payment Ledger",
|
||||||
|
"Repost Payment Ledger Items",
|
||||||
|
)
|
||||||
self.make_gl_entries(1)
|
self.make_gl_entries(1)
|
||||||
self.update_advance_paid()
|
self.update_advance_paid()
|
||||||
self.unlink_advance_entry_reference()
|
self.unlink_advance_entry_reference()
|
||||||
@@ -238,21 +244,16 @@ class JournalEntry(AccountsController):
|
|||||||
):
|
):
|
||||||
processed_assets.append(d.reference_name)
|
processed_assets.append(d.reference_name)
|
||||||
|
|
||||||
asset = frappe.db.get_value(
|
asset = frappe.get_doc("Asset", d.reference_name)
|
||||||
"Asset", d.reference_name, ["calculate_depreciation", "value_after_depreciation"], as_dict=1
|
|
||||||
)
|
|
||||||
|
|
||||||
if asset.calculate_depreciation:
|
if asset.calculate_depreciation:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
depr_value = d.debit or d.credit
|
depr_value = d.debit or d.credit
|
||||||
|
|
||||||
frappe.db.set_value(
|
asset.db_set("value_after_depreciation", asset.value_after_depreciation - depr_value)
|
||||||
"Asset",
|
|
||||||
d.reference_name,
|
asset.set_status()
|
||||||
"value_after_depreciation",
|
|
||||||
asset.value_after_depreciation - depr_value,
|
|
||||||
)
|
|
||||||
|
|
||||||
def update_inter_company_jv(self):
|
def update_inter_company_jv(self):
|
||||||
if (
|
if (
|
||||||
@@ -341,12 +342,9 @@ class JournalEntry(AccountsController):
|
|||||||
else:
|
else:
|
||||||
depr_value = d.debit or d.credit
|
depr_value = d.debit or d.credit
|
||||||
|
|
||||||
frappe.db.set_value(
|
asset.db_set("value_after_depreciation", asset.value_after_depreciation + depr_value)
|
||||||
"Asset",
|
|
||||||
d.reference_name,
|
asset.set_status()
|
||||||
"value_after_depreciation",
|
|
||||||
asset.value_after_depreciation + depr_value,
|
|
||||||
)
|
|
||||||
|
|
||||||
def unlink_inter_company_jv(self):
|
def unlink_inter_company_jv(self):
|
||||||
if (
|
if (
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ cur_frm.cscript.tax_table = "Advance Taxes and Charges";
|
|||||||
|
|
||||||
frappe.ui.form.on('Payment Entry', {
|
frappe.ui.form.on('Payment Entry', {
|
||||||
onload: function(frm) {
|
onload: function(frm) {
|
||||||
frm.ignore_doctypes_on_cancel_all = ['Sales Invoice', 'Purchase Invoice'];
|
frm.ignore_doctypes_on_cancel_all = ['Sales Invoice', 'Purchase Invoice', "Repost Payment Ledger"];
|
||||||
|
|
||||||
if(frm.doc.__islocal) {
|
if(frm.doc.__islocal) {
|
||||||
if (!frm.doc.paid_from) frm.set_value("paid_from_account_currency", null);
|
if (!frm.doc.paid_from) frm.set_value("paid_from_account_currency", null);
|
||||||
|
|||||||
@@ -239,7 +239,7 @@
|
|||||||
"depends_on": "paid_from",
|
"depends_on": "paid_from",
|
||||||
"fieldname": "paid_from_account_currency",
|
"fieldname": "paid_from_account_currency",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Account Currency",
|
"label": "Account Currency (From)",
|
||||||
"options": "Currency",
|
"options": "Currency",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
@@ -249,7 +249,7 @@
|
|||||||
"depends_on": "paid_from",
|
"depends_on": "paid_from",
|
||||||
"fieldname": "paid_from_account_balance",
|
"fieldname": "paid_from_account_balance",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Account Balance",
|
"label": "Account Balance (From)",
|
||||||
"options": "paid_from_account_currency",
|
"options": "paid_from_account_currency",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
@@ -272,7 +272,7 @@
|
|||||||
"depends_on": "paid_to",
|
"depends_on": "paid_to",
|
||||||
"fieldname": "paid_to_account_currency",
|
"fieldname": "paid_to_account_currency",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Account Currency",
|
"label": "Account Currency (To)",
|
||||||
"options": "Currency",
|
"options": "Currency",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
@@ -282,7 +282,7 @@
|
|||||||
"depends_on": "paid_to",
|
"depends_on": "paid_to",
|
||||||
"fieldname": "paid_to_account_balance",
|
"fieldname": "paid_to_account_balance",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Account Balance",
|
"label": "Account Balance (To)",
|
||||||
"options": "paid_to_account_currency",
|
"options": "paid_to_account_currency",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
@@ -304,7 +304,7 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "source_exchange_rate",
|
"fieldname": "source_exchange_rate",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"label": "Exchange Rate",
|
"label": "Source Exchange Rate",
|
||||||
"precision": "9",
|
"precision": "9",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
@@ -334,7 +334,7 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "target_exchange_rate",
|
"fieldname": "target_exchange_rate",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"label": "Exchange Rate",
|
"label": "Target Exchange Rate",
|
||||||
"precision": "9",
|
"precision": "9",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
@@ -633,14 +633,14 @@
|
|||||||
"depends_on": "eval:doc.party_type == 'Supplier'",
|
"depends_on": "eval:doc.party_type == 'Supplier'",
|
||||||
"fieldname": "purchase_taxes_and_charges_template",
|
"fieldname": "purchase_taxes_and_charges_template",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Taxes and Charges Template",
|
"label": "Purchase Taxes and Charges Template",
|
||||||
"options": "Purchase Taxes and Charges Template"
|
"options": "Purchase Taxes and Charges Template"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval: doc.party_type == 'Customer'",
|
"depends_on": "eval: doc.party_type == 'Customer'",
|
||||||
"fieldname": "sales_taxes_and_charges_template",
|
"fieldname": "sales_taxes_and_charges_template",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Taxes and Charges Template",
|
"label": "Sales Taxes and Charges Template",
|
||||||
"options": "Sales Taxes and Charges Template"
|
"options": "Sales Taxes and Charges Template"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -733,7 +733,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-12-08 16:25:43.824051",
|
"modified": "2023-02-14 04:52:30.478523",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Payment Entry",
|
"name": "Payment Entry",
|
||||||
|
|||||||
@@ -92,7 +92,13 @@ class PaymentEntry(AccountsController):
|
|||||||
self.set_status()
|
self.set_status()
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
self.ignore_linked_doctypes = ("GL Entry", "Stock Ledger Entry", "Payment Ledger Entry")
|
self.ignore_linked_doctypes = (
|
||||||
|
"GL Entry",
|
||||||
|
"Stock Ledger Entry",
|
||||||
|
"Payment Ledger Entry",
|
||||||
|
"Repost Payment Ledger",
|
||||||
|
"Repost Payment Ledger Items",
|
||||||
|
)
|
||||||
self.make_gl_entries(cancel=1)
|
self.make_gl_entries(cancel=1)
|
||||||
self.update_outstanding_amounts()
|
self.update_outstanding_amounts()
|
||||||
self.update_advance_paid()
|
self.update_advance_paid()
|
||||||
|
|||||||
@@ -368,6 +368,7 @@ class PaymentReconciliation(Document):
|
|||||||
"exchange_rate": 1,
|
"exchange_rate": 1,
|
||||||
"cost_center": erpnext.get_default_cost_center(self.company),
|
"cost_center": erpnext.get_default_cost_center(self.company),
|
||||||
reverse_dr_or_cr + "_in_account_currency": flt(row.difference_amount),
|
reverse_dr_or_cr + "_in_account_currency": flt(row.difference_amount),
|
||||||
|
reverse_dr_or_cr: flt(row.difference_amount),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -495,7 +495,7 @@ def get_amount(ref_doc, payment_account=None):
|
|||||||
"""get amount based on doctype"""
|
"""get amount based on doctype"""
|
||||||
dt = ref_doc.doctype
|
dt = ref_doc.doctype
|
||||||
if dt in ["Sales Order", "Purchase Order"]:
|
if dt in ["Sales Order", "Purchase Order"]:
|
||||||
grand_total = flt(ref_doc.grand_total) - flt(ref_doc.advance_paid)
|
grand_total = flt(ref_doc.rounded_total) - flt(ref_doc.advance_paid)
|
||||||
|
|
||||||
elif dt in ["Sales Invoice", "Purchase Invoice"]:
|
elif dt in ["Sales Invoice", "Purchase Invoice"]:
|
||||||
if ref_doc.party_account_currency == ref_doc.currency:
|
if ref_doc.party_account_currency == ref_doc.currency:
|
||||||
|
|||||||
@@ -21,8 +21,24 @@ class POSClosingEntry(StatusUpdater):
|
|||||||
if frappe.db.get_value("POS Opening Entry", self.pos_opening_entry, "status") != "Open":
|
if frappe.db.get_value("POS Opening Entry", self.pos_opening_entry, "status") != "Open":
|
||||||
frappe.throw(_("Selected POS Opening Entry should be open."), title=_("Invalid Opening Entry"))
|
frappe.throw(_("Selected POS Opening Entry should be open."), title=_("Invalid Opening Entry"))
|
||||||
|
|
||||||
|
self.validate_duplicate_pos_invoices()
|
||||||
self.validate_pos_invoices()
|
self.validate_pos_invoices()
|
||||||
|
|
||||||
|
def validate_duplicate_pos_invoices(self):
|
||||||
|
pos_occurences = {}
|
||||||
|
for idx, inv in enumerate(self.pos_transactions, 1):
|
||||||
|
pos_occurences.setdefault(inv.pos_invoice, []).append(idx)
|
||||||
|
|
||||||
|
error_list = []
|
||||||
|
for key, value in pos_occurences.items():
|
||||||
|
if len(value) > 1:
|
||||||
|
error_list.append(
|
||||||
|
_("{} is added multiple times on rows: {}".format(frappe.bold(key), frappe.bold(value)))
|
||||||
|
)
|
||||||
|
|
||||||
|
if error_list:
|
||||||
|
frappe.throw(error_list, title=_("Duplicate POS Invoices found"), as_list=True)
|
||||||
|
|
||||||
def validate_pos_invoices(self):
|
def validate_pos_invoices(self):
|
||||||
invalid_rows = []
|
invalid_rows = []
|
||||||
for d in self.pos_transactions:
|
for d in self.pos_transactions:
|
||||||
|
|||||||
@@ -18,6 +18,22 @@ class POSInvoiceMergeLog(Document):
|
|||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_customer()
|
self.validate_customer()
|
||||||
self.validate_pos_invoice_status()
|
self.validate_pos_invoice_status()
|
||||||
|
self.validate_duplicate_pos_invoices()
|
||||||
|
|
||||||
|
def validate_duplicate_pos_invoices(self):
|
||||||
|
pos_occurences = {}
|
||||||
|
for idx, inv in enumerate(self.pos_invoices, 1):
|
||||||
|
pos_occurences.setdefault(inv.pos_invoice, []).append(idx)
|
||||||
|
|
||||||
|
error_list = []
|
||||||
|
for key, value in pos_occurences.items():
|
||||||
|
if len(value) > 1:
|
||||||
|
error_list.append(
|
||||||
|
_("{} is added multiple times on rows: {}".format(frappe.bold(key), frappe.bold(value)))
|
||||||
|
)
|
||||||
|
|
||||||
|
if error_list:
|
||||||
|
frappe.throw(error_list, title=_("Duplicate POS Invoices found"), as_list=True)
|
||||||
|
|
||||||
def validate_customer(self):
|
def validate_customer(self):
|
||||||
if self.merge_invoices_based_on == "Customer Group":
|
if self.merge_invoices_based_on == "Customer Group":
|
||||||
@@ -426,6 +442,8 @@ def create_merge_logs(invoice_by_customer, closing_entry=None):
|
|||||||
|
|
||||||
if closing_entry:
|
if closing_entry:
|
||||||
closing_entry.set_status(update=True, status="Failed")
|
closing_entry.set_status(update=True, status="Failed")
|
||||||
|
if type(error_message) == list:
|
||||||
|
error_message = frappe.json.dumps(error_message)
|
||||||
closing_entry.db_set("error_message", error_message)
|
closing_entry.db_set("error_message", error_message)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|||||||
@@ -472,7 +472,7 @@
|
|||||||
"description": "If rate is zero them item will be treated as \"Free Item\"",
|
"description": "If rate is zero them item will be treated as \"Free Item\"",
|
||||||
"fieldname": "free_item_rate",
|
"fieldname": "free_item_rate",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Rate"
|
"label": "Free Item Rate"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"collapsible": 1,
|
"collapsible": 1,
|
||||||
@@ -608,7 +608,7 @@
|
|||||||
"icon": "fa fa-gift",
|
"icon": "fa fa-gift",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-10-13 19:05:35.056304",
|
"modified": "2023-02-14 04:53:34.887358",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Pricing Rule",
|
"name": "Pricing Rule",
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ erpnext.accounts.PurchaseInvoice = class PurchaseInvoice extends erpnext.buying.
|
|||||||
super.onload();
|
super.onload();
|
||||||
|
|
||||||
// Ignore linked advances
|
// Ignore linked advances
|
||||||
this.frm.ignore_doctypes_on_cancel_all = ['Journal Entry', 'Payment Entry', 'Purchase Invoice'];
|
this.frm.ignore_doctypes_on_cancel_all = ['Journal Entry', 'Payment Entry', 'Purchase Invoice', "Repost Payment Ledger"];
|
||||||
|
|
||||||
if(!this.frm.doc.__islocal) {
|
if(!this.frm.doc.__islocal) {
|
||||||
// show credit_to in print format
|
// show credit_to in print format
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import _, throw
|
from frappe import _, throw
|
||||||
from frappe.model.mapper import get_mapped_doc
|
from frappe.model.mapper import get_mapped_doc
|
||||||
|
from frappe.query_builder.functions import Sum
|
||||||
from frappe.utils import cint, cstr, flt, formatdate, get_link_to_form, getdate, nowdate
|
from frappe.utils import cint, cstr, flt, formatdate, get_link_to_form, getdate, nowdate
|
||||||
|
|
||||||
import erpnext
|
import erpnext
|
||||||
@@ -1416,6 +1417,8 @@ class PurchaseInvoice(BuyingController):
|
|||||||
"GL Entry",
|
"GL Entry",
|
||||||
"Stock Ledger Entry",
|
"Stock Ledger Entry",
|
||||||
"Repost Item Valuation",
|
"Repost Item Valuation",
|
||||||
|
"Repost Payment Ledger",
|
||||||
|
"Repost Payment Ledger Items",
|
||||||
"Payment Ledger Entry",
|
"Payment Ledger Entry",
|
||||||
"Tax Withheld Vouchers",
|
"Tax Withheld Vouchers",
|
||||||
)
|
)
|
||||||
@@ -1463,19 +1466,16 @@ class PurchaseInvoice(BuyingController):
|
|||||||
def update_billing_status_in_pr(self, update_modified=True):
|
def update_billing_status_in_pr(self, update_modified=True):
|
||||||
updated_pr = []
|
updated_pr = []
|
||||||
po_details = []
|
po_details = []
|
||||||
|
|
||||||
|
pr_details_billed_amt = self.get_pr_details_billed_amt()
|
||||||
|
|
||||||
for d in self.get("items"):
|
for d in self.get("items"):
|
||||||
if d.pr_detail:
|
if d.pr_detail:
|
||||||
billed_amt = frappe.db.sql(
|
|
||||||
"""select sum(amount) from `tabPurchase Invoice Item`
|
|
||||||
where pr_detail=%s and docstatus=1""",
|
|
||||||
d.pr_detail,
|
|
||||||
)
|
|
||||||
billed_amt = billed_amt and billed_amt[0][0] or 0
|
|
||||||
frappe.db.set_value(
|
frappe.db.set_value(
|
||||||
"Purchase Receipt Item",
|
"Purchase Receipt Item",
|
||||||
d.pr_detail,
|
d.pr_detail,
|
||||||
"billed_amt",
|
"billed_amt",
|
||||||
billed_amt,
|
flt(pr_details_billed_amt.get(d.pr_detail)),
|
||||||
update_modified=update_modified,
|
update_modified=update_modified,
|
||||||
)
|
)
|
||||||
updated_pr.append(d.purchase_receipt)
|
updated_pr.append(d.purchase_receipt)
|
||||||
@@ -1491,6 +1491,24 @@ class PurchaseInvoice(BuyingController):
|
|||||||
pr_doc = frappe.get_doc("Purchase Receipt", pr)
|
pr_doc = frappe.get_doc("Purchase Receipt", pr)
|
||||||
update_billing_percentage(pr_doc, update_modified=update_modified)
|
update_billing_percentage(pr_doc, update_modified=update_modified)
|
||||||
|
|
||||||
|
def get_pr_details_billed_amt(self):
|
||||||
|
# Get billed amount based on purchase receipt item reference (pr_detail) in purchase invoice
|
||||||
|
|
||||||
|
pr_details_billed_amt = {}
|
||||||
|
pr_details = [d.get("pr_detail") for d in self.get("items") if d.get("pr_detail")]
|
||||||
|
if pr_details:
|
||||||
|
doctype = frappe.qb.DocType("Purchase Invoice Item")
|
||||||
|
query = (
|
||||||
|
frappe.qb.from_(doctype)
|
||||||
|
.select(doctype.pr_detail, Sum(doctype.amount))
|
||||||
|
.where(doctype.pr_detail.isin(pr_details) & doctype.docstatus == 1)
|
||||||
|
.groupby(doctype.pr_detail)
|
||||||
|
)
|
||||||
|
|
||||||
|
pr_details_billed_amt = frappe._dict(query.run(as_list=1))
|
||||||
|
|
||||||
|
return pr_details_billed_amt
|
||||||
|
|
||||||
def on_recurring(self, reference_doc, auto_repeat_doc):
|
def on_recurring(self, reference_doc, auto_repeat_doc):
|
||||||
self.due_date = None
|
self.due_date = None
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends e
|
|||||||
super.onload();
|
super.onload();
|
||||||
|
|
||||||
this.frm.ignore_doctypes_on_cancel_all = ['POS Invoice', 'Timesheet', 'POS Invoice Merge Log',
|
this.frm.ignore_doctypes_on_cancel_all = ['POS Invoice', 'Timesheet', 'POS Invoice Merge Log',
|
||||||
'POS Closing Entry', 'Journal Entry', 'Payment Entry'];
|
'POS Closing Entry', 'Journal Entry', 'Payment Entry', "Repost Payment Ledger"];
|
||||||
|
|
||||||
if(!this.frm.doc.__islocal && !this.frm.doc.customer && this.frm.doc.debit_to) {
|
if(!this.frm.doc.__islocal && !this.frm.doc.customer && this.frm.doc.debit_to) {
|
||||||
// show debit_to in print format
|
// show debit_to in print format
|
||||||
@@ -64,6 +64,25 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends e
|
|||||||
|
|
||||||
this.frm.toggle_reqd("due_date", !this.frm.doc.is_return);
|
this.frm.toggle_reqd("due_date", !this.frm.doc.is_return);
|
||||||
|
|
||||||
|
if (this.frm.doc.repost_required && this.frm.doc.docstatus===1) {
|
||||||
|
this.frm.set_intro(__("Accounting entries for this invoice needs to be reposted. Please click on 'Repost' button to update."));
|
||||||
|
this.frm.add_custom_button(__('Repost Accounting Entries'),
|
||||||
|
() => {
|
||||||
|
this.frm.call({
|
||||||
|
doc: this.frm.doc,
|
||||||
|
method: 'repost_accounting_entries',
|
||||||
|
freeze: true,
|
||||||
|
freeze_message: __('Reposting...'),
|
||||||
|
callback: (r) => {
|
||||||
|
if (!r.exc) {
|
||||||
|
frappe.msgprint(__('Accounting Entries are reposted'));
|
||||||
|
me.frm.refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}).removeClass('btn-default').addClass('btn-warning');
|
||||||
|
}
|
||||||
|
|
||||||
if (this.frm.doc.is_return) {
|
if (this.frm.doc.is_return) {
|
||||||
this.frm.return_print_format = "Sales Invoice Return";
|
this.frm.return_print_format = "Sales Invoice Return";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -209,6 +209,7 @@
|
|||||||
"is_internal_customer",
|
"is_internal_customer",
|
||||||
"is_discounted",
|
"is_discounted",
|
||||||
"remarks",
|
"remarks",
|
||||||
|
"repost_required",
|
||||||
"connections_tab"
|
"connections_tab"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
@@ -1038,6 +1039,7 @@
|
|||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_on_submit": 1,
|
||||||
"depends_on": "redeem_loyalty_points",
|
"depends_on": "redeem_loyalty_points",
|
||||||
"fieldname": "loyalty_redemption_account",
|
"fieldname": "loyalty_redemption_account",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
@@ -1336,6 +1338,7 @@
|
|||||||
"options": "fa fa-money"
|
"options": "fa fa-money"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_on_submit": 1,
|
||||||
"depends_on": "is_pos",
|
"depends_on": "is_pos",
|
||||||
"fieldname": "cash_bank_account",
|
"fieldname": "cash_bank_account",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
@@ -1435,6 +1438,7 @@
|
|||||||
"print_hide": 1
|
"print_hide": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_on_submit": 1,
|
||||||
"depends_on": "is_pos",
|
"depends_on": "is_pos",
|
||||||
"fieldname": "account_for_change_amount",
|
"fieldname": "account_for_change_amount",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
@@ -1483,6 +1487,7 @@
|
|||||||
"hide_seconds": 1
|
"hide_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_on_submit": 1,
|
||||||
"fieldname": "write_off_account",
|
"fieldname": "write_off_account",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hide_days": 1,
|
"hide_days": 1,
|
||||||
@@ -1706,6 +1711,7 @@
|
|||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_on_submit": 1,
|
||||||
"default": "No",
|
"default": "No",
|
||||||
"fieldname": "is_opening",
|
"fieldname": "is_opening",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
@@ -1922,6 +1928,7 @@
|
|||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_on_submit": 1,
|
||||||
"depends_on": "eval:doc.is_internal_customer",
|
"depends_on": "eval:doc.is_internal_customer",
|
||||||
"description": "Unrealized Profit / Loss account for intra-company transfers",
|
"description": "Unrealized Profit / Loss account for intra-company transfers",
|
||||||
"fieldname": "unrealized_profit_loss_account",
|
"fieldname": "unrealized_profit_loss_account",
|
||||||
@@ -1964,6 +1971,7 @@
|
|||||||
"label": "Disable Rounded Total"
|
"label": "Disable Rounded Total"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_on_submit": 1,
|
||||||
"fieldname": "additional_discount_account",
|
"fieldname": "additional_discount_account",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Discount Account",
|
"label": "Discount Account",
|
||||||
@@ -2114,6 +2122,15 @@
|
|||||||
"fieldname": "named_place",
|
"fieldname": "named_place",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Named Place"
|
"label": "Named Place"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "repost_required",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"hidden": 1,
|
||||||
|
"label": "Repost Required",
|
||||||
|
"no_copy": 1,
|
||||||
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-file-text",
|
"icon": "fa fa-file-text",
|
||||||
@@ -2126,7 +2143,7 @@
|
|||||||
"link_fieldname": "consolidated_invoice"
|
"link_fieldname": "consolidated_invoice"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"modified": "2023-01-28 19:45:47.538163",
|
"modified": "2022-11-07 16:02:07.972258",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Sales Invoice",
|
"name": "Sales Invoice",
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ from frappe.utils import add_days, cint, cstr, flt, formatdate, get_link_to_form
|
|||||||
|
|
||||||
import erpnext
|
import erpnext
|
||||||
from erpnext.accounts.deferred_revenue import validate_service_stop_date
|
from erpnext.accounts.deferred_revenue import validate_service_stop_date
|
||||||
|
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
|
||||||
|
get_accounting_dimensions,
|
||||||
|
)
|
||||||
from erpnext.accounts.doctype.loyalty_program.loyalty_program import (
|
from erpnext.accounts.doctype.loyalty_program.loyalty_program import (
|
||||||
get_loyalty_program_details_with_points,
|
get_loyalty_program_details_with_points,
|
||||||
validate_loyalty_points,
|
validate_loyalty_points,
|
||||||
@@ -100,13 +103,11 @@ class SalesInvoice(SellingController):
|
|||||||
self.validate_debit_to_acc()
|
self.validate_debit_to_acc()
|
||||||
self.clear_unallocated_advances("Sales Invoice Advance", "advances")
|
self.clear_unallocated_advances("Sales Invoice Advance", "advances")
|
||||||
self.add_remarks()
|
self.add_remarks()
|
||||||
self.validate_write_off_account()
|
|
||||||
self.validate_account_for_change_amount()
|
|
||||||
self.validate_fixed_asset()
|
self.validate_fixed_asset()
|
||||||
self.set_income_account_for_fixed_assets()
|
self.set_income_account_for_fixed_assets()
|
||||||
self.validate_item_cost_centers()
|
self.validate_item_cost_centers()
|
||||||
self.validate_income_account()
|
|
||||||
self.check_conversion_rate()
|
self.check_conversion_rate()
|
||||||
|
self.validate_accounts()
|
||||||
|
|
||||||
validate_inter_company_party(
|
validate_inter_company_party(
|
||||||
self.doctype, self.customer, self.company, self.inter_company_invoice_reference
|
self.doctype, self.customer, self.company, self.inter_company_invoice_reference
|
||||||
@@ -170,6 +171,11 @@ class SalesInvoice(SellingController):
|
|||||||
|
|
||||||
self.reset_default_field_value("set_warehouse", "items", "warehouse")
|
self.reset_default_field_value("set_warehouse", "items", "warehouse")
|
||||||
|
|
||||||
|
def validate_accounts(self):
|
||||||
|
self.validate_write_off_account()
|
||||||
|
self.validate_account_for_change_amount()
|
||||||
|
self.validate_income_account()
|
||||||
|
|
||||||
def validate_fixed_asset(self):
|
def validate_fixed_asset(self):
|
||||||
for d in self.get("items"):
|
for d in self.get("items"):
|
||||||
if d.is_fixed_asset and d.meta.get_field("asset") and d.asset:
|
if d.is_fixed_asset and d.meta.get_field("asset") and d.asset:
|
||||||
@@ -368,6 +374,7 @@ class SalesInvoice(SellingController):
|
|||||||
self.repost_future_sle_and_gle()
|
self.repost_future_sle_and_gle()
|
||||||
|
|
||||||
self.db_set("status", "Cancelled")
|
self.db_set("status", "Cancelled")
|
||||||
|
self.db_set("repost_required", 0)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
frappe.db.get_single_value("Selling Settings", "sales_update_frequency") == "Each Transaction"
|
frappe.db.get_single_value("Selling Settings", "sales_update_frequency") == "Each Transaction"
|
||||||
@@ -390,6 +397,8 @@ class SalesInvoice(SellingController):
|
|||||||
"GL Entry",
|
"GL Entry",
|
||||||
"Stock Ledger Entry",
|
"Stock Ledger Entry",
|
||||||
"Repost Item Valuation",
|
"Repost Item Valuation",
|
||||||
|
"Repost Payment Ledger",
|
||||||
|
"Repost Payment Ledger Items",
|
||||||
"Payment Ledger Entry",
|
"Payment Ledger Entry",
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -514,6 +523,92 @@ class SalesInvoice(SellingController):
|
|||||||
def on_update(self):
|
def on_update(self):
|
||||||
self.set_paid_amount()
|
self.set_paid_amount()
|
||||||
|
|
||||||
|
def on_update_after_submit(self):
|
||||||
|
if hasattr(self, "repost_required"):
|
||||||
|
needs_repost = 0
|
||||||
|
|
||||||
|
# Check if any field affecting accounting entry is altered
|
||||||
|
doc_before_update = self.get_doc_before_save()
|
||||||
|
accounting_dimensions = get_accounting_dimensions() + ["cost_center", "project"]
|
||||||
|
|
||||||
|
# Check if opening entry check updated
|
||||||
|
if doc_before_update.get("is_opening") != self.is_opening:
|
||||||
|
needs_repost = 1
|
||||||
|
|
||||||
|
if not needs_repost:
|
||||||
|
# Parent Level Accounts excluding party account
|
||||||
|
for field in (
|
||||||
|
"additional_discount_account",
|
||||||
|
"cash_bank_account",
|
||||||
|
"account_for_change_amount",
|
||||||
|
"write_off_account",
|
||||||
|
"loyalty_redemption_account",
|
||||||
|
"unrealized_profit_loss_account",
|
||||||
|
):
|
||||||
|
if doc_before_update.get(field) != self.get(field):
|
||||||
|
needs_repost = 1
|
||||||
|
break
|
||||||
|
|
||||||
|
# Check for parent accounting dimensions
|
||||||
|
for dimension in accounting_dimensions:
|
||||||
|
if doc_before_update.get(dimension) != self.get(dimension):
|
||||||
|
needs_repost = 1
|
||||||
|
break
|
||||||
|
|
||||||
|
# Check for child tables
|
||||||
|
if self.check_if_child_table_updated(
|
||||||
|
"items",
|
||||||
|
doc_before_update,
|
||||||
|
("income_account", "expense_account", "discount_account"),
|
||||||
|
accounting_dimensions,
|
||||||
|
):
|
||||||
|
needs_repost = 1
|
||||||
|
|
||||||
|
if self.check_if_child_table_updated(
|
||||||
|
"taxes", doc_before_update, ("account_head",), accounting_dimensions
|
||||||
|
):
|
||||||
|
needs_repost = 1
|
||||||
|
|
||||||
|
self.validate_accounts()
|
||||||
|
|
||||||
|
# validate if deferred revenue is enabled for any item
|
||||||
|
# Don't allow to update the invoice if deferred revenue is enabled
|
||||||
|
for item in self.get("items"):
|
||||||
|
if item.enable_deferred_revenue:
|
||||||
|
frappe.throw(
|
||||||
|
_(
|
||||||
|
"Deferred Revenue is enabled for item {0}. You cannot update the invoice after submission."
|
||||||
|
).format(item.item_code)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.db_set("repost_required", needs_repost)
|
||||||
|
|
||||||
|
def check_if_child_table_updated(
|
||||||
|
self, child_table, doc_before_update, fields_to_check, accounting_dimensions
|
||||||
|
):
|
||||||
|
# Check if any field affecting accounting entry is altered
|
||||||
|
for index, item in enumerate(self.get(child_table)):
|
||||||
|
for field in fields_to_check:
|
||||||
|
if doc_before_update.get(child_table)[index].get(field) != item.get(field):
|
||||||
|
return True
|
||||||
|
|
||||||
|
for dimension in accounting_dimensions:
|
||||||
|
if doc_before_update.get(child_table)[index].get(dimension) != item.get(dimension):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def repost_accounting_entries(self):
|
||||||
|
if self.repost_required:
|
||||||
|
self.docstatus = 2
|
||||||
|
self.make_gl_entries_on_cancel()
|
||||||
|
self.docstatus = 1
|
||||||
|
self.make_gl_entries()
|
||||||
|
self.db_set("repost_required", 0)
|
||||||
|
else:
|
||||||
|
frappe.throw(_("No updates pending for reposting"))
|
||||||
|
|
||||||
def set_paid_amount(self):
|
def set_paid_amount(self):
|
||||||
paid_amount = 0.0
|
paid_amount = 0.0
|
||||||
base_paid_amount = 0.0
|
base_paid_amount = 0.0
|
||||||
|
|||||||
@@ -2769,6 +2769,31 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
|
|
||||||
check_gl_entries(self, si.name, expected_gle, add_days(nowdate(), -1))
|
check_gl_entries(self, si.name, expected_gle, add_days(nowdate(), -1))
|
||||||
|
|
||||||
|
# Update Invoice post submit and then check GL Entries again
|
||||||
|
|
||||||
|
si.load_from_db()
|
||||||
|
si.items[0].income_account = "Service - _TC"
|
||||||
|
si.additional_discount_account = "_Test Account Sales - _TC"
|
||||||
|
si.taxes[0].account_head = "TDS Payable - _TC"
|
||||||
|
si.save()
|
||||||
|
|
||||||
|
si.load_from_db()
|
||||||
|
self.assertTrue(si.repost_required)
|
||||||
|
|
||||||
|
si.repost_accounting_entries()
|
||||||
|
|
||||||
|
expected_gle = [
|
||||||
|
["_Test Account Sales - _TC", 22.0, 0.0, nowdate()],
|
||||||
|
["Debtors - _TC", 88, 0.0, nowdate()],
|
||||||
|
["Service - _TC", 0.0, 100.0, nowdate()],
|
||||||
|
["TDS Payable - _TC", 0.0, 10.0, nowdate()],
|
||||||
|
]
|
||||||
|
|
||||||
|
check_gl_entries(self, si.name, expected_gle, add_days(nowdate(), -1))
|
||||||
|
|
||||||
|
si.load_from_db()
|
||||||
|
self.assertFalse(si.repost_required)
|
||||||
|
|
||||||
def test_asset_depreciation_on_sale_with_pro_rata(self):
|
def test_asset_depreciation_on_sale_with_pro_rata(self):
|
||||||
"""
|
"""
|
||||||
Tests if an Asset set to depreciate yearly on June 30, that gets sold on Sept 30, creates an additional depreciation entry on its date of sale.
|
Tests if an Asset set to depreciate yearly on June 30, that gets sold on Sept 30, creates an additional depreciation entry on its date of sale.
|
||||||
@@ -3326,6 +3351,7 @@ def check_gl_entries(doc, voucher_no, expected_gle, posting_date):
|
|||||||
"""select account, debit, credit, posting_date
|
"""select account, debit, credit, posting_date
|
||||||
from `tabGL Entry`
|
from `tabGL Entry`
|
||||||
where voucher_type='Sales Invoice' and voucher_no=%s and posting_date > %s
|
where voucher_type='Sales Invoice' and voucher_no=%s and posting_date > %s
|
||||||
|
and is_cancelled = 0
|
||||||
order by posting_date asc, account asc""",
|
order by posting_date asc, account asc""",
|
||||||
(voucher_no, posting_date),
|
(voucher_no, posting_date),
|
||||||
as_dict=1,
|
as_dict=1,
|
||||||
|
|||||||
@@ -438,6 +438,7 @@
|
|||||||
"label": "Accounting Details"
|
"label": "Accounting Details"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_on_submit": 1,
|
||||||
"fieldname": "income_account",
|
"fieldname": "income_account",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Income Account",
|
"label": "Income Account",
|
||||||
@@ -450,6 +451,7 @@
|
|||||||
"width": "120px"
|
"width": "120px"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_on_submit": 1,
|
||||||
"fieldname": "expense_account",
|
"fieldname": "expense_account",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Expense Account",
|
"label": "Expense Account",
|
||||||
@@ -469,6 +471,7 @@
|
|||||||
"print_hide": 1
|
"print_hide": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_on_submit": 1,
|
||||||
"default": ":Company",
|
"default": ":Company",
|
||||||
"fieldname": "cost_center",
|
"fieldname": "cost_center",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
@@ -800,6 +803,7 @@
|
|||||||
"options": "Finance Book"
|
"options": "Finance Book"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_on_submit": 1,
|
||||||
"fieldname": "project",
|
"fieldname": "project",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Project",
|
"label": "Project",
|
||||||
@@ -822,7 +826,6 @@
|
|||||||
"label": "Incoming Rate (Costing)",
|
"label": "Incoming Rate (Costing)",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "Company:company:default_currency",
|
"options": "Company:company:default_currency",
|
||||||
"precision": "6",
|
|
||||||
"print_hide": 1
|
"print_hide": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -835,6 +838,7 @@
|
|||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_on_submit": 1,
|
||||||
"fieldname": "discount_account",
|
"fieldname": "discount_account",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Discount Account",
|
"label": "Discount Account",
|
||||||
@@ -886,7 +890,7 @@
|
|||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-12-28 16:17:33.484531",
|
"modified": "2022-10-17 12:51:44.825398",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Sales Invoice Item",
|
"name": "Sales Invoice Item",
|
||||||
|
|||||||
@@ -51,6 +51,7 @@
|
|||||||
"oldfieldtype": "Data"
|
"oldfieldtype": "Data"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_on_submit": 1,
|
||||||
"columns": 2,
|
"columns": 2,
|
||||||
"fieldname": "account_head",
|
"fieldname": "account_head",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
@@ -63,6 +64,7 @@
|
|||||||
"search_index": 1
|
"search_index": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_on_submit": 1,
|
||||||
"default": ":Company",
|
"default": ":Company",
|
||||||
"fieldname": "cost_center",
|
"fieldname": "cost_center",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
@@ -216,12 +218,13 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-08-05 20:04:01.726867",
|
"modified": "2022-10-17 13:08:17.776528",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Sales Taxes and Charges",
|
"name": "Sales Taxes and Charges",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [],
|
"permissions": [],
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "ASC"
|
"sort_order": "ASC",
|
||||||
|
"states": []
|
||||||
}
|
}
|
||||||
@@ -278,7 +278,7 @@ def get_tax_amount(party_type, parties, inv, tax_details, posting_date, pan_no=N
|
|||||||
tax_amount = get_tcs_amount(parties, inv, tax_details, vouchers, advance_vouchers)
|
tax_amount = get_tcs_amount(parties, inv, tax_details, vouchers, advance_vouchers)
|
||||||
|
|
||||||
if cint(tax_details.round_off_tax_amount):
|
if cint(tax_details.round_off_tax_amount):
|
||||||
tax_amount = round(tax_amount)
|
tax_amount = normal_round(tax_amount)
|
||||||
|
|
||||||
return tax_amount, tax_deducted, tax_deducted_on_advances, voucher_wise_amount
|
return tax_amount, tax_deducted, tax_deducted_on_advances, voucher_wise_amount
|
||||||
|
|
||||||
@@ -603,3 +603,20 @@ def is_valid_certificate(
|
|||||||
valid = True
|
valid = True
|
||||||
|
|
||||||
return valid
|
return valid
|
||||||
|
|
||||||
|
|
||||||
|
def normal_round(number):
|
||||||
|
"""
|
||||||
|
Rounds a number to the nearest integer.
|
||||||
|
:param number: The number to round.
|
||||||
|
"""
|
||||||
|
decimal_part = number - int(number)
|
||||||
|
|
||||||
|
if decimal_part >= 0.5:
|
||||||
|
decimal_part = 1
|
||||||
|
else:
|
||||||
|
decimal_part = 0
|
||||||
|
|
||||||
|
number = int(number) + decimal_part
|
||||||
|
|
||||||
|
return number
|
||||||
|
|||||||
@@ -250,7 +250,7 @@ frappe.ui.form.on('Asset', {
|
|||||||
$.each(depr_entries || [], function(i, v) {
|
$.each(depr_entries || [], function(i, v) {
|
||||||
x_intervals.push(frappe.format(v.posting_date, { fieldtype: 'Date' }));
|
x_intervals.push(frappe.format(v.posting_date, { fieldtype: 'Date' }));
|
||||||
let last_asset_value = asset_values[asset_values.length - 1]
|
let last_asset_value = asset_values[asset_values.length - 1]
|
||||||
asset_values.push(last_asset_value - v.value);
|
asset_values.push(flt(last_asset_value - v.value, precision('gross_purchase_amount')));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -677,11 +677,15 @@ class Asset(AccountsController):
|
|||||||
|
|
||||||
if self.journal_entry_for_scrap:
|
if self.journal_entry_for_scrap:
|
||||||
status = "Scrapped"
|
status = "Scrapped"
|
||||||
elif self.finance_books:
|
else:
|
||||||
idx = self.get_default_finance_book_idx() or 0
|
expected_value_after_useful_life = 0
|
||||||
|
value_after_depreciation = self.value_after_depreciation
|
||||||
|
|
||||||
expected_value_after_useful_life = self.finance_books[idx].expected_value_after_useful_life
|
if self.calculate_depreciation:
|
||||||
value_after_depreciation = self.finance_books[idx].value_after_depreciation
|
idx = self.get_default_finance_book_idx() or 0
|
||||||
|
|
||||||
|
expected_value_after_useful_life = self.finance_books[idx].expected_value_after_useful_life
|
||||||
|
value_after_depreciation = self.finance_books[idx].value_after_depreciation
|
||||||
|
|
||||||
if flt(value_after_depreciation) <= expected_value_after_useful_life:
|
if flt(value_after_depreciation) <= expected_value_after_useful_life:
|
||||||
status = "Fully Depreciated"
|
status = "Fully Depreciated"
|
||||||
@@ -843,6 +847,7 @@ class Asset(AccountsController):
|
|||||||
.where(gle.debit != 0)
|
.where(gle.debit != 0)
|
||||||
.where(gle.is_cancelled == 0)
|
.where(gle.is_cancelled == 0)
|
||||||
.orderby(gle.posting_date)
|
.orderby(gle.posting_date)
|
||||||
|
.orderby(gle.creation)
|
||||||
).run(as_dict=True)
|
).run(as_dict=True)
|
||||||
|
|
||||||
return records
|
return records
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ def make_depreciation_entry(asset_name, date=None):
|
|||||||
finance_books.value_after_depreciation -= d.depreciation_amount
|
finance_books.value_after_depreciation -= d.depreciation_amount
|
||||||
finance_books.db_update()
|
finance_books.db_update()
|
||||||
|
|
||||||
frappe.db.set_value("Asset", asset_name, "depr_entry_posting_status", "Successful")
|
asset.db_set("depr_entry_posting_status", "Successful")
|
||||||
|
|
||||||
asset.set_status()
|
asset.set_status()
|
||||||
|
|
||||||
|
|||||||
@@ -77,6 +77,9 @@ class AssetRepair(AccountsController):
|
|||||||
self.asset_doc.prepare_depreciation_data()
|
self.asset_doc.prepare_depreciation_data()
|
||||||
self.asset_doc.save()
|
self.asset_doc.save()
|
||||||
|
|
||||||
|
def after_delete(self):
|
||||||
|
frappe.get_doc("Asset", self.asset).set_status()
|
||||||
|
|
||||||
def check_repair_status(self):
|
def check_repair_status(self):
|
||||||
if self.repair_status == "Pending":
|
if self.repair_status == "Pending":
|
||||||
frappe.throw(_("Please update Repair Status."))
|
frappe.throw(_("Please update Repair Status."))
|
||||||
|
|||||||
@@ -151,6 +151,7 @@ def prepare_chart_data(data, filters):
|
|||||||
filters.filter_based_on,
|
filters.filter_based_on,
|
||||||
"Monthly",
|
"Monthly",
|
||||||
company=filters.company,
|
company=filters.company,
|
||||||
|
ignore_fiscal_year=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
for d in period_list:
|
for d in period_list:
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
"allow_multiple_items",
|
"allow_multiple_items",
|
||||||
"bill_for_rejected_quantity_in_purchase_invoice",
|
"bill_for_rejected_quantity_in_purchase_invoice",
|
||||||
"disable_last_purchase_rate",
|
"disable_last_purchase_rate",
|
||||||
|
"show_pay_button",
|
||||||
"subcontract",
|
"subcontract",
|
||||||
"backflush_raw_materials_of_subcontract_based_on",
|
"backflush_raw_materials_of_subcontract_based_on",
|
||||||
"column_break_11",
|
"column_break_11",
|
||||||
@@ -140,6 +141,12 @@
|
|||||||
"fieldname": "disable_last_purchase_rate",
|
"fieldname": "disable_last_purchase_rate",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Disable Last Purchase Rate"
|
"label": "Disable Last Purchase Rate"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "1",
|
||||||
|
"fieldname": "show_pay_button",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Show Pay Button in Purchase Order Portal"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-cog",
|
"icon": "fa fa-cog",
|
||||||
@@ -147,7 +154,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-01-09 17:08:28.828173",
|
"modified": "2023-02-15 14:42:10.200679",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Buying Settings",
|
"name": "Buying Settings",
|
||||||
|
|||||||
@@ -124,12 +124,11 @@ frappe.ui.form.on("Request for Quotation",{
|
|||||||
frappe.urllib.get_full_url(
|
frappe.urllib.get_full_url(
|
||||||
"/api/method/erpnext.buying.doctype.request_for_quotation.request_for_quotation.get_pdf?" +
|
"/api/method/erpnext.buying.doctype.request_for_quotation.request_for_quotation.get_pdf?" +
|
||||||
new URLSearchParams({
|
new URLSearchParams({
|
||||||
doctype: frm.doc.doctype,
|
|
||||||
name: frm.doc.name,
|
name: frm.doc.name,
|
||||||
supplier: data.supplier,
|
supplier: data.supplier,
|
||||||
print_format: data.print_format || "Standard",
|
print_format: data.print_format || "Standard",
|
||||||
language: data.language || frappe.boot.lang,
|
language: data.language || frappe.boot.lang,
|
||||||
letter_head: data.letter_head || frm.doc.letter_head || "",
|
letterhead: data.letter_head || frm.doc.letter_head || "",
|
||||||
}).toString()
|
}).toString()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
@@ -388,24 +389,26 @@ def create_rfq_items(sq_doc, supplier, data):
|
|||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_pdf(doctype, name, supplier, print_format=None, language=None, letter_head=None):
|
def get_pdf(
|
||||||
# permissions get checked in `download_pdf`
|
name: str,
|
||||||
if doc := get_rfq_doc(doctype, name, supplier):
|
supplier: str,
|
||||||
download_pdf(
|
print_format: Optional[str] = None,
|
||||||
doctype,
|
language: Optional[str] = None,
|
||||||
name,
|
letterhead: Optional[str] = None,
|
||||||
print_format,
|
):
|
||||||
doc=doc,
|
doc = frappe.get_doc("Request for Quotation", name)
|
||||||
language=language,
|
|
||||||
letter_head=letter_head or None,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def get_rfq_doc(doctype, name, supplier):
|
|
||||||
if supplier:
|
if supplier:
|
||||||
doc = frappe.get_doc(doctype, name)
|
|
||||||
doc.update_supplier_part_no(supplier)
|
doc.update_supplier_part_no(supplier)
|
||||||
return doc
|
|
||||||
|
# permissions get checked in `download_pdf`
|
||||||
|
download_pdf(
|
||||||
|
doc.doctype,
|
||||||
|
doc.name,
|
||||||
|
print_format,
|
||||||
|
doc=doc,
|
||||||
|
language=language,
|
||||||
|
letterhead=letterhead or None,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ from frappe.utils import nowdate
|
|||||||
|
|
||||||
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import (
|
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import (
|
||||||
create_supplier_quotation,
|
create_supplier_quotation,
|
||||||
|
get_pdf,
|
||||||
make_supplier_quotation_from_rfq,
|
make_supplier_quotation_from_rfq,
|
||||||
)
|
)
|
||||||
from erpnext.crm.doctype.opportunity.opportunity import make_request_for_quotation as make_rfq
|
from erpnext.crm.doctype.opportunity.opportunity import make_request_for_quotation as make_rfq
|
||||||
@@ -124,6 +125,11 @@ class TestRequestforQuotation(FrappeTestCase):
|
|||||||
rfq.status = "Draft"
|
rfq.status = "Draft"
|
||||||
rfq.submit()
|
rfq.submit()
|
||||||
|
|
||||||
|
def test_get_pdf(self):
|
||||||
|
rfq = make_request_for_quotation()
|
||||||
|
get_pdf(rfq.name, rfq.get("suppliers")[0].supplier)
|
||||||
|
self.assertEqual(frappe.local.response.type, "pdf")
|
||||||
|
|
||||||
|
|
||||||
def make_request_for_quotation(**args):
|
def make_request_for_quotation(**args):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -204,6 +204,12 @@ class AccountsController(TransactionBase):
|
|||||||
validate_einvoice_fields(self)
|
validate_einvoice_fields(self)
|
||||||
|
|
||||||
def on_trash(self):
|
def on_trash(self):
|
||||||
|
# delete references in 'Repost Payment Ledger'
|
||||||
|
rpi = frappe.qb.DocType("Repost Payment Ledger Items")
|
||||||
|
frappe.qb.from_(rpi).delete().where(
|
||||||
|
(rpi.voucher_type == self.doctype) & (rpi.voucher_no == self.name)
|
||||||
|
).run()
|
||||||
|
|
||||||
# delete sl and gl entries on deletion of transaction
|
# delete sl and gl entries on deletion of transaction
|
||||||
if frappe.db.get_single_value("Accounts Settings", "delete_linked_ledger_entries"):
|
if frappe.db.get_single_value("Accounts Settings", "delete_linked_ledger_entries"):
|
||||||
ple = frappe.qb.DocType("Payment Ledger Entry")
|
ple = frappe.qb.DocType("Payment Ledger Entry")
|
||||||
|
|||||||
@@ -409,7 +409,14 @@ class SubcontractingController(StockController):
|
|||||||
if self.available_materials.get(key) and self.available_materials[key]["batch_no"]:
|
if self.available_materials.get(key) and self.available_materials[key]["batch_no"]:
|
||||||
new_rm_obj = None
|
new_rm_obj = None
|
||||||
for batch_no, batch_qty in self.available_materials[key]["batch_no"].items():
|
for batch_no, batch_qty in self.available_materials[key]["batch_no"].items():
|
||||||
if batch_qty >= qty:
|
if batch_qty >= qty or (
|
||||||
|
rm_obj.consumed_qty == 0
|
||||||
|
and self.backflush_based_on == "BOM"
|
||||||
|
and len(self.available_materials[key]["batch_no"]) == 1
|
||||||
|
):
|
||||||
|
if rm_obj.consumed_qty == 0:
|
||||||
|
self.__set_consumed_qty(rm_obj, qty)
|
||||||
|
|
||||||
self.__set_batch_no_as_per_qty(item_row, rm_obj, batch_no, qty)
|
self.__set_batch_no_as_per_qty(item_row, rm_obj, batch_no, qty)
|
||||||
self.available_materials[key]["batch_no"][batch_no] -= qty
|
self.available_materials[key]["batch_no"][batch_no] -= qty
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -26,10 +26,11 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-02-08 12:51:48.971517",
|
"modified": "2023-02-10 00:51:44.973957",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "CRM",
|
"module": "CRM",
|
||||||
"name": "Lead Source",
|
"name": "Lead Source",
|
||||||
|
"naming_rule": "By fieldname",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
@@ -58,5 +59,7 @@
|
|||||||
],
|
],
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC"
|
"sort_order": "DESC",
|
||||||
|
"states": [],
|
||||||
|
"translated_doctype": 1
|
||||||
}
|
}
|
||||||
@@ -18,10 +18,11 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-05-20 12:22:01.866472",
|
"modified": "2023-02-10 01:40:23.713390",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "CRM",
|
"module": "CRM",
|
||||||
"name": "Sales Stage",
|
"name": "Sales Stage",
|
||||||
|
"naming_rule": "By fieldname",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
@@ -40,5 +41,7 @@
|
|||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"track_changes": 1
|
"states": [],
|
||||||
|
"track_changes": 1,
|
||||||
|
"translated_doctype": 1
|
||||||
}
|
}
|
||||||
@@ -306,7 +306,6 @@ erpnext.patches.v13_0.set_per_billed_in_return_delivery_note
|
|||||||
execute:frappe.delete_doc("DocType", "Naming Series")
|
execute:frappe.delete_doc("DocType", "Naming Series")
|
||||||
erpnext.patches.v13_0.job_card_status_on_hold
|
erpnext.patches.v13_0.job_card_status_on_hold
|
||||||
erpnext.patches.v14_0.copy_is_subcontracted_value_to_is_old_subcontracting_flow
|
erpnext.patches.v14_0.copy_is_subcontracted_value_to_is_old_subcontracting_flow
|
||||||
erpnext.patches.v14_0.migrate_gl_to_payment_ledger
|
|
||||||
erpnext.patches.v14_0.crm_ux_cleanup
|
erpnext.patches.v14_0.crm_ux_cleanup
|
||||||
erpnext.patches.v14_0.migrate_existing_lead_notes_as_per_the_new_format
|
erpnext.patches.v14_0.migrate_existing_lead_notes_as_per_the_new_format
|
||||||
erpnext.patches.v14_0.remove_india_localisation # 14-07-2022
|
erpnext.patches.v14_0.remove_india_localisation # 14-07-2022
|
||||||
@@ -315,10 +314,9 @@ erpnext.patches.v14_0.remove_hr_and_payroll_modules # 20-07-2022
|
|||||||
erpnext.patches.v14_0.fix_crm_no_of_employees
|
erpnext.patches.v14_0.fix_crm_no_of_employees
|
||||||
erpnext.patches.v14_0.create_accounting_dimensions_in_subcontracting_doctypes
|
erpnext.patches.v14_0.create_accounting_dimensions_in_subcontracting_doctypes
|
||||||
erpnext.patches.v14_0.fix_subcontracting_receipt_gl_entries
|
erpnext.patches.v14_0.fix_subcontracting_receipt_gl_entries
|
||||||
erpnext.patches.v14_0.migrate_remarks_from_gl_to_payment_ledger
|
erpnext.patches.v13_0.update_schedule_type_in_loans
|
||||||
erpnext.patches.v13_0.drop_unused_sle_index_parts
|
erpnext.patches.v13_0.drop_unused_sle_index_parts
|
||||||
erpnext.patches.v14_0.create_accounting_dimensions_for_asset_capitalization
|
erpnext.patches.v14_0.create_accounting_dimensions_for_asset_capitalization
|
||||||
erpnext.patches.v13_0.update_schedule_type_in_loans
|
|
||||||
erpnext.patches.v14_0.update_partial_tds_fields
|
erpnext.patches.v14_0.update_partial_tds_fields
|
||||||
erpnext.patches.v14_0.create_incoterms_and_migrate_shipment
|
erpnext.patches.v14_0.create_incoterms_and_migrate_shipment
|
||||||
erpnext.patches.v14_0.setup_clear_repost_logs
|
erpnext.patches.v14_0.setup_clear_repost_logs
|
||||||
@@ -326,4 +324,7 @@ erpnext.patches.v14_0.create_accounting_dimensions_for_payment_request
|
|||||||
erpnext.patches.v14_0.update_entry_type_for_journal_entry
|
erpnext.patches.v14_0.update_entry_type_for_journal_entry
|
||||||
erpnext.patches.v14_0.change_autoname_for_tax_withheld_vouchers
|
erpnext.patches.v14_0.change_autoname_for_tax_withheld_vouchers
|
||||||
erpnext.patches.v14_0.update_asset_value_for_manual_depr_entries
|
erpnext.patches.v14_0.update_asset_value_for_manual_depr_entries
|
||||||
erpnext.patches.v14_0.set_pick_list_status
|
erpnext.patches.v14_0.set_pick_list_status
|
||||||
|
# below 2 migration patches should always run last
|
||||||
|
erpnext.patches.v14_0.migrate_gl_to_payment_ledger
|
||||||
|
erpnext.patches.v14_0.migrate_remarks_from_gl_to_payment_ledger
|
||||||
|
|||||||
@@ -1,16 +1,17 @@
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
|
||||||
|
|
||||||
|
|
||||||
def execute():
|
def execute():
|
||||||
from erpnext.setup.setup_wizard.operations.install_fixtures import default_sales_partner_type
|
from erpnext.setup.setup_wizard.operations.install_fixtures import read_lines
|
||||||
|
|
||||||
frappe.reload_doc("selling", "doctype", "sales_partner_type")
|
frappe.reload_doc("selling", "doctype", "sales_partner_type")
|
||||||
|
|
||||||
frappe.local.lang = frappe.db.get_default("lang") or "en"
|
frappe.local.lang = frappe.db.get_default("lang") or "en"
|
||||||
|
|
||||||
|
default_sales_partner_type = read_lines("sales_partner_type.txt")
|
||||||
|
|
||||||
for s in default_sales_partner_type:
|
for s in default_sales_partner_type:
|
||||||
insert_sales_partner_type(_(s))
|
insert_sales_partner_type(s)
|
||||||
|
|
||||||
# get partner type in existing forms (customized)
|
# get partner type in existing forms (customized)
|
||||||
# and create a document if not created
|
# and create a document if not created
|
||||||
|
|||||||
@@ -17,10 +17,11 @@ def execute():
|
|||||||
|
|
||||||
for report in reports_to_delete:
|
for report in reports_to_delete:
|
||||||
if frappe.db.exists("Report", report):
|
if frappe.db.exists("Report", report):
|
||||||
|
delete_links_from_desktop_icons(report)
|
||||||
delete_auto_email_reports(report)
|
delete_auto_email_reports(report)
|
||||||
check_and_delete_linked_reports(report)
|
check_and_delete_linked_reports(report)
|
||||||
|
|
||||||
frappe.delete_doc("Report", report)
|
frappe.delete_doc("Report", report, force=True)
|
||||||
|
|
||||||
|
|
||||||
def delete_auto_email_reports(report):
|
def delete_auto_email_reports(report):
|
||||||
@@ -28,3 +29,10 @@ def delete_auto_email_reports(report):
|
|||||||
auto_email_reports = frappe.db.get_values("Auto Email Report", {"report": report}, ["name"])
|
auto_email_reports = frappe.db.get_values("Auto Email Report", {"report": report}, ["name"])
|
||||||
for auto_email_report in auto_email_reports:
|
for auto_email_report in auto_email_reports:
|
||||||
frappe.delete_doc("Auto Email Report", auto_email_report[0])
|
frappe.delete_doc("Auto Email Report", auto_email_report[0])
|
||||||
|
|
||||||
|
|
||||||
|
def delete_links_from_desktop_icons(report):
|
||||||
|
"""Check for one or multiple Desktop Icons and delete"""
|
||||||
|
desktop_icons = frappe.db.get_values("Desktop Icon", {"_report": report}, ["name"])
|
||||||
|
for desktop_icon in desktop_icons:
|
||||||
|
frappe.delete_doc("Desktop Icon", desktop_icon[0], force=True)
|
||||||
|
|||||||
@@ -408,7 +408,7 @@
|
|||||||
"depends_on": "eval:(doc.frequency == \"Daily\" && doc.collect_progress == true)",
|
"depends_on": "eval:(doc.frequency == \"Daily\" && doc.collect_progress == true)",
|
||||||
"fieldname": "daily_time_to_send",
|
"fieldname": "daily_time_to_send",
|
||||||
"fieldtype": "Time",
|
"fieldtype": "Time",
|
||||||
"label": "Time to send"
|
"label": "Daily Time to send"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:(doc.frequency == \"Weekly\" && doc.collect_progress == true)",
|
"depends_on": "eval:(doc.frequency == \"Weekly\" && doc.collect_progress == true)",
|
||||||
@@ -421,7 +421,7 @@
|
|||||||
"depends_on": "eval:(doc.frequency == \"Weekly\" && doc.collect_progress == true)",
|
"depends_on": "eval:(doc.frequency == \"Weekly\" && doc.collect_progress == true)",
|
||||||
"fieldname": "weekly_time_to_send",
|
"fieldname": "weekly_time_to_send",
|
||||||
"fieldtype": "Time",
|
"fieldtype": "Time",
|
||||||
"label": "Time to send"
|
"label": "Weekly Time to send"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_45",
|
"fieldname": "column_break_45",
|
||||||
@@ -451,7 +451,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"max_attachments": 4,
|
"max_attachments": 4,
|
||||||
"modified": "2022-06-23 16:45:06.108499",
|
"modified": "2023-02-14 04:54:25.819620",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Projects",
|
"module": "Projects",
|
||||||
"name": "Project",
|
"name": "Project",
|
||||||
@@ -497,4 +497,4 @@
|
|||||||
"timeline_field": "customer",
|
"timeline_field": "customer",
|
||||||
"title_field": "project_name",
|
"title_field": "project_name",
|
||||||
"track_seen": 1
|
"track_seen": 1
|
||||||
}
|
}
|
||||||
@@ -282,21 +282,21 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "base_total_costing_amount",
|
"fieldname": "base_total_costing_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Total Costing Amount",
|
"label": "Base Total Costing Amount",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "base_total_billable_amount",
|
"fieldname": "base_total_billable_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Total Billable Amount",
|
"label": "Base Total Billable Amount",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "base_total_billed_amount",
|
"fieldname": "base_total_billed_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Total Billed Amount",
|
"label": "Base Total Billed Amount",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
@@ -311,10 +311,11 @@
|
|||||||
"idx": 1,
|
"idx": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-06-15 22:08:53.930200",
|
"modified": "2023-02-14 04:55:41.735991",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Projects",
|
"module": "Projects",
|
||||||
"name": "Timesheet",
|
"name": "Timesheet",
|
||||||
|
"naming_rule": "By \"Naming Series\" field",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
@@ -388,5 +389,6 @@
|
|||||||
],
|
],
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "ASC",
|
"sort_order": "ASC",
|
||||||
|
"states": [],
|
||||||
"title_field": "title"
|
"title_field": "title"
|
||||||
}
|
}
|
||||||
@@ -143,6 +143,12 @@ var get_payment_mode_account = function(frm, mode_of_payment, callback) {
|
|||||||
|
|
||||||
cur_frm.cscript.account_head = function(doc, cdt, cdn) {
|
cur_frm.cscript.account_head = function(doc, cdt, cdn) {
|
||||||
var d = locals[cdt][cdn];
|
var d = locals[cdt][cdn];
|
||||||
|
|
||||||
|
if (doc.docstatus == 1) {
|
||||||
|
// Should not trigger any changes on change post submit
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(!d.charge_type && d.account_head){
|
if(!d.charge_type && d.account_head){
|
||||||
frappe.msgprint(__("Please select Charge Type first"));
|
frappe.msgprint(__("Please select Charge Type first"));
|
||||||
frappe.model.set_value(cdt, cdn, "account_head", "");
|
frappe.model.set_value(cdt, cdn, "account_head", "");
|
||||||
|
|||||||
@@ -221,9 +221,9 @@ $.extend(erpnext.utils, {
|
|||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
if (r.message && r.message.length) {
|
if (r.message && r.message.length) {
|
||||||
r.message.forEach((dimension) => {
|
r.message.forEach((dimension) => {
|
||||||
let found = filters.some(el => el.fieldname === dimension['fieldname']);
|
let existing_filter = filters.filter(el => el.fieldname === dimension['fieldname']);
|
||||||
|
|
||||||
if (!found) {
|
if (!existing_filter.length) {
|
||||||
filters.splice(index, 0, {
|
filters.splice(index, 0, {
|
||||||
"fieldname": dimension["fieldname"],
|
"fieldname": dimension["fieldname"],
|
||||||
"label": __(dimension["doctype"]),
|
"label": __(dimension["doctype"]),
|
||||||
@@ -232,6 +232,11 @@ $.extend(erpnext.utils, {
|
|||||||
return frappe.db.get_link_options(dimension["doctype"], txt);
|
return frappe.db.get_link_options(dimension["doctype"], txt);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
existing_filter[0]['fieldtype'] = "MultiSelectList";
|
||||||
|
existing_filter[0]['get_data'] = function(txt) {
|
||||||
|
return frappe.db.get_link_options(dimension["doctype"], txt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,123 +1,68 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"actions": [],
|
||||||
"allow_import": 1,
|
"allow_import": 1,
|
||||||
"allow_rename": 1,
|
"allow_rename": 1,
|
||||||
"autoname": "field:industry",
|
"autoname": "field:industry",
|
||||||
"beta": 0,
|
"creation": "2012-03-27 14:36:09",
|
||||||
"creation": "2012-03-27 14:36:09",
|
"doctype": "DocType",
|
||||||
"custom": 0,
|
"document_type": "Setup",
|
||||||
"docstatus": 0,
|
"engine": "InnoDB",
|
||||||
"doctype": "DocType",
|
"field_order": [
|
||||||
"document_type": "Setup",
|
"industry"
|
||||||
"editable_grid": 0,
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
"fieldname": "industry",
|
||||||
"bold": 0,
|
"fieldtype": "Data",
|
||||||
"collapsible": 0,
|
"in_list_view": 1,
|
||||||
"fieldname": "industry",
|
"label": "Industry",
|
||||||
"fieldtype": "Data",
|
"oldfieldname": "industry",
|
||||||
"hidden": 0,
|
"oldfieldtype": "Data",
|
||||||
"ignore_user_permissions": 0,
|
"reqd": 1,
|
||||||
"ignore_xss_filter": 0,
|
"unique": 1
|
||||||
"in_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"label": "Industry",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"oldfieldname": "industry",
|
|
||||||
"oldfieldtype": "Data",
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"hide_heading": 0,
|
"icon": "fa fa-flag",
|
||||||
"hide_toolbar": 0,
|
"idx": 1,
|
||||||
"icon": "fa fa-flag",
|
"links": [],
|
||||||
"idx": 1,
|
"modified": "2023-02-10 03:14:40.735763",
|
||||||
"image_view": 0,
|
"modified_by": "Administrator",
|
||||||
"in_create": 0,
|
"module": "Selling",
|
||||||
|
"name": "Industry Type",
|
||||||
"is_submittable": 0,
|
"naming_rule": "By fieldname",
|
||||||
"issingle": 0,
|
"owner": "Administrator",
|
||||||
"istable": 0,
|
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2020-09-18 17:26:09.703215",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "Selling",
|
|
||||||
"name": "Industry Type",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"create": 1,
|
||||||
"apply_user_permissions": 0,
|
"email": 1,
|
||||||
"cancel": 0,
|
"print": 1,
|
||||||
"create": 1,
|
"read": 1,
|
||||||
"delete": 0,
|
"report": 1,
|
||||||
"email": 1,
|
"role": "Sales Manager",
|
||||||
"export": 0,
|
"share": 1,
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "Sales Manager",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"email": 1,
|
||||||
"apply_user_permissions": 0,
|
"print": 1,
|
||||||
"cancel": 0,
|
"read": 1,
|
||||||
"create": 0,
|
"report": 1,
|
||||||
"delete": 0,
|
"role": "Sales User"
|
||||||
"email": 1,
|
},
|
||||||
"export": 0,
|
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "Sales User",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 0,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"create": 1,
|
||||||
"apply_user_permissions": 0,
|
"email": 1,
|
||||||
"cancel": 0,
|
"print": 1,
|
||||||
"create": 1,
|
"read": 1,
|
||||||
"delete": 0,
|
"report": 1,
|
||||||
"email": 1,
|
"role": "Sales Master Manager",
|
||||||
"export": 0,
|
"share": 1,
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "Sales Master Manager",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"read_only": 0,
|
"sort_field": "modified",
|
||||||
"read_only_onload": 0,
|
"sort_order": "DESC",
|
||||||
"track_seen": 0
|
"states": [],
|
||||||
|
"translated_doctype": 1
|
||||||
}
|
}
|
||||||
@@ -1,94 +1,47 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"actions": [],
|
||||||
"allow_guest_to_view": 0,
|
"autoname": "field:sales_partner_type",
|
||||||
"allow_import": 0,
|
"creation": "2018-06-11 13:15:57.404716",
|
||||||
"allow_rename": 0,
|
"doctype": "DocType",
|
||||||
"autoname": "field:sales_partner_type",
|
"editable_grid": 1,
|
||||||
"beta": 0,
|
"engine": "InnoDB",
|
||||||
"creation": "2018-06-11 13:15:57.404716",
|
"field_order": [
|
||||||
"custom": 0,
|
"sales_partner_type"
|
||||||
"docstatus": 0,
|
],
|
||||||
"doctype": "DocType",
|
|
||||||
"document_type": "",
|
|
||||||
"editable_grid": 1,
|
|
||||||
"engine": "InnoDB",
|
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "sales_partner_type",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Data",
|
||||||
"allow_on_submit": 0,
|
"in_list_view": 1,
|
||||||
"bold": 0,
|
"label": "Sales Partner Type",
|
||||||
"collapsible": 0,
|
"reqd": 1,
|
||||||
"columns": 0,
|
"unique": 1
|
||||||
"fieldname": "sales_partner_type",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Sales Partner Type",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
"links": [],
|
||||||
"hide_heading": 0,
|
"modified": "2023-02-10 01:00:20.110800",
|
||||||
"hide_toolbar": 0,
|
"modified_by": "Administrator",
|
||||||
"idx": 0,
|
"module": "Selling",
|
||||||
"image_view": 0,
|
"name": "Sales Partner Type",
|
||||||
"in_create": 0,
|
"naming_rule": "By fieldname",
|
||||||
"is_submittable": 0,
|
"owner": "Administrator",
|
||||||
"issingle": 0,
|
|
||||||
"istable": 0,
|
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2018-06-11 13:45:13.554307",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "Selling",
|
|
||||||
"name": "Sales Partner Type",
|
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"create": 1,
|
||||||
"cancel": 0,
|
"delete": 1,
|
||||||
"create": 1,
|
"email": 1,
|
||||||
"delete": 1,
|
"export": 1,
|
||||||
"email": 1,
|
"print": 1,
|
||||||
"export": 1,
|
"read": 1,
|
||||||
"if_owner": 0,
|
"report": 1,
|
||||||
"import": 0,
|
"role": "System Manager",
|
||||||
"permlevel": 0,
|
"share": 1,
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "System Manager",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"read_only": 0,
|
"sort_field": "modified",
|
||||||
"read_only_onload": 0,
|
"sort_order": "DESC",
|
||||||
"show_name_in_global_search": 0,
|
"states": [],
|
||||||
"sort_field": "modified",
|
"translated_doctype": 1
|
||||||
"sort_order": "DESC",
|
|
||||||
"track_changes": 0,
|
|
||||||
"track_seen": 0
|
|
||||||
}
|
}
|
||||||
@@ -216,7 +216,7 @@ def get_sales_order_details(company_list, filters):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if filters.get("item_group"):
|
if filters.get("item_group"):
|
||||||
query = query.where(db_so_item.item_group == frappe.db.escape(filters.item_group))
|
query = query.where(db_so_item.item_group == filters.item_group)
|
||||||
|
|
||||||
if filters.get("from_date"):
|
if filters.get("from_date"):
|
||||||
query = query.where(db_so.transaction_date >= filters.from_date)
|
query = query.where(db_so.transaction_date >= filters.from_date)
|
||||||
@@ -225,7 +225,7 @@ def get_sales_order_details(company_list, filters):
|
|||||||
query = query.where(db_so.transaction_date <= filters.to_date)
|
query = query.where(db_so.transaction_date <= filters.to_date)
|
||||||
|
|
||||||
if filters.get("item_code"):
|
if filters.get("item_code"):
|
||||||
query = query.where(db_so_item.item_group == frappe.db.escape(filters.item_code))
|
query = query.where(db_so_item.item_code == filters.item_code)
|
||||||
|
|
||||||
if filters.get("customer"):
|
if filters.get("customer"):
|
||||||
query = query.where(db_so.customer == filters.customer)
|
query = query.where(db_so.customer == filters.customer)
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
"icon": "fa fa-bookmark",
|
"icon": "fa fa-bookmark",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-06-28 17:10:26.853753",
|
"modified": "2023-02-10 01:53:41.319386",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Setup",
|
"module": "Setup",
|
||||||
"name": "Designation",
|
"name": "Designation",
|
||||||
@@ -58,5 +58,6 @@
|
|||||||
"show_name_in_global_search": 1,
|
"show_name_in_global_search": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "ASC",
|
"sort_order": "ASC",
|
||||||
"states": []
|
"states": [],
|
||||||
|
"translated_doctype": 1
|
||||||
}
|
}
|
||||||
@@ -3,13 +3,17 @@
|
|||||||
|
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _, qb
|
||||||
from frappe.desk.notifications import clear_notifications
|
from frappe.desk.notifications import clear_notifications
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils import cint
|
from frappe.utils import cint, create_batch
|
||||||
|
|
||||||
|
|
||||||
class TransactionDeletionRecord(Document):
|
class TransactionDeletionRecord(Document):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(TransactionDeletionRecord, self).__init__(*args, **kwargs)
|
||||||
|
self.batch_size = 5000
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
frappe.only_for("System Manager")
|
frappe.only_for("System Manager")
|
||||||
self.validate_doctypes_to_be_ignored()
|
self.validate_doctypes_to_be_ignored()
|
||||||
@@ -155,8 +159,9 @@ class TransactionDeletionRecord(Document):
|
|||||||
"DocField", filters={"fieldtype": "Table", "parent": doctype}, pluck="options"
|
"DocField", filters={"fieldtype": "Table", "parent": doctype}, pluck="options"
|
||||||
)
|
)
|
||||||
|
|
||||||
for table in child_tables:
|
for batch in create_batch(parent_docs_to_be_deleted, self.batch_size):
|
||||||
frappe.db.delete(table, {"parent": ["in", parent_docs_to_be_deleted]})
|
for table in child_tables:
|
||||||
|
frappe.db.delete(table, {"parent": ["in", batch]})
|
||||||
|
|
||||||
def delete_docs_linked_with_specified_company(self, doctype, company_fieldname):
|
def delete_docs_linked_with_specified_company(self, doctype, company_fieldname):
|
||||||
frappe.db.delete(doctype, {company_fieldname: self.company})
|
frappe.db.delete(doctype, {company_fieldname: self.company})
|
||||||
@@ -181,13 +186,16 @@ class TransactionDeletionRecord(Document):
|
|||||||
frappe.db.sql("""update `tabSeries` set current = %s where name=%s""", (last, prefix))
|
frappe.db.sql("""update `tabSeries` set current = %s where name=%s""", (last, prefix))
|
||||||
|
|
||||||
def delete_version_log(self, doctype, company_fieldname):
|
def delete_version_log(self, doctype, company_fieldname):
|
||||||
frappe.db.sql(
|
dt = qb.DocType(doctype)
|
||||||
"""delete from `tabVersion` where ref_doctype=%s and docname in
|
names = qb.from_(dt).select(dt.name).where(dt[company_fieldname] == self.company).run(as_list=1)
|
||||||
(select name from `tab{0}` where `{1}`=%s)""".format(
|
names = [x[0] for x in names]
|
||||||
doctype, company_fieldname
|
|
||||||
),
|
if names:
|
||||||
(doctype, self.company),
|
versions = qb.DocType("Version")
|
||||||
)
|
for batch in create_batch(names, self.batch_size):
|
||||||
|
qb.from_(versions).delete().where(
|
||||||
|
(versions.ref_doctype == doctype) & (versions.docname.isin(batch))
|
||||||
|
).run()
|
||||||
|
|
||||||
def delete_communications(self, doctype, company_fieldname):
|
def delete_communications(self, doctype, company_fieldname):
|
||||||
reference_docs = frappe.get_all(doctype, filters={company_fieldname: self.company})
|
reference_docs = frappe.get_all(doctype, filters={company_fieldname: self.company})
|
||||||
@@ -199,7 +207,8 @@ class TransactionDeletionRecord(Document):
|
|||||||
)
|
)
|
||||||
communication_names = [c.name for c in communications]
|
communication_names = [c.name for c in communications]
|
||||||
|
|
||||||
frappe.delete_doc("Communication", communication_names, ignore_permissions=True)
|
for batch in create_batch(communication_names, self.batch_size):
|
||||||
|
frappe.delete_doc("Communication", batch, ignore_permissions=True)
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
|
|||||||
31
erpnext/setup/setup_wizard/data/designation.txt
Normal file
31
erpnext/setup/setup_wizard/data/designation.txt
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
Accountant
|
||||||
|
Administrative Assistant
|
||||||
|
Administrative Officer
|
||||||
|
Analyst
|
||||||
|
Associate
|
||||||
|
Business Analyst
|
||||||
|
Business Development Manager
|
||||||
|
Consultant
|
||||||
|
Chief Executive Officer
|
||||||
|
Chief Financial Officer
|
||||||
|
Chief Operating Officer
|
||||||
|
Chief Technology Officer
|
||||||
|
Customer Service Representative
|
||||||
|
Designer
|
||||||
|
Engineer
|
||||||
|
Executive Assistant
|
||||||
|
Finance Manager
|
||||||
|
HR Manager
|
||||||
|
Head of Marketing and Sales
|
||||||
|
Manager
|
||||||
|
Managing Director
|
||||||
|
Marketing Manager
|
||||||
|
Marketing Specialist
|
||||||
|
President
|
||||||
|
Product Manager
|
||||||
|
Project Manager
|
||||||
|
Researcher
|
||||||
|
Sales Representative
|
||||||
|
Secretary
|
||||||
|
Software Developer
|
||||||
|
Vice President
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
from frappe import _
|
|
||||||
|
|
||||||
|
|
||||||
def get_industry_types():
|
|
||||||
return [
|
|
||||||
_("Accounting"),
|
|
||||||
_("Advertising"),
|
|
||||||
_("Aerospace"),
|
|
||||||
_("Agriculture"),
|
|
||||||
_("Airline"),
|
|
||||||
_("Apparel & Accessories"),
|
|
||||||
_("Automotive"),
|
|
||||||
_("Banking"),
|
|
||||||
_("Biotechnology"),
|
|
||||||
_("Broadcasting"),
|
|
||||||
_("Brokerage"),
|
|
||||||
_("Chemical"),
|
|
||||||
_("Computer"),
|
|
||||||
_("Consulting"),
|
|
||||||
_("Consumer Products"),
|
|
||||||
_("Cosmetics"),
|
|
||||||
_("Defense"),
|
|
||||||
_("Department Stores"),
|
|
||||||
_("Education"),
|
|
||||||
_("Electronics"),
|
|
||||||
_("Energy"),
|
|
||||||
_("Entertainment & Leisure"),
|
|
||||||
_("Executive Search"),
|
|
||||||
_("Financial Services"),
|
|
||||||
_("Food, Beverage & Tobacco"),
|
|
||||||
_("Grocery"),
|
|
||||||
_("Health Care"),
|
|
||||||
_("Internet Publishing"),
|
|
||||||
_("Investment Banking"),
|
|
||||||
_("Legal"),
|
|
||||||
_("Manufacturing"),
|
|
||||||
_("Motion Picture & Video"),
|
|
||||||
_("Music"),
|
|
||||||
_("Newspaper Publishers"),
|
|
||||||
_("Online Auctions"),
|
|
||||||
_("Pension Funds"),
|
|
||||||
_("Pharmaceuticals"),
|
|
||||||
_("Private Equity"),
|
|
||||||
_("Publishing"),
|
|
||||||
_("Real Estate"),
|
|
||||||
_("Retail & Wholesale"),
|
|
||||||
_("Securities & Commodity Exchanges"),
|
|
||||||
_("Service"),
|
|
||||||
_("Soap & Detergent"),
|
|
||||||
_("Software"),
|
|
||||||
_("Sports"),
|
|
||||||
_("Technology"),
|
|
||||||
_("Telecommunications"),
|
|
||||||
_("Television"),
|
|
||||||
_("Transportation"),
|
|
||||||
_("Venture Capital"),
|
|
||||||
]
|
|
||||||
51
erpnext/setup/setup_wizard/data/industry_type.txt
Normal file
51
erpnext/setup/setup_wizard/data/industry_type.txt
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
Accounting
|
||||||
|
Advertising
|
||||||
|
Aerospace
|
||||||
|
Agriculture
|
||||||
|
Airline
|
||||||
|
Apparel & Accessories
|
||||||
|
Automotive
|
||||||
|
Banking
|
||||||
|
Biotechnology
|
||||||
|
Broadcasting
|
||||||
|
Brokerage
|
||||||
|
Chemical
|
||||||
|
Computer
|
||||||
|
Consulting
|
||||||
|
Consumer Products
|
||||||
|
Cosmetics
|
||||||
|
Defense
|
||||||
|
Department Stores
|
||||||
|
Education
|
||||||
|
Electronics
|
||||||
|
Energy
|
||||||
|
Entertainment & Leisure
|
||||||
|
Executive Search
|
||||||
|
Financial Services
|
||||||
|
Food, Beverage & Tobacco
|
||||||
|
Grocery
|
||||||
|
Health Care
|
||||||
|
Internet Publishing
|
||||||
|
Investment Banking
|
||||||
|
Legal
|
||||||
|
Manufacturing
|
||||||
|
Motion Picture & Video
|
||||||
|
Music
|
||||||
|
Newspaper Publishers
|
||||||
|
Online Auctions
|
||||||
|
Pension Funds
|
||||||
|
Pharmaceuticals
|
||||||
|
Private Equity
|
||||||
|
Publishing
|
||||||
|
Real Estate
|
||||||
|
Retail & Wholesale
|
||||||
|
Securities & Commodity Exchanges
|
||||||
|
Service
|
||||||
|
Soap & Detergent
|
||||||
|
Software
|
||||||
|
Sports
|
||||||
|
Technology
|
||||||
|
Telecommunications
|
||||||
|
Television
|
||||||
|
Transportation
|
||||||
|
Venture Capital
|
||||||
10
erpnext/setup/setup_wizard/data/lead_source.txt
Normal file
10
erpnext/setup/setup_wizard/data/lead_source.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Existing Customer
|
||||||
|
Reference
|
||||||
|
Advertisement
|
||||||
|
Cold Calling
|
||||||
|
Exhibition
|
||||||
|
Supplier Reference
|
||||||
|
Mass Mailing
|
||||||
|
Customer's Vendor
|
||||||
|
Campaign
|
||||||
|
Walk In
|
||||||
7
erpnext/setup/setup_wizard/data/sales_partner_type.txt
Normal file
7
erpnext/setup/setup_wizard/data/sales_partner_type.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Channel Partner
|
||||||
|
Distributor
|
||||||
|
Dealer
|
||||||
|
Agent
|
||||||
|
Retailer
|
||||||
|
Implementation Partner
|
||||||
|
Reseller
|
||||||
8
erpnext/setup/setup_wizard/data/sales_stage.txt
Normal file
8
erpnext/setup/setup_wizard/data/sales_stage.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Prospecting
|
||||||
|
Qualification
|
||||||
|
Needs Analysis
|
||||||
|
Value Proposition
|
||||||
|
Identifying Decision Makers
|
||||||
|
Perception Analysis
|
||||||
|
Proposal/Price Quote
|
||||||
|
Negotiation/Review
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
@@ -16,28 +17,10 @@ from frappe.utils import cstr, getdate
|
|||||||
from erpnext.accounts.doctype.account.account import RootNotEditable
|
from erpnext.accounts.doctype.account.account import RootNotEditable
|
||||||
from erpnext.regional.address_template.setup import set_up_address_templates
|
from erpnext.regional.address_template.setup import set_up_address_templates
|
||||||
|
|
||||||
default_lead_sources = [
|
|
||||||
"Existing Customer",
|
|
||||||
"Reference",
|
|
||||||
"Advertisement",
|
|
||||||
"Cold Calling",
|
|
||||||
"Exhibition",
|
|
||||||
"Supplier Reference",
|
|
||||||
"Mass Mailing",
|
|
||||||
"Customer's Vendor",
|
|
||||||
"Campaign",
|
|
||||||
"Walk In",
|
|
||||||
]
|
|
||||||
|
|
||||||
default_sales_partner_type = [
|
def read_lines(filename: str) -> list[str]:
|
||||||
"Channel Partner",
|
"""Return a list of lines from a file in the data directory."""
|
||||||
"Distributor",
|
return (Path(__file__).parent.parent / "data" / filename).read_text().splitlines()
|
||||||
"Dealer",
|
|
||||||
"Agent",
|
|
||||||
"Retailer",
|
|
||||||
"Implementation Partner",
|
|
||||||
"Reseller",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def install(country=None):
|
def install(country=None):
|
||||||
@@ -85,7 +68,11 @@ def install(country=None):
|
|||||||
# Stock Entry Type
|
# Stock Entry Type
|
||||||
{"doctype": "Stock Entry Type", "name": "Material Issue", "purpose": "Material Issue"},
|
{"doctype": "Stock Entry Type", "name": "Material Issue", "purpose": "Material Issue"},
|
||||||
{"doctype": "Stock Entry Type", "name": "Material Receipt", "purpose": "Material Receipt"},
|
{"doctype": "Stock Entry Type", "name": "Material Receipt", "purpose": "Material Receipt"},
|
||||||
{"doctype": "Stock Entry Type", "name": "Material Transfer", "purpose": "Material Transfer"},
|
{
|
||||||
|
"doctype": "Stock Entry Type",
|
||||||
|
"name": "Material Transfer",
|
||||||
|
"purpose": "Material Transfer",
|
||||||
|
},
|
||||||
{"doctype": "Stock Entry Type", "name": "Manufacture", "purpose": "Manufacture"},
|
{"doctype": "Stock Entry Type", "name": "Manufacture", "purpose": "Manufacture"},
|
||||||
{"doctype": "Stock Entry Type", "name": "Repack", "purpose": "Repack"},
|
{"doctype": "Stock Entry Type", "name": "Repack", "purpose": "Repack"},
|
||||||
{
|
{
|
||||||
@@ -103,22 +90,6 @@ def install(country=None):
|
|||||||
"name": "Material Consumption for Manufacture",
|
"name": "Material Consumption for Manufacture",
|
||||||
"purpose": "Material Consumption for Manufacture",
|
"purpose": "Material Consumption for Manufacture",
|
||||||
},
|
},
|
||||||
# Designation
|
|
||||||
{"doctype": "Designation", "designation_name": _("CEO")},
|
|
||||||
{"doctype": "Designation", "designation_name": _("Manager")},
|
|
||||||
{"doctype": "Designation", "designation_name": _("Analyst")},
|
|
||||||
{"doctype": "Designation", "designation_name": _("Engineer")},
|
|
||||||
{"doctype": "Designation", "designation_name": _("Accountant")},
|
|
||||||
{"doctype": "Designation", "designation_name": _("Secretary")},
|
|
||||||
{"doctype": "Designation", "designation_name": _("Associate")},
|
|
||||||
{"doctype": "Designation", "designation_name": _("Administrative Officer")},
|
|
||||||
{"doctype": "Designation", "designation_name": _("Business Development Manager")},
|
|
||||||
{"doctype": "Designation", "designation_name": _("HR Manager")},
|
|
||||||
{"doctype": "Designation", "designation_name": _("Project Manager")},
|
|
||||||
{"doctype": "Designation", "designation_name": _("Head of Marketing and Sales")},
|
|
||||||
{"doctype": "Designation", "designation_name": _("Software Developer")},
|
|
||||||
{"doctype": "Designation", "designation_name": _("Designer")},
|
|
||||||
{"doctype": "Designation", "designation_name": _("Researcher")},
|
|
||||||
# territory: with two default territories, one for home country and one named Rest of the World
|
# territory: with two default territories, one for home country and one named Rest of the World
|
||||||
{
|
{
|
||||||
"doctype": "Territory",
|
"doctype": "Territory",
|
||||||
@@ -291,28 +262,18 @@ def install(country=None):
|
|||||||
{"doctype": "Market Segment", "market_segment": _("Lower Income")},
|
{"doctype": "Market Segment", "market_segment": _("Lower Income")},
|
||||||
{"doctype": "Market Segment", "market_segment": _("Middle Income")},
|
{"doctype": "Market Segment", "market_segment": _("Middle Income")},
|
||||||
{"doctype": "Market Segment", "market_segment": _("Upper Income")},
|
{"doctype": "Market Segment", "market_segment": _("Upper Income")},
|
||||||
# Sales Stages
|
|
||||||
{"doctype": "Sales Stage", "stage_name": _("Prospecting")},
|
|
||||||
{"doctype": "Sales Stage", "stage_name": _("Qualification")},
|
|
||||||
{"doctype": "Sales Stage", "stage_name": _("Needs Analysis")},
|
|
||||||
{"doctype": "Sales Stage", "stage_name": _("Value Proposition")},
|
|
||||||
{"doctype": "Sales Stage", "stage_name": _("Identifying Decision Makers")},
|
|
||||||
{"doctype": "Sales Stage", "stage_name": _("Perception Analysis")},
|
|
||||||
{"doctype": "Sales Stage", "stage_name": _("Proposal/Price Quote")},
|
|
||||||
{"doctype": "Sales Stage", "stage_name": _("Negotiation/Review")},
|
|
||||||
# Warehouse Type
|
# Warehouse Type
|
||||||
{"doctype": "Warehouse Type", "name": "Transit"},
|
{"doctype": "Warehouse Type", "name": "Transit"},
|
||||||
]
|
]
|
||||||
|
|
||||||
from erpnext.setup.setup_wizard.data.industry_type import get_industry_types
|
for doctype, title_field, filename in (
|
||||||
|
("Designation", "designation_name", "designation.txt"),
|
||||||
records += [{"doctype": "Industry Type", "industry": d} for d in get_industry_types()]
|
("Sales Stage", "stage_name", "sales_stage.txt"),
|
||||||
# records += [{"doctype":"Operation", "operation": d} for d in get_operations()]
|
("Industry Type", "industry", "industry_type.txt"),
|
||||||
records += [{"doctype": "Lead Source", "source_name": _(d)} for d in default_lead_sources]
|
("Lead Source", "source_name", "lead_source.txt"),
|
||||||
|
("Sales Partner Type", "sales_partner_type", "sales_partner_type.txt"),
|
||||||
records += [
|
):
|
||||||
{"doctype": "Sales Partner Type", "sales_partner_type": _(d)} for d in default_sales_partner_type
|
records += [{"doctype": doctype, title_field: title} for title in read_lines(filename)]
|
||||||
]
|
|
||||||
|
|
||||||
base_path = frappe.get_app_path("erpnext", "stock", "doctype")
|
base_path = frappe.get_app_path("erpnext", "stock", "doctype")
|
||||||
response = frappe.read_file(
|
response = frappe.read_file(
|
||||||
@@ -397,7 +358,8 @@ def add_uom_data():
|
|||||||
frappe.get_doc({"doctype": "UOM Category", "category_name": _(d.get("category"))}).db_insert()
|
frappe.get_doc({"doctype": "UOM Category", "category_name": _(d.get("category"))}).db_insert()
|
||||||
|
|
||||||
if not frappe.db.exists(
|
if not frappe.db.exists(
|
||||||
"UOM Conversion Factor", {"from_uom": _(d.get("from_uom")), "to_uom": _(d.get("to_uom"))}
|
"UOM Conversion Factor",
|
||||||
|
{"from_uom": _(d.get("from_uom")), "to_uom": _(d.get("to_uom"))},
|
||||||
):
|
):
|
||||||
frappe.get_doc(
|
frappe.get_doc(
|
||||||
{
|
{
|
||||||
@@ -535,7 +497,8 @@ def create_bank_account(args):
|
|||||||
|
|
||||||
company_name = args.get("company_name")
|
company_name = args.get("company_name")
|
||||||
bank_account_group = frappe.db.get_value(
|
bank_account_group = frappe.db.get_value(
|
||||||
"Account", {"account_type": "Bank", "is_group": 1, "root_type": "Asset", "company": company_name}
|
"Account",
|
||||||
|
{"account_type": "Bank", "is_group": 1, "root_type": "Asset", "company": company_name},
|
||||||
)
|
)
|
||||||
if bank_account_group:
|
if bank_account_group:
|
||||||
bank_account = frappe.get_doc(
|
bank_account = frappe.get_doc(
|
||||||
|
|||||||
@@ -97,12 +97,12 @@ frappe.ui.form.on("Delivery Note", {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (frm.doc.docstatus == 1 && !frm.doc.inter_company_reference) {
|
if (frm.doc.docstatus == 1 && !frm.doc.inter_company_reference) {
|
||||||
let internal = me.frm.doc.is_internal_customer;
|
let internal = frm.doc.is_internal_customer;
|
||||||
if (internal) {
|
if (internal) {
|
||||||
let button_label = (me.frm.doc.company === me.frm.doc.represents_company) ? "Internal Purchase Receipt" :
|
let button_label = (frm.doc.company === frm.doc.represents_company) ? "Internal Purchase Receipt" :
|
||||||
"Inter Company Purchase Receipt";
|
"Inter Company Purchase Receipt";
|
||||||
|
|
||||||
me.frm.add_custom_button(button_label, function() {
|
frm.add_custom_button(__(button_label), function() {
|
||||||
frappe.model.open_mapped_doc({
|
frappe.model.open_mapped_doc({
|
||||||
method: 'erpnext.stock.doctype.delivery_note.delivery_note.make_inter_company_purchase_receipt',
|
method: 'erpnext.stock.doctype.delivery_note.delivery_note.make_inter_company_purchase_receipt',
|
||||||
frm: frm,
|
frm: frm,
|
||||||
|
|||||||
@@ -521,6 +521,7 @@
|
|||||||
"allow_bulk_edit": 1,
|
"allow_bulk_edit": 1,
|
||||||
"fieldname": "items",
|
"fieldname": "items",
|
||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
|
"label": "Delivery Note Item",
|
||||||
"oldfieldname": "delivery_note_details",
|
"oldfieldname": "delivery_note_details",
|
||||||
"oldfieldtype": "Table",
|
"oldfieldtype": "Table",
|
||||||
"options": "Delivery Note Item",
|
"options": "Delivery Note Item",
|
||||||
@@ -666,6 +667,7 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "taxes",
|
"fieldname": "taxes",
|
||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
|
"label": "Sales Taxes and Charges",
|
||||||
"oldfieldname": "other_charges",
|
"oldfieldname": "other_charges",
|
||||||
"oldfieldtype": "Table",
|
"oldfieldtype": "Table",
|
||||||
"options": "Sales Taxes and Charges"
|
"options": "Sales Taxes and Charges"
|
||||||
@@ -1401,7 +1403,7 @@
|
|||||||
"idx": 146,
|
"idx": 146,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-12-12 18:38:53.067799",
|
"modified": "2023-02-14 04:45:44.179670",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Delivery Note",
|
"name": "Delivery Note",
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ frappe.listview_settings['Delivery Note'] = {
|
|||||||
return [__("Completed"), "green", "per_billed,=,100"];
|
return [__("Completed"), "green", "per_billed,=,100"];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onload: function (listview) {
|
onload: function (doclist) {
|
||||||
const action = () => {
|
const action = () => {
|
||||||
const selected_docs = doclist.get_checked_items();
|
const selected_docs = doclist.get_checked_items();
|
||||||
const docnames = doclist.get_checked_items(true);
|
const docnames = doclist.get_checked_items(true);
|
||||||
@@ -56,14 +56,14 @@ frappe.listview_settings['Delivery Note'] = {
|
|||||||
|
|
||||||
// doclist.page.add_actions_menu_item(__('Create Delivery Trip'), action, false);
|
// doclist.page.add_actions_menu_item(__('Create Delivery Trip'), action, false);
|
||||||
|
|
||||||
listview.page.add_action_item(__('Create Delivery Trip'), action);
|
doclist.page.add_action_item(__('Create Delivery Trip'), action);
|
||||||
|
|
||||||
listview.page.add_action_item(__("Sales Invoice"), ()=>{
|
doclist.page.add_action_item(__("Sales Invoice"), ()=>{
|
||||||
erpnext.bulk_transaction_processing.create(listview, "Delivery Note", "Sales Invoice");
|
erpnext.bulk_transaction_processing.create(doclist, "Delivery Note", "Sales Invoice");
|
||||||
});
|
});
|
||||||
|
|
||||||
listview.page.add_action_item(__("Packaging Slip From Delivery Note"), ()=>{
|
doclist.page.add_action_item(__("Packaging Slip From Delivery Note"), ()=>{
|
||||||
erpnext.bulk_transaction_processing.create(listview, "Delivery Note", "Packing Slip");
|
erpnext.bulk_transaction_processing.create(doclist, "Delivery Note", "Packing Slip");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -706,7 +706,7 @@
|
|||||||
"depends_on": "enable_deferred_expense",
|
"depends_on": "enable_deferred_expense",
|
||||||
"fieldname": "no_of_months_exp",
|
"fieldname": "no_of_months_exp",
|
||||||
"fieldtype": "Int",
|
"fieldtype": "Int",
|
||||||
"label": "No of Months"
|
"label": "No of Months (Expense)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"collapsible": 1,
|
"collapsible": 1,
|
||||||
@@ -911,7 +911,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"make_attachments_public": 1,
|
"make_attachments_public": 1,
|
||||||
"modified": "2022-09-13 04:08:17.431731",
|
"modified": "2023-02-14 04:48:26.343620",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Item",
|
"name": "Item",
|
||||||
|
|||||||
@@ -108,10 +108,13 @@ frappe.ui.form.on('Material Request', {
|
|||||||
() => frm.events.create_pick_list(frm), __('Create'));
|
() => frm.events.create_pick_list(frm), __('Create'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frm.doc.material_request_type === "Material Transfer") {
|
if (frm.doc.material_request_type === 'Material Transfer') {
|
||||||
add_create_pick_list_button();
|
add_create_pick_list_button();
|
||||||
frm.add_custom_button(__("Transfer Material"),
|
frm.add_custom_button(__('Material Transfer'),
|
||||||
() => frm.events.make_stock_entry(frm), __('Create'));
|
() => frm.events.make_stock_entry(frm), __('Create'));
|
||||||
|
|
||||||
|
frm.add_custom_button(__('Material Transfer (In Transit)'),
|
||||||
|
() => frm.events.make_in_transit_stock_entry(frm), __('Create'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frm.doc.material_request_type === "Material Issue") {
|
if (frm.doc.material_request_type === "Material Issue") {
|
||||||
@@ -333,6 +336,46 @@ frappe.ui.form.on('Material Request', {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
make_in_transit_stock_entry(frm) {
|
||||||
|
frappe.prompt(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
label: __('In Transit Warehouse'),
|
||||||
|
fieldname: 'in_transit_warehouse',
|
||||||
|
fieldtype: 'Link',
|
||||||
|
options: 'Warehouse',
|
||||||
|
reqd: 1,
|
||||||
|
get_query: () => {
|
||||||
|
return{
|
||||||
|
filters: {
|
||||||
|
'company': frm.doc.company,
|
||||||
|
'is_group': 0,
|
||||||
|
'warehouse_type': 'Transit'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
(values) => {
|
||||||
|
frappe.call({
|
||||||
|
method: "erpnext.stock.doctype.material_request.material_request.make_in_transit_stock_entry",
|
||||||
|
args: {
|
||||||
|
source_name: frm.doc.name,
|
||||||
|
in_transit_warehouse: values.in_transit_warehouse
|
||||||
|
},
|
||||||
|
callback: function(r) {
|
||||||
|
if (r.message) {
|
||||||
|
let doc = frappe.model.sync(r.message);
|
||||||
|
frappe.set_route('Form', doc[0].doctype, doc[0].name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
__('In Transit Transfer'),
|
||||||
|
__('Create Stock Entry')
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
create_pick_list: (frm) => {
|
create_pick_list: (frm) => {
|
||||||
frappe.model.open_mapped_doc({
|
frappe.model.open_mapped_doc({
|
||||||
method: "erpnext.stock.doctype.material_request.material_request.create_pick_list",
|
method: "erpnext.stock.doctype.material_request.material_request.create_pick_list",
|
||||||
|
|||||||
@@ -719,3 +719,14 @@ def create_pick_list(source_name, target_doc=None):
|
|||||||
doc.set_item_locations()
|
doc.set_item_locations()
|
||||||
|
|
||||||
return doc
|
return doc
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def make_in_transit_stock_entry(source_name, in_transit_warehouse):
|
||||||
|
ste_doc = make_stock_entry(source_name)
|
||||||
|
ste_doc.add_to_transit = 1
|
||||||
|
|
||||||
|
for row in ste_doc.items:
|
||||||
|
row.t_warehouse = in_transit_warehouse
|
||||||
|
|
||||||
|
return ste_doc
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ from frappe.utils import flt, today
|
|||||||
|
|
||||||
from erpnext.stock.doctype.item.test_item import create_item
|
from erpnext.stock.doctype.item.test_item import create_item
|
||||||
from erpnext.stock.doctype.material_request.material_request import (
|
from erpnext.stock.doctype.material_request.material_request import (
|
||||||
|
make_in_transit_stock_entry,
|
||||||
make_purchase_order,
|
make_purchase_order,
|
||||||
make_stock_entry,
|
make_stock_entry,
|
||||||
make_supplier_quotation,
|
make_supplier_quotation,
|
||||||
@@ -56,6 +57,22 @@ class TestMaterialRequest(FrappeTestCase):
|
|||||||
self.assertEqual(se.doctype, "Stock Entry")
|
self.assertEqual(se.doctype, "Stock Entry")
|
||||||
self.assertEqual(len(se.get("items")), len(mr.get("items")))
|
self.assertEqual(len(se.get("items")), len(mr.get("items")))
|
||||||
|
|
||||||
|
def test_in_transit_make_stock_entry(self):
|
||||||
|
mr = frappe.copy_doc(test_records[0]).insert()
|
||||||
|
|
||||||
|
self.assertRaises(frappe.ValidationError, make_stock_entry, mr.name)
|
||||||
|
|
||||||
|
mr = frappe.get_doc("Material Request", mr.name)
|
||||||
|
mr.material_request_type = "Material Transfer"
|
||||||
|
mr.submit()
|
||||||
|
|
||||||
|
in_transit_warehouse = get_in_transit_warehouse(mr.company)
|
||||||
|
se = make_in_transit_stock_entry(mr.name, in_transit_warehouse)
|
||||||
|
|
||||||
|
self.assertEqual(se.doctype, "Stock Entry")
|
||||||
|
for row in se.get("items"):
|
||||||
|
self.assertEqual(row.t_warehouse, in_transit_warehouse)
|
||||||
|
|
||||||
def _insert_stock_entry(self, qty1, qty2, warehouse=None):
|
def _insert_stock_entry(self, qty1, qty2, warehouse=None):
|
||||||
se = frappe.get_doc(
|
se = frappe.get_doc(
|
||||||
{
|
{
|
||||||
@@ -742,6 +759,36 @@ class TestMaterialRequest(FrappeTestCase):
|
|||||||
self.assertEqual(existing_requested_qty, current_requested_qty)
|
self.assertEqual(existing_requested_qty, current_requested_qty)
|
||||||
|
|
||||||
|
|
||||||
|
def get_in_transit_warehouse(company):
|
||||||
|
if not frappe.db.exists("Warehouse Type", "Transit"):
|
||||||
|
frappe.get_doc(
|
||||||
|
{
|
||||||
|
"doctype": "Warehouse Type",
|
||||||
|
"name": "Transit",
|
||||||
|
}
|
||||||
|
).insert()
|
||||||
|
|
||||||
|
in_transit_warehouse = frappe.db.exists(
|
||||||
|
"Warehouse", {"warehouse_type": "Transit", "company": company}
|
||||||
|
)
|
||||||
|
|
||||||
|
if not in_transit_warehouse:
|
||||||
|
in_transit_warehouse = (
|
||||||
|
frappe.get_doc(
|
||||||
|
{
|
||||||
|
"doctype": "Warehouse",
|
||||||
|
"warehouse_name": "Transit",
|
||||||
|
"warehouse_type": "Transit",
|
||||||
|
"company": company,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.insert()
|
||||||
|
.name
|
||||||
|
)
|
||||||
|
|
||||||
|
return in_transit_warehouse
|
||||||
|
|
||||||
|
|
||||||
def make_material_request(**args):
|
def make_material_request(**args):
|
||||||
args = frappe._dict(args)
|
args = frappe._dict(args)
|
||||||
mr = frappe.new_doc("Material Request")
|
mr = frappe.new_doc("Material Request")
|
||||||
|
|||||||
@@ -887,18 +887,10 @@ def update_billing_percentage(pr_doc, update_modified=True):
|
|||||||
|
|
||||||
# Update Billing % based on pending accepted qty
|
# Update Billing % based on pending accepted qty
|
||||||
total_amount, total_billed_amount = 0, 0
|
total_amount, total_billed_amount = 0, 0
|
||||||
for item in pr_doc.items:
|
item_wise_returned_qty = get_item_wise_returned_qty(pr_doc)
|
||||||
return_data = frappe.db.get_list(
|
|
||||||
"Purchase Receipt",
|
|
||||||
fields=["sum(abs(`tabPurchase Receipt Item`.qty)) as qty"],
|
|
||||||
filters=[
|
|
||||||
["Purchase Receipt", "docstatus", "=", 1],
|
|
||||||
["Purchase Receipt", "is_return", "=", 1],
|
|
||||||
["Purchase Receipt Item", "purchase_receipt_item", "=", item.name],
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
returned_qty = return_data[0].qty if return_data else 0
|
for item in pr_doc.items:
|
||||||
|
returned_qty = flt(item_wise_returned_qty.get(item.name))
|
||||||
returned_amount = flt(returned_qty) * flt(item.rate)
|
returned_amount = flt(returned_qty) * flt(item.rate)
|
||||||
pending_amount = flt(item.amount) - returned_amount
|
pending_amount = flt(item.amount) - returned_amount
|
||||||
total_billable_amount = pending_amount if item.billed_amt <= pending_amount else item.billed_amt
|
total_billable_amount = pending_amount if item.billed_amt <= pending_amount else item.billed_amt
|
||||||
@@ -915,6 +907,27 @@ def update_billing_percentage(pr_doc, update_modified=True):
|
|||||||
pr_doc.notify_update()
|
pr_doc.notify_update()
|
||||||
|
|
||||||
|
|
||||||
|
def get_item_wise_returned_qty(pr_doc):
|
||||||
|
items = [d.name for d in pr_doc.items]
|
||||||
|
|
||||||
|
return frappe._dict(
|
||||||
|
frappe.get_all(
|
||||||
|
"Purchase Receipt",
|
||||||
|
fields=[
|
||||||
|
"`tabPurchase Receipt Item`.purchase_receipt_item",
|
||||||
|
"sum(abs(`tabPurchase Receipt Item`.qty)) as qty",
|
||||||
|
],
|
||||||
|
filters=[
|
||||||
|
["Purchase Receipt", "docstatus", "=", 1],
|
||||||
|
["Purchase Receipt", "is_return", "=", 1],
|
||||||
|
["Purchase Receipt Item", "purchase_receipt_item", "in", items],
|
||||||
|
],
|
||||||
|
group_by="`tabPurchase Receipt Item`.purchase_receipt_item",
|
||||||
|
as_list=1,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def make_purchase_invoice(source_name, target_doc=None):
|
def make_purchase_invoice(source_name, target_doc=None):
|
||||||
from erpnext.accounts.party import get_payment_terms_template
|
from erpnext.accounts.party import get_payment_terms_template
|
||||||
|
|||||||
@@ -859,7 +859,8 @@
|
|||||||
"label": "Purchase Receipt Item",
|
"label": "Purchase Receipt Item",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1,
|
||||||
|
"search_index": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"collapsible": 1,
|
"collapsible": 1,
|
||||||
@@ -974,7 +975,8 @@
|
|||||||
"label": "Purchase Invoice Item",
|
"label": "Purchase Invoice Item",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1,
|
||||||
|
"search_index": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "product_bundle",
|
"fieldname": "product_bundle",
|
||||||
@@ -1010,7 +1012,7 @@
|
|||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-11-02 12:49:28.746701",
|
"modified": "2023-01-18 15:48:58.114923",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Purchase Receipt Item",
|
"name": "Purchase Receipt Item",
|
||||||
|
|||||||
@@ -2,7 +2,22 @@
|
|||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
frappe.ui.form.on('Stock Reposting Settings', {
|
frappe.ui.form.on('Stock Reposting Settings', {
|
||||||
// refresh: function(frm) {
|
refresh: function(frm) {
|
||||||
|
frm.trigger('convert_to_item_based_reposting');
|
||||||
|
},
|
||||||
|
|
||||||
// }
|
convert_to_item_based_reposting: function(frm) {
|
||||||
|
frm.add_custom_button(__('Convert to Item Based Reposting'), function() {
|
||||||
|
frm.call({
|
||||||
|
method: 'convert_to_item_wh_reposting',
|
||||||
|
frezz: true,
|
||||||
|
doc: frm.doc,
|
||||||
|
callback: function(r) {
|
||||||
|
if (!r.exc) {
|
||||||
|
frm.reload_doc();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
|
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
from frappe import _
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils import add_to_date, get_datetime, get_time_str, time_diff_in_hours
|
from frappe.utils import add_to_date, get_datetime, get_time_str, time_diff_in_hours
|
||||||
|
|
||||||
@@ -24,3 +26,62 @@ class StockRepostingSettings(Document):
|
|||||||
|
|
||||||
if diff < 10:
|
if diff < 10:
|
||||||
self.end_time = get_time_str(add_to_date(self.start_time, hours=10, as_datetime=True))
|
self.end_time = get_time_str(add_to_date(self.start_time, hours=10, as_datetime=True))
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def convert_to_item_wh_reposting(self):
|
||||||
|
"""Convert Transaction reposting to Item Warehouse based reposting if Item Based Reposting has enabled."""
|
||||||
|
|
||||||
|
reposting_data = get_reposting_entries()
|
||||||
|
|
||||||
|
vouchers = [d.voucher_no for d in reposting_data]
|
||||||
|
|
||||||
|
item_warehouses = {}
|
||||||
|
|
||||||
|
for ledger in get_stock_ledgers(vouchers):
|
||||||
|
key = (ledger.item_code, ledger.warehouse)
|
||||||
|
if key not in item_warehouses:
|
||||||
|
item_warehouses[key] = ledger.posting_date
|
||||||
|
elif frappe.utils.getdate(item_warehouses.get(key)) > frappe.utils.getdate(ledger.posting_date):
|
||||||
|
item_warehouses[key] = ledger.posting_date
|
||||||
|
|
||||||
|
for key, posting_date in item_warehouses.items():
|
||||||
|
item_code, warehouse = key
|
||||||
|
create_repost_item_valuation(item_code, warehouse, posting_date)
|
||||||
|
|
||||||
|
for row in reposting_data:
|
||||||
|
frappe.db.set_value("Repost Item Valuation", row.name, "status", "Skipped")
|
||||||
|
|
||||||
|
self.db_set("item_based_reposting", 1)
|
||||||
|
frappe.msgprint(_("Item Warehouse based reposting has been enabled."))
|
||||||
|
|
||||||
|
|
||||||
|
def get_reposting_entries():
|
||||||
|
return frappe.get_all(
|
||||||
|
"Repost Item Valuation",
|
||||||
|
fields=["voucher_no", "name"],
|
||||||
|
filters={"status": ("in", ["Queued", "In Progress"]), "docstatus": 1, "based_on": "Transaction"},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_stock_ledgers(vouchers):
|
||||||
|
return frappe.get_all(
|
||||||
|
"Stock Ledger Entry",
|
||||||
|
fields=["item_code", "warehouse", "posting_date"],
|
||||||
|
filters={"voucher_no": ("in", vouchers)},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def create_repost_item_valuation(item_code, warehouse, posting_date):
|
||||||
|
frappe.get_doc(
|
||||||
|
{
|
||||||
|
"doctype": "Repost Item Valuation",
|
||||||
|
"company": frappe.get_cached_value("Warehouse", warehouse, "company"),
|
||||||
|
"posting_date": posting_date,
|
||||||
|
"based_on": "Item and Warehouse",
|
||||||
|
"posting_time": "00:00:01",
|
||||||
|
"item_code": item_code,
|
||||||
|
"warehouse": warehouse,
|
||||||
|
"allow_negative_stock": True,
|
||||||
|
"status": "Queued",
|
||||||
|
}
|
||||||
|
).submit()
|
||||||
|
|||||||
@@ -306,7 +306,7 @@ def get_stock_ledger_entries(filters, items):
|
|||||||
query = query.where(sle.item_code.isin(items))
|
query = query.where(sle.item_code.isin(items))
|
||||||
|
|
||||||
for field in ["voucher_no", "batch_no", "project", "company"]:
|
for field in ["voucher_no", "batch_no", "project", "company"]:
|
||||||
if filters.get(field):
|
if filters.get(field) and field not in inventory_dimension_fields:
|
||||||
query = query.where(sle[field] == filters.get(field))
|
query = query.where(sle[field] == filters.get(field))
|
||||||
|
|
||||||
query = apply_warehouse_filter(query, sle, filters)
|
query = apply_warehouse_filter(query, sle, filters)
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ def get_reserved_qty(item_code, warehouse):
|
|||||||
and parenttype='Sales Order'
|
and parenttype='Sales Order'
|
||||||
and item_code != parent_item
|
and item_code != parent_item
|
||||||
and exists (select * from `tabSales Order` so
|
and exists (select * from `tabSales Order` so
|
||||||
where name = dnpi_in.parent and docstatus = 1 and status != 'Closed')
|
where name = dnpi_in.parent and docstatus = 1 and status not in ('On Hold', 'Closed'))
|
||||||
) dnpi)
|
) dnpi)
|
||||||
union
|
union
|
||||||
(select stock_qty as dnpi_qty, qty as so_item_qty,
|
(select stock_qty as dnpi_qty, qty as so_item_qty,
|
||||||
@@ -131,7 +131,7 @@ def get_reserved_qty(item_code, warehouse):
|
|||||||
and (so_item.delivered_by_supplier is null or so_item.delivered_by_supplier = 0)
|
and (so_item.delivered_by_supplier is null or so_item.delivered_by_supplier = 0)
|
||||||
and exists(select * from `tabSales Order` so
|
and exists(select * from `tabSales Order` so
|
||||||
where so.name = so_item.parent and so.docstatus = 1
|
where so.name = so_item.parent and so.docstatus = 1
|
||||||
and so.status != 'Closed'))
|
and so.status not in ('On Hold', 'Closed')))
|
||||||
) tab
|
) tab
|
||||||
where
|
where
|
||||||
so_item_qty >= so_item_delivered_qty
|
so_item_qty >= so_item_delivered_qty
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.tests.utils import FrappeTestCase
|
from frappe.tests.utils import FrappeTestCase
|
||||||
@@ -186,6 +187,40 @@ class TestSubcontractingOrder(FrappeTestCase):
|
|||||||
)
|
)
|
||||||
self.assertEqual(len(ste.items), len(rm_items))
|
self.assertEqual(len(ste.items), len(rm_items))
|
||||||
|
|
||||||
|
def test_make_rm_stock_entry_for_batch_items_with_less_transfer(self):
|
||||||
|
set_backflush_based_on("BOM")
|
||||||
|
|
||||||
|
service_items = [
|
||||||
|
{
|
||||||
|
"warehouse": "_Test Warehouse - _TC",
|
||||||
|
"item_code": "Subcontracted Service Item 4",
|
||||||
|
"qty": 5,
|
||||||
|
"rate": 100,
|
||||||
|
"fg_item": "Subcontracted Item SA4",
|
||||||
|
"fg_item_qty": 5,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
sco = get_subcontracting_order(service_items=service_items)
|
||||||
|
rm_items = get_rm_items(sco.supplied_items)
|
||||||
|
itemwise_details = make_stock_in_entry(rm_items=rm_items)
|
||||||
|
|
||||||
|
itemwise_transfer_qty = defaultdict(int)
|
||||||
|
for item in rm_items:
|
||||||
|
item["qty"] -= 1
|
||||||
|
itemwise_transfer_qty[item["item_code"]] += item["qty"]
|
||||||
|
|
||||||
|
ste = make_stock_transfer_entry(
|
||||||
|
sco_no=sco.name,
|
||||||
|
rm_items=rm_items,
|
||||||
|
itemwise_details=copy.deepcopy(itemwise_details),
|
||||||
|
)
|
||||||
|
|
||||||
|
scr = make_subcontracting_receipt(sco.name)
|
||||||
|
|
||||||
|
for row in scr.supplied_items:
|
||||||
|
self.assertEqual(row.consumed_qty, itemwise_transfer_qty.get(row.rm_item_code) + 1)
|
||||||
|
|
||||||
def test_update_reserved_qty_for_subcontracting(self):
|
def test_update_reserved_qty_for_subcontracting(self):
|
||||||
# Create RM Material Receipt
|
# Create RM Material Receipt
|
||||||
make_stock_entry(target="_Test Warehouse - _TC", item_code="_Test Item", qty=10, basic_rate=100)
|
make_stock_entry(target="_Test Warehouse - _TC", item_code="_Test Item", qty=10, basic_rate=100)
|
||||||
|
|||||||
@@ -51,13 +51,31 @@ frappe.ui.form.on('Subcontracting Receipt', {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
frm.set_query("expense_account", "items", function () {
|
frm.set_query('expense_account', 'items', function () {
|
||||||
return {
|
return {
|
||||||
query: "erpnext.controllers.queries.get_expense_account",
|
query: 'erpnext.controllers.queries.get_expense_account',
|
||||||
filters: { 'company': frm.doc.company }
|
filters: { 'company': frm.doc.company }
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
frm.set_query('batch_no', 'items', function(doc, cdt, cdn) {
|
||||||
|
var row = locals[cdt][cdn];
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
item: row.item_code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let batch_no_field = frm.get_docfield("items", "batch_no");
|
||||||
|
if (batch_no_field) {
|
||||||
|
batch_no_field.get_route_options_for_new_doc = function(row) {
|
||||||
|
return {
|
||||||
|
"item": row.doc.item_code
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
frappe.db.get_single_value('Buying Settings', 'backflush_raw_materials_of_subcontract_based_on').then(val => {
|
frappe.db.get_single_value('Buying Settings', 'backflush_raw_materials_of_subcontract_based_on').then(val => {
|
||||||
if (val == 'Material Transferred for Subcontract') {
|
if (val == 'Material Transferred for Subcontract') {
|
||||||
frm.fields_dict['supplied_items'].grid.grid_rows.forEach((grid_row) => {
|
frm.fields_dict['supplied_items'].grid.grid_rows.forEach((grid_row) => {
|
||||||
@@ -73,7 +91,7 @@ frappe.ui.form.on('Subcontracting Receipt', {
|
|||||||
|
|
||||||
refresh: (frm) => {
|
refresh: (frm) => {
|
||||||
if (frm.doc.docstatus > 0) {
|
if (frm.doc.docstatus > 0) {
|
||||||
frm.add_custom_button(__("Stock Ledger"), function () {
|
frm.add_custom_button(__('Stock Ledger'), function () {
|
||||||
frappe.route_options = {
|
frappe.route_options = {
|
||||||
voucher_no: frm.doc.name,
|
voucher_no: frm.doc.name,
|
||||||
from_date: frm.doc.posting_date,
|
from_date: frm.doc.posting_date,
|
||||||
@@ -81,8 +99,8 @@ frappe.ui.form.on('Subcontracting Receipt', {
|
|||||||
company: frm.doc.company,
|
company: frm.doc.company,
|
||||||
show_cancelled_entries: frm.doc.docstatus === 2
|
show_cancelled_entries: frm.doc.docstatus === 2
|
||||||
};
|
};
|
||||||
frappe.set_route("query-report", "Stock Ledger");
|
frappe.set_route('query-report', 'Stock Ledger');
|
||||||
}, __("View"));
|
}, __('View'));
|
||||||
|
|
||||||
frm.add_custom_button(__('Accounting Ledger'), function () {
|
frm.add_custom_button(__('Accounting Ledger'), function () {
|
||||||
frappe.route_options = {
|
frappe.route_options = {
|
||||||
@@ -90,11 +108,11 @@ frappe.ui.form.on('Subcontracting Receipt', {
|
|||||||
from_date: frm.doc.posting_date,
|
from_date: frm.doc.posting_date,
|
||||||
to_date: moment(frm.doc.modified).format('YYYY-MM-DD'),
|
to_date: moment(frm.doc.modified).format('YYYY-MM-DD'),
|
||||||
company: frm.doc.company,
|
company: frm.doc.company,
|
||||||
group_by: "Group by Voucher (Consolidated)",
|
group_by: 'Group by Voucher (Consolidated)',
|
||||||
show_cancelled_entries: frm.doc.docstatus === 2
|
show_cancelled_entries: frm.doc.docstatus === 2
|
||||||
};
|
};
|
||||||
frappe.set_route("query-report", "General Ledger");
|
frappe.set_route('query-report', 'General Ledger');
|
||||||
}, __("View"));
|
}, __('View'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!frm.doc.is_return && frm.doc.docstatus == 1 && frm.doc.per_returned < 100) {
|
if (!frm.doc.is_return && frm.doc.docstatus == 1 && frm.doc.per_returned < 100) {
|
||||||
@@ -111,25 +129,25 @@ frappe.ui.form.on('Subcontracting Receipt', {
|
|||||||
frm.add_custom_button(__('Subcontracting Order'), function () {
|
frm.add_custom_button(__('Subcontracting Order'), function () {
|
||||||
if (!frm.doc.supplier) {
|
if (!frm.doc.supplier) {
|
||||||
frappe.throw({
|
frappe.throw({
|
||||||
title: __("Mandatory"),
|
title: __('Mandatory'),
|
||||||
message: __("Please Select a Supplier")
|
message: __('Please Select a Supplier')
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
erpnext.utils.map_current_doc({
|
erpnext.utils.map_current_doc({
|
||||||
method: 'erpnext.subcontracting.doctype.subcontracting_order.subcontracting_order.make_subcontracting_receipt',
|
method: 'erpnext.subcontracting.doctype.subcontracting_order.subcontracting_order.make_subcontracting_receipt',
|
||||||
source_doctype: "Subcontracting Order",
|
source_doctype: 'Subcontracting Order',
|
||||||
target: frm,
|
target: frm,
|
||||||
setters: {
|
setters: {
|
||||||
supplier: frm.doc.supplier,
|
supplier: frm.doc.supplier,
|
||||||
},
|
},
|
||||||
get_query_filters: {
|
get_query_filters: {
|
||||||
docstatus: 1,
|
docstatus: 1,
|
||||||
per_received: ["<", 100],
|
per_received: ['<', 100],
|
||||||
company: frm.doc.company
|
company: frm.doc.company
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, __("Get Items From"));
|
}, __('Get Items From'));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -34,16 +34,18 @@
|
|||||||
</a>
|
</a>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-column col-sm-6">
|
{% if show_pay_button %}
|
||||||
<div class="page-header-actions-block" data-html-block="header-actions">
|
<div class="form-column col-sm-6">
|
||||||
<p>
|
<div class="page-header-actions-block" data-html-block="header-actions">
|
||||||
<a href="/api/method/erpnext.accounts.doctype.payment_request.payment_request.make_payment_request?dn={{ doc.name }}&dt={{ doc.doctype }}&submit_doc=1&order_type=Shopping Cart"
|
<p>
|
||||||
class="btn btn-primary btn-sm" id="pay-for-order">
|
<a href="/api/method/erpnext.accounts.doctype.payment_request.payment_request.make_payment_request?dn={{ doc.name }}&dt={{ doc.doctype }}&submit_doc=1&order_type=Shopping Cart"
|
||||||
{{ _("Pay") }} {{doc.get_formatted("grand_total") }}
|
class="btn btn-primary btn-sm" id="pay-for-order">
|
||||||
</a>
|
{{ _("Pay") }} {{doc.get_formatted("grand_total") }}
|
||||||
</p>
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ def get_context(context):
|
|||||||
)
|
)
|
||||||
context.available_loyalty_points = int(loyalty_program_details.get("loyalty_points"))
|
context.available_loyalty_points = int(loyalty_program_details.get("loyalty_points"))
|
||||||
|
|
||||||
|
context.show_pay_button = frappe.db.get_single_value("Buying Settings", "show_pay_button")
|
||||||
context.show_make_pi_button = False
|
context.show_make_pi_button = False
|
||||||
if context.doc.get("supplier"):
|
if context.doc.get("supplier"):
|
||||||
# show Make Purchase Invoice button based on permission
|
# show Make Purchase Invoice button based on permission
|
||||||
|
|||||||
Reference in New Issue
Block a user