mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-23 06:59:20 +00:00
Merge branch 'develop' into version-15-beta
This commit is contained in:
8
.github/workflows/server-tests-mariadb.yml
vendored
8
.github/workflows/server-tests-mariadb.yml
vendored
@@ -7,11 +7,9 @@ on:
|
|||||||
- '**.css'
|
- '**.css'
|
||||||
- '**.md'
|
- '**.md'
|
||||||
- '**.html'
|
- '**.html'
|
||||||
push:
|
schedule:
|
||||||
branches: [ develop ]
|
# Run everday at midnight UTC / 5:30 IST
|
||||||
paths-ignore:
|
- cron: "0 0 * * *"
|
||||||
- '**.js'
|
|
||||||
- '**.md'
|
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs:
|
inputs:
|
||||||
user:
|
user:
|
||||||
|
|||||||
@@ -4,18 +4,19 @@
|
|||||||
"creation": "2020-07-17 11:25:34.593061",
|
"creation": "2020-07-17 11:25:34.593061",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Dashboard Chart",
|
"doctype": "Dashboard Chart",
|
||||||
"dynamic_filters_json": "{\"company\":\"frappe.defaults.get_user_default(\\\"Company\\\")\",\"from_fiscal_year\":\"frappe.sys_defaults.fiscal_year\",\"to_fiscal_year\":\"frappe.sys_defaults.fiscal_year\"}",
|
"dynamic_filters_json": "{\"company\":\"frappe.defaults.get_user_default(\\\"Company\\\")\",\"from_fiscal_year\":\"erpnext.utils.get_fiscal_year()\",\"to_fiscal_year\":\"erpnext.utils.get_fiscal_year()\"}",
|
||||||
"filters_json": "{\"period\":\"Monthly\",\"budget_against\":\"Cost Center\",\"show_cumulative\":0}",
|
"filters_json": "{\"period\":\"Monthly\",\"budget_against\":\"Cost Center\",\"show_cumulative\":0}",
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_public": 1,
|
"is_public": 1,
|
||||||
"is_standard": 1,
|
"is_standard": 1,
|
||||||
"modified": "2020-07-22 12:24:49.144210",
|
"modified": "2023-07-19 13:13:13.307073",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Budget Variance",
|
"name": "Budget Variance",
|
||||||
"number_of_groups": 0,
|
"number_of_groups": 0,
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"report_name": "Budget Variance Report",
|
"report_name": "Budget Variance Report",
|
||||||
|
"roles": [],
|
||||||
"timeseries": 0,
|
"timeseries": 0,
|
||||||
"type": "Bar",
|
"type": "Bar",
|
||||||
"use_report_chart": 1,
|
"use_report_chart": 1,
|
||||||
|
|||||||
@@ -4,18 +4,19 @@
|
|||||||
"creation": "2020-07-17 11:25:34.448572",
|
"creation": "2020-07-17 11:25:34.448572",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Dashboard Chart",
|
"doctype": "Dashboard Chart",
|
||||||
"dynamic_filters_json": "{\"company\":\"frappe.defaults.get_user_default(\\\"Company\\\")\",\"from_fiscal_year\":\"frappe.sys_defaults.fiscal_year\",\"to_fiscal_year\":\"frappe.sys_defaults.fiscal_year\"}",
|
"dynamic_filters_json": "{\"company\":\"frappe.defaults.get_user_default(\\\"Company\\\")\",\"from_fiscal_year\":\"erpnext.utils.get_fiscal_year()\",\"to_fiscal_year\":\"erpnext.utils.get_fiscal_year()\"}",
|
||||||
"filters_json": "{\"filter_based_on\":\"Fiscal Year\",\"period_start_date\":\"2020-04-01\",\"period_end_date\":\"2021-03-31\",\"periodicity\":\"Yearly\",\"include_default_book_entries\":1}",
|
"filters_json": "{\"filter_based_on\":\"Fiscal Year\",\"period_start_date\":\"2020-04-01\",\"period_end_date\":\"2021-03-31\",\"periodicity\":\"Yearly\",\"include_default_book_entries\":1}",
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_public": 1,
|
"is_public": 1,
|
||||||
"is_standard": 1,
|
"is_standard": 1,
|
||||||
"modified": "2020-07-22 12:33:48.888943",
|
"modified": "2023-07-19 13:08:56.470390",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Profit and Loss",
|
"name": "Profit and Loss",
|
||||||
"number_of_groups": 0,
|
"number_of_groups": 0,
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"report_name": "Profit and Loss Statement",
|
"report_name": "Profit and Loss Statement",
|
||||||
|
"roles": [],
|
||||||
"timeseries": 0,
|
"timeseries": 0,
|
||||||
"type": "Bar",
|
"type": "Bar",
|
||||||
"use_report_chart": 1,
|
"use_report_chart": 1,
|
||||||
|
|||||||
@@ -14,10 +14,8 @@ class AccountClosingBalance(Document):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def make_closing_entries(closing_entries, voucher_name):
|
def make_closing_entries(closing_entries, voucher_name, company, closing_date):
|
||||||
accounting_dimensions = get_accounting_dimensions()
|
accounting_dimensions = get_accounting_dimensions()
|
||||||
company = closing_entries[0].get("company")
|
|
||||||
closing_date = closing_entries[0].get("closing_date")
|
|
||||||
|
|
||||||
previous_closing_entries = get_previous_closing_entries(
|
previous_closing_entries = get_previous_closing_entries(
|
||||||
company, closing_date, accounting_dimensions
|
company, closing_date, accounting_dimensions
|
||||||
|
|||||||
@@ -20,5 +20,11 @@ frappe.ui.form.on('Accounting Period', {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
frm.set_query("document_type", "closed_documents", () => {
|
||||||
|
return {
|
||||||
|
query: "erpnext.controllers.queries.get_doctypes_for_closing",
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,6 +11,10 @@ class OverlapError(frappe.ValidationError):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClosedAccountingPeriod(frappe.ValidationError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class AccountingPeriod(Document):
|
class AccountingPeriod(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_overlap()
|
self.validate_overlap()
|
||||||
@@ -65,3 +69,42 @@ class AccountingPeriod(Document):
|
|||||||
"closed_documents",
|
"closed_documents",
|
||||||
{"document_type": doctype_for_closing.document_type, "closed": doctype_for_closing.closed},
|
{"document_type": doctype_for_closing.document_type, "closed": doctype_for_closing.closed},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def validate_accounting_period_on_doc_save(doc, method=None):
|
||||||
|
if doc.doctype == "Bank Clearance":
|
||||||
|
return
|
||||||
|
elif doc.doctype == "Asset":
|
||||||
|
if doc.is_existing_asset:
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
date = doc.available_for_use_date
|
||||||
|
elif doc.doctype == "Asset Repair":
|
||||||
|
date = doc.completion_date
|
||||||
|
else:
|
||||||
|
date = doc.posting_date
|
||||||
|
|
||||||
|
ap = frappe.qb.DocType("Accounting Period")
|
||||||
|
cd = frappe.qb.DocType("Closed Document")
|
||||||
|
|
||||||
|
accounting_period = (
|
||||||
|
frappe.qb.from_(ap)
|
||||||
|
.from_(cd)
|
||||||
|
.select(ap.name)
|
||||||
|
.where(
|
||||||
|
(ap.name == cd.parent)
|
||||||
|
& (ap.company == doc.company)
|
||||||
|
& (cd.closed == 1)
|
||||||
|
& (cd.document_type == doc.doctype)
|
||||||
|
& (date >= ap.start_date)
|
||||||
|
& (date <= ap.end_date)
|
||||||
|
)
|
||||||
|
).run(as_dict=1)
|
||||||
|
|
||||||
|
if accounting_period:
|
||||||
|
frappe.throw(
|
||||||
|
_("You cannot create a {0} within the closed Accounting Period {1}").format(
|
||||||
|
doc.doctype, frappe.bold(accounting_period[0]["name"])
|
||||||
|
),
|
||||||
|
ClosedAccountingPeriod,
|
||||||
|
)
|
||||||
|
|||||||
@@ -6,9 +6,11 @@ import unittest
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe.utils import add_months, nowdate
|
from frappe.utils import add_months, nowdate
|
||||||
|
|
||||||
from erpnext.accounts.doctype.accounting_period.accounting_period import OverlapError
|
from erpnext.accounts.doctype.accounting_period.accounting_period import (
|
||||||
|
ClosedAccountingPeriod,
|
||||||
|
OverlapError,
|
||||||
|
)
|
||||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||||
from erpnext.accounts.general_ledger import ClosedAccountingPeriod
|
|
||||||
|
|
||||||
test_dependencies = ["Item"]
|
test_dependencies = ["Item"]
|
||||||
|
|
||||||
@@ -33,9 +35,9 @@ class TestAccountingPeriod(unittest.TestCase):
|
|||||||
ap1.save()
|
ap1.save()
|
||||||
|
|
||||||
doc = create_sales_invoice(
|
doc = create_sales_invoice(
|
||||||
do_not_submit=1, cost_center="_Test Company - _TC", warehouse="Stores - _TC"
|
do_not_save=1, cost_center="_Test Company - _TC", warehouse="Stores - _TC"
|
||||||
)
|
)
|
||||||
self.assertRaises(ClosedAccountingPeriod, doc.submit)
|
self.assertRaises(ClosedAccountingPeriod, doc.save)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
for d in frappe.get_all("Accounting Period"):
|
for d in frappe.get_all("Accounting Period"):
|
||||||
|
|||||||
@@ -8,17 +8,6 @@ frappe.ui.form.on('Fiscal Year', {
|
|||||||
frappe.datetime.add_days(frappe.defaults.get_default("year_end_date"), 1));
|
frappe.datetime.add_days(frappe.defaults.get_default("year_end_date"), 1));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
refresh: function (frm) {
|
|
||||||
if (!frm.doc.__islocal && (frm.doc.name != frappe.sys_defaults.fiscal_year)) {
|
|
||||||
frm.add_custom_button(__("Set as Default"), () => frm.events.set_as_default(frm));
|
|
||||||
frm.set_intro(__("To set this Fiscal Year as Default, click on 'Set as Default'"));
|
|
||||||
} else {
|
|
||||||
frm.set_intro("");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
set_as_default: function(frm) {
|
|
||||||
return frm.call('set_as_default');
|
|
||||||
},
|
|
||||||
year_start_date: function(frm) {
|
year_start_date: function(frm) {
|
||||||
if (!frm.doc.is_short_year) {
|
if (!frm.doc.is_short_year) {
|
||||||
let year_end_date =
|
let year_end_date =
|
||||||
|
|||||||
@@ -4,28 +4,12 @@
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from dateutil.relativedelta import relativedelta
|
from dateutil.relativedelta import relativedelta
|
||||||
from frappe import _, msgprint
|
from frappe import _
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils import add_days, add_years, cstr, getdate
|
from frappe.utils import add_days, add_years, cstr, getdate
|
||||||
|
|
||||||
|
|
||||||
class FiscalYear(Document):
|
class FiscalYear(Document):
|
||||||
@frappe.whitelist()
|
|
||||||
def set_as_default(self):
|
|
||||||
frappe.db.set_single_value("Global Defaults", "current_fiscal_year", self.name)
|
|
||||||
global_defaults = frappe.get_doc("Global Defaults")
|
|
||||||
global_defaults.check_permission("write")
|
|
||||||
global_defaults.on_update()
|
|
||||||
|
|
||||||
# clear cache
|
|
||||||
frappe.clear_cache()
|
|
||||||
|
|
||||||
msgprint(
|
|
||||||
_(
|
|
||||||
"{0} is now the default Fiscal Year. Please refresh your browser for the change to take effect."
|
|
||||||
).format(self.name)
|
|
||||||
)
|
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_dates()
|
self.validate_dates()
|
||||||
self.validate_overlap()
|
self.validate_overlap()
|
||||||
@@ -68,13 +52,6 @@ class FiscalYear(Document):
|
|||||||
frappe.cache().delete_value("fiscal_years")
|
frappe.cache().delete_value("fiscal_years")
|
||||||
|
|
||||||
def on_trash(self):
|
def on_trash(self):
|
||||||
global_defaults = frappe.get_doc("Global Defaults")
|
|
||||||
if global_defaults.current_fiscal_year == self.name:
|
|
||||||
frappe.throw(
|
|
||||||
_(
|
|
||||||
"You cannot delete Fiscal Year {0}. Fiscal Year {0} is set as default in Global Settings"
|
|
||||||
).format(self.name)
|
|
||||||
)
|
|
||||||
frappe.cache().delete_value("fiscal_years")
|
frappe.cache().delete_value("fiscal_years")
|
||||||
|
|
||||||
def validate_overlap(self):
|
def validate_overlap(self):
|
||||||
|
|||||||
@@ -408,6 +408,15 @@ class JournalEntry(AccountsController):
|
|||||||
d.idx, d.account
|
d.idx, d.account
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
elif (
|
||||||
|
d.party_type
|
||||||
|
and frappe.db.get_value("Party Type", d.party_type, "account_type") != account_type
|
||||||
|
):
|
||||||
|
frappe.throw(
|
||||||
|
_("Row {0}: Account {1} and Party Type {2} have different account types").format(
|
||||||
|
d.idx, d.account, d.party_type
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
def check_credit_limit(self):
|
def check_credit_limit(self):
|
||||||
customers = list(
|
customers = list(
|
||||||
|
|||||||
@@ -226,10 +226,12 @@ class PaymentEntry(AccountsController):
|
|||||||
latest_lookup = {}
|
latest_lookup = {}
|
||||||
for d in latest_references:
|
for d in latest_references:
|
||||||
d = frappe._dict(d)
|
d = frappe._dict(d)
|
||||||
latest_lookup.update({(d.voucher_type, d.voucher_no): d})
|
latest_lookup.setdefault((d.voucher_type, d.voucher_no), frappe._dict())[d.payment_term] = d
|
||||||
|
|
||||||
for d in self.get("references"):
|
for d in self.get("references"):
|
||||||
latest = latest_lookup.get((d.reference_doctype, d.reference_name))
|
latest = (latest_lookup.get((d.reference_doctype, d.reference_name)) or frappe._dict()).get(
|
||||||
|
d.payment_term
|
||||||
|
)
|
||||||
|
|
||||||
# The reference has already been fully paid
|
# The reference has already been fully paid
|
||||||
if not latest:
|
if not latest:
|
||||||
@@ -251,6 +253,18 @@ class PaymentEntry(AccountsController):
|
|||||||
if (flt(d.allocated_amount)) > 0 and flt(d.allocated_amount) > flt(latest.outstanding_amount):
|
if (flt(d.allocated_amount)) > 0 and flt(d.allocated_amount) > flt(latest.outstanding_amount):
|
||||||
frappe.throw(fail_message.format(d.idx))
|
frappe.throw(fail_message.format(d.idx))
|
||||||
|
|
||||||
|
if d.payment_term and (
|
||||||
|
(flt(d.allocated_amount)) > 0
|
||||||
|
and flt(d.allocated_amount) > flt(latest.payment_term_outstanding)
|
||||||
|
):
|
||||||
|
frappe.throw(
|
||||||
|
_(
|
||||||
|
"Row #{0}: Allocated amount:{1} is greater than outstanding amount:{2} for Payment Term {3}"
|
||||||
|
).format(
|
||||||
|
d.idx, d.allocated_amount, latest.payment_term_outstanding, d.payment_term
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
# Check for negative outstanding invoices as well
|
# Check for negative outstanding invoices as well
|
||||||
if flt(d.allocated_amount) < 0 and flt(d.allocated_amount) < flt(latest.outstanding_amount):
|
if flt(d.allocated_amount) < 0 and flt(d.allocated_amount) < flt(latest.outstanding_amount):
|
||||||
frappe.throw(fail_message.format(d.idx))
|
frappe.throw(fail_message.format(d.idx))
|
||||||
@@ -1500,7 +1514,9 @@ def get_outstanding_reference_documents(args, validate=False):
|
|||||||
accounting_dimensions=accounting_dimensions_filter,
|
accounting_dimensions=accounting_dimensions_filter,
|
||||||
)
|
)
|
||||||
|
|
||||||
outstanding_invoices = split_invoices_based_on_payment_terms(outstanding_invoices)
|
outstanding_invoices = split_invoices_based_on_payment_terms(
|
||||||
|
outstanding_invoices, args.get("company")
|
||||||
|
)
|
||||||
|
|
||||||
for d in outstanding_invoices:
|
for d in outstanding_invoices:
|
||||||
d["exchange_rate"] = 1
|
d["exchange_rate"] = 1
|
||||||
@@ -1560,8 +1576,27 @@ def get_outstanding_reference_documents(args, validate=False):
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
def split_invoices_based_on_payment_terms(outstanding_invoices):
|
def split_invoices_based_on_payment_terms(outstanding_invoices, company):
|
||||||
invoice_ref_based_on_payment_terms = {}
|
invoice_ref_based_on_payment_terms = {}
|
||||||
|
|
||||||
|
company_currency = (
|
||||||
|
frappe.db.get_value("Company", company, "default_currency") if company else None
|
||||||
|
)
|
||||||
|
exc_rates = frappe._dict()
|
||||||
|
for doctype in ["Sales Invoice", "Purchase Invoice"]:
|
||||||
|
invoices = [x.voucher_no for x in outstanding_invoices if x.voucher_type == doctype]
|
||||||
|
for x in frappe.db.get_all(
|
||||||
|
doctype,
|
||||||
|
filters={"name": ["in", invoices]},
|
||||||
|
fields=["name", "currency", "conversion_rate", "party_account_currency"],
|
||||||
|
):
|
||||||
|
exc_rates[x.name] = frappe._dict(
|
||||||
|
conversion_rate=x.conversion_rate,
|
||||||
|
currency=x.currency,
|
||||||
|
party_account_currency=x.party_account_currency,
|
||||||
|
company_currency=company_currency,
|
||||||
|
)
|
||||||
|
|
||||||
for idx, d in enumerate(outstanding_invoices):
|
for idx, d in enumerate(outstanding_invoices):
|
||||||
if d.voucher_type in ["Sales Invoice", "Purchase Invoice"]:
|
if d.voucher_type in ["Sales Invoice", "Purchase Invoice"]:
|
||||||
payment_term_template = frappe.db.get_value(
|
payment_term_template = frappe.db.get_value(
|
||||||
@@ -1578,6 +1613,14 @@ def split_invoices_based_on_payment_terms(outstanding_invoices):
|
|||||||
|
|
||||||
for payment_term in payment_schedule:
|
for payment_term in payment_schedule:
|
||||||
if payment_term.outstanding > 0.1:
|
if payment_term.outstanding > 0.1:
|
||||||
|
doc_details = exc_rates.get(payment_term.parent, None)
|
||||||
|
is_multi_currency_acc = (doc_details.currency != doc_details.company_currency) and (
|
||||||
|
doc_details.party_account_currency != doc_details.company_currency
|
||||||
|
)
|
||||||
|
payment_term_outstanding = flt(payment_term.outstanding)
|
||||||
|
if not is_multi_currency_acc:
|
||||||
|
payment_term_outstanding = doc_details.conversion_rate * flt(payment_term.outstanding)
|
||||||
|
|
||||||
invoice_ref_based_on_payment_terms.setdefault(idx, [])
|
invoice_ref_based_on_payment_terms.setdefault(idx, [])
|
||||||
invoice_ref_based_on_payment_terms[idx].append(
|
invoice_ref_based_on_payment_terms[idx].append(
|
||||||
frappe._dict(
|
frappe._dict(
|
||||||
@@ -1589,6 +1632,7 @@ def split_invoices_based_on_payment_terms(outstanding_invoices):
|
|||||||
"posting_date": d.posting_date,
|
"posting_date": d.posting_date,
|
||||||
"invoice_amount": flt(d.invoice_amount),
|
"invoice_amount": flt(d.invoice_amount),
|
||||||
"outstanding_amount": flt(d.outstanding_amount),
|
"outstanding_amount": flt(d.outstanding_amount),
|
||||||
|
"payment_term_outstanding": payment_term_outstanding,
|
||||||
"payment_amount": payment_term.payment_amount,
|
"payment_amount": payment_term.payment_amount,
|
||||||
"payment_term": payment_term.payment_term,
|
"payment_term": payment_term.payment_term,
|
||||||
"account": d.account,
|
"account": d.account,
|
||||||
@@ -2371,6 +2415,7 @@ def get_reference_as_per_payment_terms(
|
|||||||
"due_date": doc.get("due_date"),
|
"due_date": doc.get("due_date"),
|
||||||
"total_amount": grand_total,
|
"total_amount": grand_total,
|
||||||
"outstanding_amount": outstanding_amount,
|
"outstanding_amount": outstanding_amount,
|
||||||
|
"payment_term_outstanding": payment_term_outstanding,
|
||||||
"payment_term": payment_term.payment_term,
|
"payment_term": payment_term.payment_term,
|
||||||
"allocated_amount": payment_term_outstanding,
|
"allocated_amount": payment_term_outstanding,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,6 +133,8 @@ class PeriodClosingVoucher(AccountsController):
|
|||||||
gl_entries=gl_entries,
|
gl_entries=gl_entries,
|
||||||
closing_entries=closing_entries,
|
closing_entries=closing_entries,
|
||||||
voucher_name=self.name,
|
voucher_name=self.name,
|
||||||
|
company=self.company,
|
||||||
|
closing_date=self.posting_date,
|
||||||
queue="long",
|
queue="long",
|
||||||
)
|
)
|
||||||
frappe.msgprint(
|
frappe.msgprint(
|
||||||
@@ -140,7 +142,7 @@ class PeriodClosingVoucher(AccountsController):
|
|||||||
alert=True,
|
alert=True,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
process_gl_entries(gl_entries, closing_entries, voucher_name=self.name)
|
process_gl_entries(gl_entries, closing_entries, self.name, self.company, self.posting_date)
|
||||||
|
|
||||||
def get_grouped_gl_entries(self, get_opening_entries=False):
|
def get_grouped_gl_entries(self, get_opening_entries=False):
|
||||||
closing_entries = []
|
closing_entries = []
|
||||||
@@ -321,7 +323,7 @@ class PeriodClosingVoucher(AccountsController):
|
|||||||
return query.run(as_dict=1)
|
return query.run(as_dict=1)
|
||||||
|
|
||||||
|
|
||||||
def process_gl_entries(gl_entries, closing_entries, voucher_name=None):
|
def process_gl_entries(gl_entries, closing_entries, voucher_name, company, closing_date):
|
||||||
from erpnext.accounts.doctype.account_closing_balance.account_closing_balance import (
|
from erpnext.accounts.doctype.account_closing_balance.account_closing_balance import (
|
||||||
make_closing_entries,
|
make_closing_entries,
|
||||||
)
|
)
|
||||||
@@ -329,7 +331,7 @@ def process_gl_entries(gl_entries, closing_entries, voucher_name=None):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
make_gl_entries(gl_entries, merge_entries=False)
|
make_gl_entries(gl_entries, merge_entries=False)
|
||||||
make_closing_entries(gl_entries + closing_entries, voucher_name=voucher_name)
|
make_closing_entries(gl_entries + closing_entries, voucher_name, company, closing_date)
|
||||||
frappe.db.set_value(
|
frappe.db.set_value(
|
||||||
"Period Closing Voucher", gl_entries[0].get("voucher_no"), "gle_processing_status", "Completed"
|
"Period Closing Voucher", gl_entries[0].get("voucher_no"), "gle_processing_status", "Completed"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -13,14 +13,11 @@ import erpnext
|
|||||||
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
|
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
|
||||||
get_accounting_dimensions,
|
get_accounting_dimensions,
|
||||||
)
|
)
|
||||||
|
from erpnext.accounts.doctype.accounting_period.accounting_period import ClosedAccountingPeriod
|
||||||
from erpnext.accounts.doctype.budget.budget import validate_expense_against_budget
|
from erpnext.accounts.doctype.budget.budget import validate_expense_against_budget
|
||||||
from erpnext.accounts.utils import create_payment_ledger_entry
|
from erpnext.accounts.utils import create_payment_ledger_entry
|
||||||
|
|
||||||
|
|
||||||
class ClosedAccountingPeriod(frappe.ValidationError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def make_gl_entries(
|
def make_gl_entries(
|
||||||
gl_map,
|
gl_map,
|
||||||
cancel=False,
|
cancel=False,
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
|
|||||||
"label": __("Start Year"),
|
"label": __("Start Year"),
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"options": "Fiscal Year",
|
"options": "Fiscal Year",
|
||||||
"default": frappe.defaults.get_user_default("fiscal_year"),
|
"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
on_change: () => {
|
on_change: () => {
|
||||||
frappe.model.with_doc("Fiscal Year", frappe.query_report.get_filter_value('from_fiscal_year'), function(r) {
|
frappe.model.with_doc("Fiscal Year", frappe.query_report.get_filter_value('from_fiscal_year'), function(r) {
|
||||||
@@ -65,7 +65,7 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
|
|||||||
"label": __("End Year"),
|
"label": __("End Year"),
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"options": "Fiscal Year",
|
"options": "Fiscal Year",
|
||||||
"default": frappe.defaults.get_user_default("fiscal_year"),
|
"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
on_change: () => {
|
on_change: () => {
|
||||||
frappe.model.with_doc("Fiscal Year", frappe.query_report.get_filter_value('to_fiscal_year'), function(r) {
|
frappe.model.with_doc("Fiscal Year", frappe.query_report.get_filter_value('to_fiscal_year'), function(r) {
|
||||||
@@ -139,7 +139,7 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
|
|||||||
return value;
|
return value;
|
||||||
},
|
},
|
||||||
onload: function() {
|
onload: function() {
|
||||||
let fiscal_year = frappe.defaults.get_user_default("fiscal_year")
|
let fiscal_year = erpnext.utils.get_fiscal_year(frappe.datetime.get_today());
|
||||||
|
|
||||||
frappe.model.with_doc("Fiscal Year", fiscal_year, function(r) {
|
frappe.model.with_doc("Fiscal Year", fiscal_year, function(r) {
|
||||||
var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
|
var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ function get_filters() {
|
|||||||
"label": __("Start Year"),
|
"label": __("Start Year"),
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"options": "Fiscal Year",
|
"options": "Fiscal Year",
|
||||||
"default": frappe.defaults.get_user_default("fiscal_year"),
|
"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -56,7 +56,7 @@ function get_filters() {
|
|||||||
"label": __("End Year"),
|
"label": __("End Year"),
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"options": "Fiscal Year",
|
"options": "Fiscal Year",
|
||||||
"default": frappe.defaults.get_user_default("fiscal_year"),
|
"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -100,7 +100,7 @@ frappe.query_reports["Deferred Revenue and Expense"] = {
|
|||||||
return default_formatter(value, row, column, data);
|
return default_formatter(value, row, column, data);
|
||||||
},
|
},
|
||||||
onload: function(report){
|
onload: function(report){
|
||||||
let fiscal_year = frappe.defaults.get_user_default("fiscal_year");
|
let fiscal_year = erpnext.utils.get_fiscal_year(frappe.datetime.get_today());
|
||||||
|
|
||||||
frappe.model.with_doc("Fiscal Year", fiscal_year, function(r) {
|
frappe.model.with_doc("Fiscal Year", fiscal_year, function(r) {
|
||||||
var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
|
var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
|
||||||
|
|||||||
@@ -4,9 +4,10 @@
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import _, qb
|
from frappe import _, qb
|
||||||
from frappe.query_builder import Column, functions
|
from frappe.query_builder import Column, functions
|
||||||
from frappe.utils import add_days, date_diff, flt, get_first_day, get_last_day, rounded
|
from frappe.utils import add_days, date_diff, flt, get_first_day, get_last_day, getdate, rounded
|
||||||
|
|
||||||
from erpnext.accounts.report.financial_statements import get_period_list
|
from erpnext.accounts.report.financial_statements import get_period_list
|
||||||
|
from erpnext.accounts.utils import get_fiscal_year
|
||||||
|
|
||||||
|
|
||||||
class Deferred_Item(object):
|
class Deferred_Item(object):
|
||||||
@@ -226,7 +227,7 @@ class Deferred_Revenue_and_Expense_Report(object):
|
|||||||
|
|
||||||
# If no filters are provided, get user defaults
|
# If no filters are provided, get user defaults
|
||||||
if not filters:
|
if not filters:
|
||||||
fiscal_year = frappe.get_doc("Fiscal Year", frappe.defaults.get_user_default("fiscal_year"))
|
fiscal_year = frappe.get_doc("Fiscal Year", get_fiscal_year(date=getdate()))
|
||||||
self.filters = frappe._dict(
|
self.filters = frappe._dict(
|
||||||
{
|
{
|
||||||
"company": frappe.defaults.get_user_default("Company"),
|
"company": frappe.defaults.get_user_default("Company"),
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sal
|
|||||||
from erpnext.accounts.report.deferred_revenue_and_expense.deferred_revenue_and_expense import (
|
from erpnext.accounts.report.deferred_revenue_and_expense.deferred_revenue_and_expense import (
|
||||||
Deferred_Revenue_and_Expense_Report,
|
Deferred_Revenue_and_Expense_Report,
|
||||||
)
|
)
|
||||||
|
from erpnext.accounts.utils import get_fiscal_year
|
||||||
from erpnext.buying.doctype.supplier.test_supplier import create_supplier
|
from erpnext.buying.doctype.supplier.test_supplier import create_supplier
|
||||||
from erpnext.stock.doctype.item.test_item import create_item
|
from erpnext.stock.doctype.item.test_item import create_item
|
||||||
|
|
||||||
@@ -116,7 +117,7 @@ class TestDeferredRevenueAndExpense(unittest.TestCase):
|
|||||||
pda.submit()
|
pda.submit()
|
||||||
|
|
||||||
# execute report
|
# execute report
|
||||||
fiscal_year = frappe.get_doc("Fiscal Year", frappe.defaults.get_user_default("fiscal_year"))
|
fiscal_year = frappe.get_doc("Fiscal Year", get_fiscal_year(date="2021-05-01"))
|
||||||
self.filters = frappe._dict(
|
self.filters = frappe._dict(
|
||||||
{
|
{
|
||||||
"company": frappe.defaults.get_user_default("Company"),
|
"company": frappe.defaults.get_user_default("Company"),
|
||||||
@@ -209,7 +210,7 @@ class TestDeferredRevenueAndExpense(unittest.TestCase):
|
|||||||
pda.submit()
|
pda.submit()
|
||||||
|
|
||||||
# execute report
|
# execute report
|
||||||
fiscal_year = frappe.get_doc("Fiscal Year", frappe.defaults.get_user_default("fiscal_year"))
|
fiscal_year = frappe.get_doc("Fiscal Year", get_fiscal_year(date="2021-05-01"))
|
||||||
self.filters = frappe._dict(
|
self.filters = frappe._dict(
|
||||||
{
|
{
|
||||||
"company": frappe.defaults.get_user_default("Company"),
|
"company": frappe.defaults.get_user_default("Company"),
|
||||||
@@ -297,7 +298,7 @@ class TestDeferredRevenueAndExpense(unittest.TestCase):
|
|||||||
pda.submit()
|
pda.submit()
|
||||||
|
|
||||||
# execute report
|
# execute report
|
||||||
fiscal_year = frappe.get_doc("Fiscal Year", frappe.defaults.get_user_default("fiscal_year"))
|
fiscal_year = frappe.get_doc("Fiscal Year", get_fiscal_year(date="2021-05-01"))
|
||||||
self.filters = frappe._dict(
|
self.filters = frappe._dict(
|
||||||
{
|
{
|
||||||
"company": frappe.defaults.get_user_default("Company"),
|
"company": frappe.defaults.get_user_default("Company"),
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
|
|||||||
"label": __("Fiscal Year"),
|
"label": __("Fiscal Year"),
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"options": "Fiscal Year",
|
"options": "Fiscal Year",
|
||||||
"default": frappe.defaults.get_user_default("fiscal_year"),
|
"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"on_change": function(query_report) {
|
"on_change": function(query_report) {
|
||||||
var fiscal_year = query_report.get_values().fiscal_year;
|
var fiscal_year = query_report.get_values().fiscal_year;
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
|
|||||||
"label": __("Fiscal Year"),
|
"label": __("Fiscal Year"),
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"options": "Fiscal Year",
|
"options": "Fiscal Year",
|
||||||
"default": frappe.defaults.get_user_default("fiscal_year"),
|
"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"on_change": function(query_report) {
|
"on_change": function(query_report) {
|
||||||
var fiscal_year = query_report.get_values().fiscal_year;
|
var fiscal_year = query_report.get_values().fiscal_year;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
|
|||||||
"label": __("Fiscal Year"),
|
"label": __("Fiscal Year"),
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"options": "Fiscal Year",
|
"options": "Fiscal Year",
|
||||||
"default": frappe.defaults.get_user_default("fiscal_year"),
|
"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"on_change": function(query_report) {
|
"on_change": function(query_report) {
|
||||||
var fiscal_year = query_report.get_values().fiscal_year;
|
var fiscal_year = query_report.get_values().fiscal_year;
|
||||||
|
|||||||
@@ -221,7 +221,10 @@ def get_opening_balance(
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
if start_date:
|
if start_date:
|
||||||
opening_balance = opening_balance.where(closing_balance.posting_date >= start_date)
|
opening_balance = opening_balance.where(
|
||||||
|
(closing_balance.posting_date >= start_date)
|
||||||
|
& (closing_balance.posting_date < filters.from_date)
|
||||||
|
)
|
||||||
opening_balance = opening_balance.where(closing_balance.is_opening == "No")
|
opening_balance = opening_balance.where(closing_balance.is_opening == "No")
|
||||||
else:
|
else:
|
||||||
opening_balance = opening_balance.where(
|
opening_balance = opening_balance.where(
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ frappe.query_reports["Trial Balance for Party"] = {
|
|||||||
"label": __("Fiscal Year"),
|
"label": __("Fiscal Year"),
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"options": "Fiscal Year",
|
"options": "Fiscal Year",
|
||||||
"default": frappe.defaults.get_user_default("fiscal_year"),
|
"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"on_change": function(query_report) {
|
"on_change": function(query_report) {
|
||||||
var fiscal_year = query_report.get_values().fiscal_year;
|
var fiscal_year = query_report.get_values().fiscal_year;
|
||||||
|
|||||||
@@ -1110,6 +1110,11 @@ def get_autoname_with_number(number_value, doc_title, company):
|
|||||||
return " - ".join(parts)
|
return " - ".join(parts)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_naming_series_variable(doc, variable):
|
||||||
|
if variable == "FY":
|
||||||
|
return get_fiscal_year(date=doc.get("posting_date"), company=doc.get("company"))[0]
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_coa(doctype, parent, is_root, chart=None):
|
def get_coa(doctype, parent, is_root, chart=None):
|
||||||
from erpnext.accounts.doctype.account.chart_of_accounts.chart_of_accounts import (
|
from erpnext.accounts.doctype.account.chart_of_accounts.chart_of_accounts import (
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ frappe.query_reports["Fixed Asset Register"] = {
|
|||||||
"label": __("Start Year"),
|
"label": __("Start Year"),
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"options": "Fiscal Year",
|
"options": "Fiscal Year",
|
||||||
"default": frappe.defaults.get_user_default("fiscal_year"),
|
"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
|
||||||
"depends_on": "eval: doc.filter_based_on == 'Fiscal Year'",
|
"depends_on": "eval: doc.filter_based_on == 'Fiscal Year'",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -90,7 +90,7 @@ frappe.query_reports["Fixed Asset Register"] = {
|
|||||||
"label": __("End Year"),
|
"label": __("End Year"),
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"options": "Fiscal Year",
|
"options": "Fiscal Year",
|
||||||
"default": frappe.defaults.get_user_default("fiscal_year"),
|
"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
|
||||||
"depends_on": "eval: doc.filter_based_on == 'Fiscal Year'",
|
"depends_on": "eval: doc.filter_based_on == 'Fiscal Year'",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,18 +5,19 @@
|
|||||||
"custom_options": "{\"type\": \"line\", \"axisOptions\": {\"shortenYAxisNumbers\": 1}, \"tooltipOptions\": {}, \"lineOptions\": {\"regionFill\": 1}}",
|
"custom_options": "{\"type\": \"line\", \"axisOptions\": {\"shortenYAxisNumbers\": 1}, \"tooltipOptions\": {}, \"lineOptions\": {\"regionFill\": 1}}",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Dashboard Chart",
|
"doctype": "Dashboard Chart",
|
||||||
"dynamic_filters_json": "{\"company\":\"frappe.defaults.get_user_default(\\\"Company\\\")\",\"fiscal_year\":\"frappe.sys_defaults.fiscal_year\"}",
|
"dynamic_filters_json": "{\"company\":\"frappe.defaults.get_user_default(\\\"Company\\\")\",\"fiscal_year\":\"erpnext.utils.get_fiscal_year()\"}",
|
||||||
"filters_json": "{\"period\":\"Monthly\",\"period_based_on\":\"posting_date\",\"based_on\":\"Item\"}",
|
"filters_json": "{\"period\":\"Monthly\",\"period_based_on\":\"posting_date\",\"based_on\":\"Item\"}",
|
||||||
"idx": 0,
|
"idx": 1,
|
||||||
"is_public": 1,
|
"is_public": 1,
|
||||||
"is_standard": 1,
|
"is_standard": 1,
|
||||||
"modified": "2020-07-21 16:13:25.092287",
|
"modified": "2023-07-19 13:06:42.937941",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Purchase Order Trends",
|
"name": "Purchase Order Trends",
|
||||||
"number_of_groups": 0,
|
"number_of_groups": 0,
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"report_name": "Purchase Order Trends",
|
"report_name": "Purchase Order Trends",
|
||||||
|
"roles": [],
|
||||||
"timeseries": 0,
|
"timeseries": 0,
|
||||||
"type": "Line",
|
"type": "Line",
|
||||||
"use_report_chart": 1,
|
"use_report_chart": 1,
|
||||||
|
|||||||
@@ -4,18 +4,19 @@
|
|||||||
"creation": "2020-07-20 21:01:02.329519",
|
"creation": "2020-07-20 21:01:02.329519",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Dashboard Chart",
|
"doctype": "Dashboard Chart",
|
||||||
"dynamic_filters_json": "{\"company\":\"frappe.defaults.get_user_default(\\\"Company\\\")\",\"fiscal_year\":\"frappe.sys_defaults.fiscal_year\"}",
|
"dynamic_filters_json": "{\"company\":\"frappe.defaults.get_user_default(\\\"Company\\\")\",\"fiscal_year\":\"erpnext.utils.get_fiscal_year()\"}",
|
||||||
"filters_json": "{\"period\":\"Monthly\",\"period_based_on\":\"posting_date\",\"based_on\":\"Supplier\"}",
|
"filters_json": "{\"period\":\"Monthly\",\"period_based_on\":\"posting_date\",\"based_on\":\"Supplier\"}",
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_public": 1,
|
"is_public": 1,
|
||||||
"is_standard": 1,
|
"is_standard": 1,
|
||||||
"modified": "2020-07-22 12:43:40.829652",
|
"modified": "2023-07-19 13:07:41.753556",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Top Suppliers",
|
"name": "Top Suppliers",
|
||||||
"number_of_groups": 0,
|
"number_of_groups": 0,
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"report_name": "Purchase Receipt Trends",
|
"report_name": "Purchase Receipt Trends",
|
||||||
|
"roles": [],
|
||||||
"timeseries": 0,
|
"timeseries": 0,
|
||||||
"type": "Bar",
|
"type": "Bar",
|
||||||
"use_report_chart": 1,
|
"use_report_chart": 1,
|
||||||
|
|||||||
@@ -822,6 +822,15 @@ def get_purchase_invoices(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
return frappe.db.sql(query, filters)
|
return frappe.db.sql(query, filters)
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
@frappe.validate_and_sanitize_search_inputs
|
||||||
|
def get_doctypes_for_closing(doctype, txt, searchfield, start, page_len, filters):
|
||||||
|
doctypes = frappe.get_hooks("period_closing_doctypes")
|
||||||
|
if txt:
|
||||||
|
doctypes = [d for d in doctypes if txt.lower() in d.lower()]
|
||||||
|
return [(d,) for d in set(doctypes)]
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
@frappe.validate_and_sanitize_search_inputs
|
@frappe.validate_and_sanitize_search_inputs
|
||||||
def get_tax_template(doctype, txt, searchfield, start, page_len, filters):
|
def get_tax_template(doctype, txt, searchfield, start, page_len, filters):
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ update_website_context = [
|
|||||||
my_account_context = "erpnext.e_commerce.shopping_cart.utils.update_my_account_context"
|
my_account_context = "erpnext.e_commerce.shopping_cart.utils.update_my_account_context"
|
||||||
webform_list_context = "erpnext.controllers.website_list_for_contact.get_webform_list_context"
|
webform_list_context = "erpnext.controllers.website_list_for_contact.get_webform_list_context"
|
||||||
|
|
||||||
calendars = ["Task", "Work Order", "Leave Application", "Sales Order", "Holiday List", "ToDo"]
|
calendars = ["Task", "Work Order", "Sales Order", "Holiday List", "ToDo"]
|
||||||
|
|
||||||
website_generators = ["Item Group", "Website Item", "BOM", "Sales Partner"]
|
website_generators = ["Item Group", "Website Item", "BOM", "Sales Partner"]
|
||||||
|
|
||||||
@@ -285,10 +285,34 @@ standard_queries = {
|
|||||||
"Customer": "erpnext.controllers.queries.customer_query",
|
"Customer": "erpnext.controllers.queries.customer_query",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
period_closing_doctypes = [
|
||||||
|
"Sales Invoice",
|
||||||
|
"Purchase Invoice",
|
||||||
|
"Journal Entry",
|
||||||
|
"Bank Clearance",
|
||||||
|
"Stock Entry",
|
||||||
|
"Dunning",
|
||||||
|
"Invoice Discounting",
|
||||||
|
"Payment Entry",
|
||||||
|
"Period Closing Voucher",
|
||||||
|
"Process Deferred Accounting",
|
||||||
|
"Asset",
|
||||||
|
"Asset Capitalization",
|
||||||
|
"Asset Repair",
|
||||||
|
"Delivery Note",
|
||||||
|
"Landed Cost Voucher",
|
||||||
|
"Purchase Receipt",
|
||||||
|
"Stock Reconciliation",
|
||||||
|
"Subcontracting Receipt",
|
||||||
|
]
|
||||||
|
|
||||||
doc_events = {
|
doc_events = {
|
||||||
"*": {
|
"*": {
|
||||||
"validate": "erpnext.support.doctype.service_level_agreement.service_level_agreement.apply",
|
"validate": "erpnext.support.doctype.service_level_agreement.service_level_agreement.apply",
|
||||||
},
|
},
|
||||||
|
tuple(period_closing_doctypes): {
|
||||||
|
"validate": "erpnext.accounts.doctype.accounting_period.accounting_period.validate_accounting_period_on_doc_save",
|
||||||
|
},
|
||||||
"Stock Entry": {
|
"Stock Entry": {
|
||||||
"on_submit": "erpnext.stock.doctype.material_request.material_request.update_completed_and_requested_qty",
|
"on_submit": "erpnext.stock.doctype.material_request.material_request.update_completed_and_requested_qty",
|
||||||
"on_cancel": "erpnext.stock.doctype.material_request.material_request.update_completed_and_requested_qty",
|
"on_cancel": "erpnext.stock.doctype.material_request.material_request.update_completed_and_requested_qty",
|
||||||
@@ -354,6 +378,11 @@ doc_events = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# function should expect the variable and doc as arguments
|
||||||
|
naming_series_variables = {
|
||||||
|
"FY": "erpnext.accounts.utils.parse_naming_series_variable",
|
||||||
|
}
|
||||||
|
|
||||||
# On cancel event Payment Entry will be exempted and all linked submittable doctype will get cancelled.
|
# On cancel event Payment Entry will be exempted and all linked submittable doctype will get cancelled.
|
||||||
# to maintain data integrity we exempted payment entry. it will un-link when sales invoice get cancelled.
|
# to maintain data integrity we exempted payment entry. it will un-link when sales invoice get cancelled.
|
||||||
# if payment entry not in auto cancel exempted doctypes it will cancel payment entry.
|
# if payment entry not in auto cancel exempted doctypes it will cancel payment entry.
|
||||||
@@ -459,15 +488,6 @@ advance_payment_doctypes = ["Sales Order", "Purchase Order"]
|
|||||||
|
|
||||||
invoice_doctypes = ["Sales Invoice", "Purchase Invoice"]
|
invoice_doctypes = ["Sales Invoice", "Purchase Invoice"]
|
||||||
|
|
||||||
period_closing_doctypes = [
|
|
||||||
"Sales Invoice",
|
|
||||||
"Purchase Invoice",
|
|
||||||
"Journal Entry",
|
|
||||||
"Bank Clearance",
|
|
||||||
"Asset",
|
|
||||||
"Stock Entry",
|
|
||||||
]
|
|
||||||
|
|
||||||
bank_reconciliation_doctypes = [
|
bank_reconciliation_doctypes = [
|
||||||
"Payment Entry",
|
"Payment Entry",
|
||||||
"Journal Entry",
|
"Journal Entry",
|
||||||
|
|||||||
@@ -1539,7 +1539,7 @@ def get_reserved_qty_for_production_plan(item_code, warehouse):
|
|||||||
frappe.qb.from_(table)
|
frappe.qb.from_(table)
|
||||||
.inner_join(child)
|
.inner_join(child)
|
||||||
.on(table.name == child.parent)
|
.on(table.name == child.parent)
|
||||||
.select(Sum(child.required_bom_qty * IfNull(child.conversion_factor, 1.0)))
|
.select(Sum(child.quantity * IfNull(child.conversion_factor, 1.0)))
|
||||||
.where(
|
.where(
|
||||||
(table.docstatus == 1)
|
(table.docstatus == 1)
|
||||||
& (child.item_code == item_code)
|
& (child.item_code == item_code)
|
||||||
|
|||||||
@@ -933,6 +933,54 @@ class TestProductionPlan(FrappeTestCase):
|
|||||||
|
|
||||||
self.assertEqual(after_qty, before_qty)
|
self.assertEqual(after_qty, before_qty)
|
||||||
|
|
||||||
|
def test_resered_qty_for_production_plan_for_material_requests_with_multi_UOM(self):
|
||||||
|
from erpnext.stock.utils import get_or_make_bin
|
||||||
|
|
||||||
|
fg_item = make_item(properties={"is_stock_item": 1, "stock_uom": "_Test UOM 1"}).name
|
||||||
|
bom_item = make_item(
|
||||||
|
properties={"is_stock_item": 1, "stock_uom": "_Test UOM 1", "purchase_uom": "Nos"}
|
||||||
|
).name
|
||||||
|
|
||||||
|
if not frappe.db.exists("UOM Conversion Detail", {"parent": bom_item, "uom": "Nos"}):
|
||||||
|
doc = frappe.get_doc("Item", bom_item)
|
||||||
|
doc.append("uoms", {"uom": "Nos", "conversion_factor": 25})
|
||||||
|
doc.save()
|
||||||
|
|
||||||
|
make_bom(item=fg_item, raw_materials=[bom_item], source_warehouse="_Test Warehouse - _TC")
|
||||||
|
|
||||||
|
bin_name = get_or_make_bin(bom_item, "_Test Warehouse - _TC")
|
||||||
|
before_qty = flt(frappe.db.get_value("Bin", bin_name, "reserved_qty_for_production_plan"))
|
||||||
|
|
||||||
|
pln = create_production_plan(
|
||||||
|
item_code=fg_item, planned_qty=100, ignore_existing_ordered_qty=1, stock_uom="_Test UOM 1"
|
||||||
|
)
|
||||||
|
|
||||||
|
for row in pln.mr_items:
|
||||||
|
self.assertEqual(row.uom, "Nos")
|
||||||
|
self.assertEqual(row.quantity, 4)
|
||||||
|
|
||||||
|
reserved_qty = flt(frappe.db.get_value("Bin", bin_name, "reserved_qty_for_production_plan"))
|
||||||
|
self.assertEqual(reserved_qty - before_qty, 100.0)
|
||||||
|
|
||||||
|
pln.submit_material_request = 1
|
||||||
|
pln.make_work_order()
|
||||||
|
|
||||||
|
for work_order in frappe.get_all(
|
||||||
|
"Work Order",
|
||||||
|
fields=["name"],
|
||||||
|
filters={"production_plan": pln.name},
|
||||||
|
):
|
||||||
|
wo_doc = frappe.get_doc("Work Order", work_order.name)
|
||||||
|
wo_doc.source_warehouse = "_Test Warehouse - _TC"
|
||||||
|
wo_doc.wip_warehouse = "_Test Warehouse 1 - _TC"
|
||||||
|
wo_doc.fg_warehouse = "_Test Warehouse - _TC"
|
||||||
|
wo_doc.submit()
|
||||||
|
|
||||||
|
reserved_qty_after_mr = flt(
|
||||||
|
frappe.db.get_value("Bin", bin_name, "reserved_qty_for_production_plan")
|
||||||
|
)
|
||||||
|
self.assertEqual(reserved_qty_after_mr, before_qty)
|
||||||
|
|
||||||
def test_skip_available_qty_for_sub_assembly_items(self):
|
def test_skip_available_qty_for_sub_assembly_items(self):
|
||||||
from erpnext.manufacturing.doctype.bom.test_bom import create_nested_bom
|
from erpnext.manufacturing.doctype.bom.test_bom import create_nested_bom
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ frappe.query_reports["Job Card Summary"] = {
|
|||||||
label: __("Fiscal Year"),
|
label: __("Fiscal Year"),
|
||||||
fieldtype: "Link",
|
fieldtype: "Link",
|
||||||
options: "Fiscal Year",
|
options: "Fiscal Year",
|
||||||
default: frappe.defaults.get_user_default("fiscal_year"),
|
default: erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
|
||||||
reqd: 1,
|
reqd: 1,
|
||||||
on_change: function(query_report) {
|
on_change: function(query_report) {
|
||||||
var fiscal_year = query_report.get_values().fiscal_year;
|
var fiscal_year = query_report.get_values().fiscal_year;
|
||||||
|
|||||||
@@ -334,4 +334,5 @@ erpnext.patches.v14_0.cleanup_workspaces
|
|||||||
erpnext.patches.v15_0.remove_loan_management_module #2023-07-03
|
erpnext.patches.v15_0.remove_loan_management_module #2023-07-03
|
||||||
erpnext.patches.v14_0.set_report_in_process_SOA
|
erpnext.patches.v14_0.set_report_in_process_SOA
|
||||||
erpnext.buying.doctype.supplier.patches.migrate_supplier_portal_users
|
erpnext.buying.doctype.supplier.patches.migrate_supplier_portal_users
|
||||||
|
execute:frappe.defaults.clear_default("fiscal_year")
|
||||||
erpnext.patches.v15_0.remove_exotel_integration
|
erpnext.patches.v15_0.remove_exotel_integration
|
||||||
|
|||||||
@@ -69,7 +69,6 @@ def execute():
|
|||||||
|
|
||||||
entries = gl_entries + closing_entries
|
entries = gl_entries + closing_entries
|
||||||
|
|
||||||
if entries:
|
make_closing_entries(entries, pcv.name, pcv.company, pcv.posting_date)
|
||||||
make_closing_entries(entries, voucher_name=pcv.name)
|
company_wise_order[pcv.company].append(pcv.posting_date)
|
||||||
i += 1
|
i += 1
|
||||||
company_wise_order[pcv.company].append(pcv.posting_date)
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
from contextlib import suppress
|
|
||||||
|
|
||||||
import click
|
import click
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
@@ -13,12 +11,14 @@ def execute():
|
|||||||
if "exotel_integration" in frappe.get_installed_apps():
|
if "exotel_integration" in frappe.get_installed_apps():
|
||||||
return
|
return
|
||||||
|
|
||||||
with suppress(Exception):
|
try:
|
||||||
exotel = frappe.get_doc(SETTINGS_DOCTYPE)
|
exotel = frappe.get_doc(SETTINGS_DOCTYPE)
|
||||||
if exotel.enabled:
|
if exotel.enabled:
|
||||||
notify_existing_users()
|
notify_existing_users()
|
||||||
|
|
||||||
frappe.delete_doc("DocType", SETTINGS_DOCTYPE)
|
frappe.delete_doc("DocType", SETTINGS_DOCTYPE)
|
||||||
|
except Exception:
|
||||||
|
frappe.log_error("Failed to remove Exotel Integration.")
|
||||||
|
|
||||||
|
|
||||||
def notify_existing_users():
|
def notify_existing_users():
|
||||||
|
|||||||
@@ -358,12 +358,14 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
|
|||||||
}
|
}
|
||||||
|
|
||||||
refresh() {
|
refresh() {
|
||||||
|
|
||||||
erpnext.toggle_naming_series();
|
erpnext.toggle_naming_series();
|
||||||
erpnext.hide_company();
|
erpnext.hide_company();
|
||||||
this.set_dynamic_labels();
|
this.set_dynamic_labels();
|
||||||
this.setup_sms();
|
this.setup_sms();
|
||||||
this.setup_quality_inspection();
|
this.setup_quality_inspection();
|
||||||
this.validate_has_items();
|
this.validate_has_items();
|
||||||
|
erpnext.utils.view_serial_batch_nos(this.frm);
|
||||||
}
|
}
|
||||||
|
|
||||||
scan_barcode() {
|
scan_barcode() {
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ erpnext.financial_statements = {
|
|||||||
// dropdown for links to other financial statements
|
// dropdown for links to other financial statements
|
||||||
erpnext.financial_statements.filters = get_filters()
|
erpnext.financial_statements.filters = get_filters()
|
||||||
|
|
||||||
let fiscal_year = frappe.defaults.get_user_default("fiscal_year")
|
let fiscal_year = erpnext.utils.get_fiscal_year(frappe.datetime.get_today());
|
||||||
|
|
||||||
frappe.model.with_doc("Fiscal Year", fiscal_year, function(r) {
|
frappe.model.with_doc("Fiscal Year", fiscal_year, function(r) {
|
||||||
var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
|
var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
|
||||||
@@ -137,7 +137,7 @@ function get_filters() {
|
|||||||
"label": __("Start Year"),
|
"label": __("Start Year"),
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"options": "Fiscal Year",
|
"options": "Fiscal Year",
|
||||||
"default": frappe.defaults.get_user_default("fiscal_year"),
|
"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"depends_on": "eval:doc.filter_based_on == 'Fiscal Year'"
|
"depends_on": "eval:doc.filter_based_on == 'Fiscal Year'"
|
||||||
},
|
},
|
||||||
@@ -146,7 +146,7 @@ function get_filters() {
|
|||||||
"label": __("End Year"),
|
"label": __("End Year"),
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"options": "Fiscal Year",
|
"options": "Fiscal Year",
|
||||||
"default": frappe.defaults.get_user_default("fiscal_year"),
|
"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"depends_on": "eval:doc.filter_based_on == 'Fiscal Year'"
|
"depends_on": "eval:doc.filter_based_on == 'Fiscal Year'"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -113,6 +113,23 @@ $.extend(erpnext.utils, {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
view_serial_batch_nos: function(frm) {
|
||||||
|
let bundle_ids = frm.doc.items.filter(d => d.serial_and_batch_bundle);
|
||||||
|
|
||||||
|
if (bundle_ids?.length) {
|
||||||
|
frm.add_custom_button(__('Serial / Batch Nos'), () => {
|
||||||
|
frappe.route_options = {
|
||||||
|
"voucher_no": frm.doc.name,
|
||||||
|
"voucher_type": frm.doc.doctype,
|
||||||
|
"from_date": frm.doc.posting_date || frm.doc.transaction_date,
|
||||||
|
"to_date": frm.doc.posting_date || frm.doc.transaction_date,
|
||||||
|
"company": frm.doc.company,
|
||||||
|
};
|
||||||
|
frappe.set_route("query-report", "Serial and Batch Summary");
|
||||||
|
}, __('View'));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
add_indicator_for_multicompany: function(frm, info) {
|
add_indicator_for_multicompany: function(frm, info) {
|
||||||
frm.dashboard.stats_area.show();
|
frm.dashboard.stats_area.show();
|
||||||
frm.dashboard.stats_area_row.addClass('flex');
|
frm.dashboard.stats_area_row.addClass('flex');
|
||||||
@@ -381,6 +398,27 @@ $.extend(erpnext.utils, {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
get_fiscal_year: function(date) {
|
||||||
|
if(!date) {
|
||||||
|
date = frappe.datetime.get_today();
|
||||||
|
}
|
||||||
|
|
||||||
|
let fiscal_year = '';
|
||||||
|
frappe.call({
|
||||||
|
method: "erpnext.accounts.utils.get_fiscal_year",
|
||||||
|
args: {
|
||||||
|
date: date
|
||||||
|
},
|
||||||
|
async: false,
|
||||||
|
callback: function(r) {
|
||||||
|
if (r.message) {
|
||||||
|
fiscal_year = r.message[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return fiscal_year;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1003,4 +1041,4 @@ function attach_selector_button(inner_text, append_loction, context, grid_row) {
|
|||||||
$btn.on("click", function() {
|
$btn.on("click", function() {
|
||||||
context.show_serial_batch_selector(grid_row.frm, grid_row.doc, "", "", true);
|
context.show_serial_batch_selector(grid_row.frm, grid_row.doc, "", "", true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -16,7 +16,7 @@ frappe.query_reports["Fichier des Ecritures Comptables [FEC]"] = {
|
|||||||
"label": __("Fiscal Year"),
|
"label": __("Fiscal Year"),
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"options": "Fiscal Year",
|
"options": "Fiscal Year",
|
||||||
"default": frappe.defaults.get_user_default("fiscal_year"),
|
"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ frappe.query_reports["IRS 1099"] = {
|
|||||||
"label": __("Fiscal Year"),
|
"label": __("Fiscal Year"),
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"options": "Fiscal Year",
|
"options": "Fiscal Year",
|
||||||
"default": frappe.defaults.get_user_default("fiscal_year"),
|
"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"width": 80,
|
"width": 80,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -5,18 +5,19 @@
|
|||||||
"custom_options": "{\"type\": \"line\", \"axisOptions\": {\"shortenYAxisNumbers\": 1}, \"tooltipOptions\": {}, \"lineOptions\": {\"regionFill\": 1}}",
|
"custom_options": "{\"type\": \"line\", \"axisOptions\": {\"shortenYAxisNumbers\": 1}, \"tooltipOptions\": {}, \"lineOptions\": {\"regionFill\": 1}}",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Dashboard Chart",
|
"doctype": "Dashboard Chart",
|
||||||
"dynamic_filters_json": "{\"company\":\"frappe.defaults.get_user_default(\\\"Company\\\")\",\"fiscal_year\":\"frappe.sys_defaults.fiscal_year\"}",
|
"dynamic_filters_json": "{\"company\":\"frappe.defaults.get_user_default(\\\"Company\\\")\",\"fiscal_year\":\"erpnext.utils.get_fiscal_year()\"}",
|
||||||
"filters_json": "{\"period\":\"Monthly\",\"based_on\":\"Item\"}",
|
"filters_json": "{\"period\":\"Monthly\",\"based_on\":\"Item\"}",
|
||||||
"idx": 0,
|
"idx": 1,
|
||||||
"is_public": 1,
|
"is_public": 1,
|
||||||
"is_standard": 1,
|
"is_standard": 1,
|
||||||
"modified": "2020-07-22 16:24:45.726270",
|
"modified": "2023-07-19 13:09:45.341791",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Selling",
|
"module": "Selling",
|
||||||
"name": "Sales Order Trends",
|
"name": "Sales Order Trends",
|
||||||
"number_of_groups": 0,
|
"number_of_groups": 0,
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"report_name": "Sales Order Trends",
|
"report_name": "Sales Order Trends",
|
||||||
|
"roles": [],
|
||||||
"timeseries": 0,
|
"timeseries": 0,
|
||||||
"type": "Line",
|
"type": "Line",
|
||||||
"use_report_chart": 1,
|
"use_report_chart": 1,
|
||||||
|
|||||||
@@ -5,18 +5,19 @@
|
|||||||
"custom_options": "",
|
"custom_options": "",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Dashboard Chart",
|
"doctype": "Dashboard Chart",
|
||||||
"dynamic_filters_json": "{\"company\":\"frappe.defaults.get_user_default(\\\"Company\\\")\",\"fiscal_year\":\"frappe.sys_defaults.fiscal_year\"}",
|
"dynamic_filters_json": "{\"company\":\"frappe.defaults.get_user_default(\\\"Company\\\")\",\"fiscal_year\":\"erpnext.utils.get_fiscal_year()\"}",
|
||||||
"filters_json": "{\"period\":\"Yearly\",\"based_on\":\"Customer\"}",
|
"filters_json": "{\"period\":\"Yearly\",\"based_on\":\"Customer\"}",
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_public": 1,
|
"is_public": 1,
|
||||||
"is_standard": 1,
|
"is_standard": 1,
|
||||||
"modified": "2020-07-22 17:03:10.320147",
|
"modified": "2023-07-19 13:14:20.151502",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Selling",
|
"module": "Selling",
|
||||||
"name": "Top Customers",
|
"name": "Top Customers",
|
||||||
"number_of_groups": 0,
|
"number_of_groups": 0,
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"report_name": "Delivery Note Trends",
|
"report_name": "Delivery Note Trends",
|
||||||
|
"roles": [],
|
||||||
"timeseries": 0,
|
"timeseries": 0,
|
||||||
"type": "Bar",
|
"type": "Bar",
|
||||||
"use_report_chart": 1,
|
"use_report_chart": 1,
|
||||||
|
|||||||
@@ -1904,12 +1904,11 @@ class TestSalesOrder(FrappeTestCase):
|
|||||||
"voucher_no": so.name,
|
"voucher_no": so.name,
|
||||||
"voucher_detail_no": item.name,
|
"voucher_detail_no": item.name,
|
||||||
},
|
},
|
||||||
fields=["status", "reserved_qty", "delivered_qty"],
|
fields=["reserved_qty", "delivered_qty"],
|
||||||
)
|
)
|
||||||
|
|
||||||
for sre_detail in sre_details:
|
for sre_detail in sre_details:
|
||||||
self.assertEqual(sre_detail.reserved_qty, sre_detail.delivered_qty)
|
self.assertEqual(sre_detail.reserved_qty, sre_detail.delivered_qty)
|
||||||
self.assertEqual(sre_detail.status, "Delivered")
|
|
||||||
|
|
||||||
def test_delivered_item_material_request(self):
|
def test_delivered_item_material_request(self):
|
||||||
"SO -> MR (Manufacture) -> WO. Test if WO Qty is updated in SO."
|
"SO -> MR (Manufacture) -> WO. Test if WO Qty is updated in SO."
|
||||||
|
|||||||
@@ -1,352 +1,99 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 1,
|
"actions": [],
|
||||||
"allow_guest_to_view": 0,
|
"allow_copy": 1,
|
||||||
"allow_import": 0,
|
"creation": "2013-05-02 17:53:24",
|
||||||
"allow_rename": 0,
|
"doctype": "DocType",
|
||||||
"beta": 0,
|
"engine": "InnoDB",
|
||||||
"creation": "2013-05-02 17:53:24",
|
"field_order": [
|
||||||
"custom": 0,
|
"default_company",
|
||||||
"docstatus": 0,
|
"country",
|
||||||
"doctype": "DocType",
|
"default_distance_unit",
|
||||||
"editable_grid": 0,
|
"column_break_8",
|
||||||
|
"default_currency",
|
||||||
|
"hide_currency_symbol",
|
||||||
|
"disable_rounded_total",
|
||||||
|
"disable_in_words"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "default_company",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Link",
|
||||||
"allow_on_submit": 0,
|
"ignore_user_permissions": 1,
|
||||||
"bold": 0,
|
"label": "Default Company",
|
||||||
"collapsible": 0,
|
"options": "Company"
|
||||||
"columns": 0,
|
},
|
||||||
"fieldname": "default_company",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 1,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Default Company",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Company",
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "country",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Link",
|
||||||
"allow_on_submit": 0,
|
"label": "Country",
|
||||||
"bold": 0,
|
"options": "Country"
|
||||||
"collapsible": 0,
|
},
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "current_fiscal_year",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Current Fiscal Year",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Fiscal Year",
|
|
||||||
"permlevel": 0,
|
|
||||||
"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
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "default_distance_unit",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Link",
|
||||||
"allow_on_submit": 0,
|
"label": "Default Distance Unit",
|
||||||
"bold": 0,
|
"options": "UOM"
|
||||||
"collapsible": 0,
|
},
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "country",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Country",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Country",
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "column_break_8",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Column Break"
|
||||||
"allow_on_submit": 0,
|
},
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"default": "",
|
|
||||||
"fieldname": "default_distance_unit",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Default Distance Unit",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "UOM",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"default": "INR",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "default_currency",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Link",
|
||||||
"bold": 0,
|
"ignore_user_permissions": 1,
|
||||||
"collapsible": 0,
|
"in_list_view": 1,
|
||||||
"columns": 0,
|
"label": "Default Currency",
|
||||||
"fieldname": "column_break_8",
|
"options": "Currency",
|
||||||
"fieldtype": "Column Break",
|
"reqd": 1
|
||||||
"hidden": 0,
|
},
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"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": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"description": "Do not show any symbol like $ etc next to currencies.",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "hide_currency_symbol",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Select",
|
||||||
"bold": 0,
|
"in_list_view": 1,
|
||||||
"collapsible": 0,
|
"label": "Hide Currency Symbol",
|
||||||
"columns": 0,
|
"options": "\nNo\nYes"
|
||||||
"default": "INR",
|
},
|
||||||
"fieldname": "default_currency",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 1,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Default Currency",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Currency",
|
|
||||||
"permlevel": 0,
|
|
||||||
"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
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"default": "0",
|
||||||
"allow_in_quick_entry": 0,
|
"description": "If disable, 'Rounded Total' field will not be visible in any transaction",
|
||||||
"allow_on_submit": 0,
|
"fieldname": "disable_rounded_total",
|
||||||
"bold": 0,
|
"fieldtype": "Check",
|
||||||
"collapsible": 0,
|
"in_list_view": 1,
|
||||||
"columns": 0,
|
"label": "Disable Rounded Total"
|
||||||
"description": "Do not show any symbol like $ etc next to currencies.",
|
},
|
||||||
"fieldname": "hide_currency_symbol",
|
|
||||||
"fieldtype": "Select",
|
|
||||||
"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": "Hide Currency Symbol",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "\nNo\nYes",
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"default": "0",
|
||||||
"allow_in_quick_entry": 0,
|
"description": "If disable, 'In Words' field will not be visible in any transaction",
|
||||||
"allow_on_submit": 0,
|
"fieldname": "disable_in_words",
|
||||||
"bold": 0,
|
"fieldtype": "Check",
|
||||||
"collapsible": 0,
|
"in_list_view": 1,
|
||||||
"columns": 0,
|
"label": "Disable In Words"
|
||||||
"description": "If disable, 'Rounded Total' field will not be visible in any transaction",
|
|
||||||
"fieldname": "disable_rounded_total",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"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": "Disable Rounded Total",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"description": "If disable, 'In Words' field will not be visible in any transaction",
|
|
||||||
"fieldname": "disable_in_words",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"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": "Disable In Words",
|
|
||||||
"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": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
"icon": "fa fa-cog",
|
||||||
"hide_heading": 0,
|
"idx": 1,
|
||||||
"hide_toolbar": 0,
|
"in_create": 1,
|
||||||
"icon": "fa fa-cog",
|
"issingle": 1,
|
||||||
"idx": 1,
|
"links": [],
|
||||||
"image_view": 0,
|
"modified": "2023-07-01 19:45:00.323953",
|
||||||
"in_create": 1,
|
"modified_by": "Administrator",
|
||||||
"is_submittable": 0,
|
"module": "Setup",
|
||||||
"issingle": 1,
|
"name": "Global Defaults",
|
||||||
"istable": 0,
|
"owner": "Administrator",
|
||||||
"max_attachments": 0,
|
|
||||||
"menu_index": 0,
|
|
||||||
"modified": "2018-10-15 03:08:19.886212",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "Setup",
|
|
||||||
"name": "Global Defaults",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"create": 1,
|
||||||
"cancel": 0,
|
"read": 1,
|
||||||
"create": 1,
|
"role": "System Manager",
|
||||||
"delete": 0,
|
"share": 1,
|
||||||
"email": 0,
|
|
||||||
"export": 0,
|
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 0,
|
|
||||||
"read": 1,
|
|
||||||
"report": 0,
|
|
||||||
"role": "System Manager",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 0,
|
"read_only": 1,
|
||||||
"read_only": 1,
|
"sort_field": "modified",
|
||||||
"read_only_onload": 0,
|
"sort_order": "DESC",
|
||||||
"show_name_in_global_search": 0,
|
"states": []
|
||||||
"sort_order": "DESC",
|
|
||||||
"track_changes": 0,
|
|
||||||
"track_seen": 0,
|
|
||||||
"track_views": 0
|
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,6 @@ from frappe.utils import cint
|
|||||||
|
|
||||||
keydict = {
|
keydict = {
|
||||||
# "key in defaults": "key in Global Defaults"
|
# "key in defaults": "key in Global Defaults"
|
||||||
"fiscal_year": "current_fiscal_year",
|
|
||||||
"company": "default_company",
|
"company": "default_company",
|
||||||
"currency": "default_currency",
|
"currency": "default_currency",
|
||||||
"country": "country",
|
"country": "country",
|
||||||
@@ -29,22 +28,6 @@ class GlobalDefaults(Document):
|
|||||||
for key in keydict:
|
for key in keydict:
|
||||||
frappe.db.set_default(key, self.get(keydict[key], ""))
|
frappe.db.set_default(key, self.get(keydict[key], ""))
|
||||||
|
|
||||||
# update year start date and year end date from fiscal_year
|
|
||||||
if self.current_fiscal_year:
|
|
||||||
if fiscal_year := frappe.get_all(
|
|
||||||
"Fiscal Year",
|
|
||||||
filters={"name": self.current_fiscal_year},
|
|
||||||
fields=["year_start_date", "year_end_date"],
|
|
||||||
limit=1,
|
|
||||||
order_by=None,
|
|
||||||
):
|
|
||||||
ysd = fiscal_year[0].year_start_date or ""
|
|
||||||
yed = fiscal_year[0].year_end_date or ""
|
|
||||||
|
|
||||||
if ysd and yed:
|
|
||||||
frappe.db.set_default("year_start_date", ysd.strftime("%Y-%m-%d"))
|
|
||||||
frappe.db.set_default("year_end_date", yed.strftime("%Y-%m-%d"))
|
|
||||||
|
|
||||||
# enable default currency
|
# enable default currency
|
||||||
if self.default_currency:
|
if self.default_currency:
|
||||||
frappe.db.set_value("Currency", self.default_currency, "enabled", 1)
|
frappe.db.set_value("Currency", self.default_currency, "enabled", 1)
|
||||||
|
|||||||
@@ -462,11 +462,9 @@ def install_defaults(args=None): # nosemgrep
|
|||||||
|
|
||||||
def set_global_defaults(args):
|
def set_global_defaults(args):
|
||||||
global_defaults = frappe.get_doc("Global Defaults", "Global Defaults")
|
global_defaults = frappe.get_doc("Global Defaults", "Global Defaults")
|
||||||
current_fiscal_year = frappe.get_all("Fiscal Year")[0]
|
|
||||||
|
|
||||||
global_defaults.update(
|
global_defaults.update(
|
||||||
{
|
{
|
||||||
"current_fiscal_year": current_fiscal_year.name,
|
|
||||||
"default_currency": args.get("currency"),
|
"default_currency": args.get("currency"),
|
||||||
"default_company": args.get("company_name"),
|
"default_company": args.get("company_name"),
|
||||||
"country": args.get("country"),
|
"country": args.get("country"),
|
||||||
|
|||||||
@@ -118,8 +118,8 @@ class MaterialRequest(BuyingController):
|
|||||||
self.title = _("{0} Request for {1}").format(_(self.material_request_type), items)[:100]
|
self.title = _("{0} Request for {1}").format(_(self.material_request_type), items)[:100]
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
self.update_requested_qty()
|
|
||||||
self.update_requested_qty_in_production_plan()
|
self.update_requested_qty_in_production_plan()
|
||||||
|
self.update_requested_qty()
|
||||||
if self.material_request_type == "Purchase":
|
if self.material_request_type == "Purchase":
|
||||||
self.validate_budget()
|
self.validate_budget()
|
||||||
|
|
||||||
@@ -178,8 +178,8 @@ class MaterialRequest(BuyingController):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
self.update_requested_qty()
|
|
||||||
self.update_requested_qty_in_production_plan()
|
self.update_requested_qty_in_production_plan()
|
||||||
|
self.update_requested_qty()
|
||||||
|
|
||||||
def get_mr_items_ordered_qty(self, mr_items):
|
def get_mr_items_ordered_qty(self, mr_items):
|
||||||
mr_items_ordered_qty = {}
|
mr_items_ordered_qty = {}
|
||||||
@@ -270,7 +270,13 @@ class MaterialRequest(BuyingController):
|
|||||||
item_wh_list.append([d.item_code, d.warehouse])
|
item_wh_list.append([d.item_code, d.warehouse])
|
||||||
|
|
||||||
for item_code, warehouse in item_wh_list:
|
for item_code, warehouse in item_wh_list:
|
||||||
update_bin_qty(item_code, warehouse, {"indented_qty": get_indented_qty(item_code, warehouse)})
|
update_bin_qty(
|
||||||
|
item_code,
|
||||||
|
warehouse,
|
||||||
|
{
|
||||||
|
"indented_qty": get_indented_qty(item_code, warehouse),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
def update_requested_qty_in_production_plan(self):
|
def update_requested_qty_in_production_plan(self):
|
||||||
production_plans = []
|
production_plans = []
|
||||||
|
|||||||
@@ -193,7 +193,7 @@
|
|||||||
"fieldname": "naming_series",
|
"fieldname": "naming_series",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "Naming Series",
|
"label": "Naming Series",
|
||||||
"options": "SBB-.####"
|
"options": "SABB-.########"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
@@ -244,7 +244,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-04-10 20:02:42.964309",
|
"modified": "2023-07-16 10:53:04.045605",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Serial and Batch Bundle",
|
"name": "Serial and Batch Bundle",
|
||||||
|
|||||||
@@ -889,13 +889,16 @@ def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=Fals
|
|||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_serial_batch_ledgers(item_code, docstatus=None, voucher_no=None, name=None):
|
def get_serial_batch_ledgers(item_code=None, docstatus=None, voucher_no=None, name=None):
|
||||||
filters = get_filters_for_bundle(item_code, docstatus=docstatus, voucher_no=voucher_no, name=name)
|
filters = get_filters_for_bundle(
|
||||||
|
item_code=item_code, docstatus=docstatus, voucher_no=voucher_no, name=name
|
||||||
|
)
|
||||||
|
|
||||||
return frappe.get_all(
|
return frappe.get_all(
|
||||||
"Serial and Batch Bundle",
|
"Serial and Batch Bundle",
|
||||||
fields=[
|
fields=[
|
||||||
"`tabSerial and Batch Bundle`.`name`",
|
"`tabSerial and Batch Bundle`.`name`",
|
||||||
|
"`tabSerial and Batch Bundle`.`item_code`",
|
||||||
"`tabSerial and Batch Entry`.`qty`",
|
"`tabSerial and Batch Entry`.`qty`",
|
||||||
"`tabSerial and Batch Entry`.`warehouse`",
|
"`tabSerial and Batch Entry`.`warehouse`",
|
||||||
"`tabSerial and Batch Entry`.`batch_no`",
|
"`tabSerial and Batch Entry`.`batch_no`",
|
||||||
@@ -906,12 +909,14 @@ def get_serial_batch_ledgers(item_code, docstatus=None, voucher_no=None, name=No
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_filters_for_bundle(item_code, docstatus=None, voucher_no=None, name=None):
|
def get_filters_for_bundle(item_code=None, docstatus=None, voucher_no=None, name=None):
|
||||||
filters = [
|
filters = [
|
||||||
["Serial and Batch Bundle", "item_code", "=", item_code],
|
|
||||||
["Serial and Batch Bundle", "is_cancelled", "=", 0],
|
["Serial and Batch Bundle", "is_cancelled", "=", 0],
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if item_code:
|
||||||
|
filters.append(["Serial and Batch Bundle", "item_code", "=", item_code])
|
||||||
|
|
||||||
if not docstatus:
|
if not docstatus:
|
||||||
docstatus = [0, 1]
|
docstatus = [0, 1]
|
||||||
|
|
||||||
|
|||||||
@@ -925,6 +925,7 @@ erpnext.stock.StockEntry = class StockEntry extends erpnext.stock.StockControlle
|
|||||||
this.toggle_related_fields(this.frm.doc);
|
this.toggle_related_fields(this.frm.doc);
|
||||||
this.toggle_enable_bom();
|
this.toggle_enable_bom();
|
||||||
this.show_stock_ledger();
|
this.show_stock_ledger();
|
||||||
|
erpnext.utils.view_serial_batch_nos(this.frm);
|
||||||
if (this.frm.doc.docstatus===1 && erpnext.is_perpetual_inventory_enabled(this.frm.doc.company)) {
|
if (this.frm.doc.docstatus===1 && erpnext.is_perpetual_inventory_enabled(this.frm.doc.company)) {
|
||||||
this.show_general_ledger();
|
this.show_general_ledger();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -337,6 +337,7 @@ erpnext.stock.StockReconciliation = class StockReconciliation extends erpnext.st
|
|||||||
refresh() {
|
refresh() {
|
||||||
if(this.frm.doc.docstatus > 0) {
|
if(this.frm.doc.docstatus > 0) {
|
||||||
this.show_stock_ledger();
|
this.show_stock_ledger();
|
||||||
|
erpnext.utils.view_serial_batch_nos(this.frm);
|
||||||
if (erpnext.is_perpetual_inventory_enabled(this.frm.doc.company)) {
|
if (erpnext.is_perpetual_inventory_enabled(this.frm.doc.company)) {
|
||||||
this.show_general_ledger();
|
this.show_general_ledger();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,95 @@
|
|||||||
|
// Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
frappe.query_reports["Serial and Batch Summary"] = {
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"fieldname":"company",
|
||||||
|
"label": __("Company"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Company",
|
||||||
|
"default": frappe.defaults.get_user_default("Company"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"from_date",
|
||||||
|
"label": __("From Date"),
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"to_date",
|
||||||
|
"label": __("To Date"),
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"default": frappe.datetime.get_today()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"item_code",
|
||||||
|
"label": __("Item"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Item",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"warehouse",
|
||||||
|
"label": __("Warehouse"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Warehouse",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"voucher_type",
|
||||||
|
"label": __("Voucher Type"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "DocType",
|
||||||
|
get_query: function() {
|
||||||
|
return {
|
||||||
|
query: "erpnext.stock.report.serial_and_batch_summary.serial_and_batch_summary.get_voucher_type",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"voucher_no",
|
||||||
|
"label": __("Voucher No"),
|
||||||
|
"fieldtype": "MultiSelectList",
|
||||||
|
get_data: function(txt) {
|
||||||
|
if (!frappe.query_report.filters) return;
|
||||||
|
|
||||||
|
let voucher_type = frappe.query_report.get_filter_value('voucher_type');
|
||||||
|
if (!voucher_type) return;
|
||||||
|
|
||||||
|
return frappe.db.get_link_options(voucher_type, txt);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"serial_no",
|
||||||
|
"label": __("Serial No"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Serial No",
|
||||||
|
get_query: function() {
|
||||||
|
return {
|
||||||
|
query: "erpnext.stock.report.serial_and_batch_summary.serial_and_batch_summary.get_serial_nos",
|
||||||
|
filters: {
|
||||||
|
"item_code": frappe.query_report.get_filter_value('item_code'),
|
||||||
|
"voucher_type": frappe.query_report.get_filter_value('voucher_type'),
|
||||||
|
"voucher_no": frappe.query_report.get_filter_value('voucher_no'),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"batch_no",
|
||||||
|
"label": __("Batch No"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Batch",
|
||||||
|
get_query: function() {
|
||||||
|
return {
|
||||||
|
query: "erpnext.stock.report.serial_and_batch_summary.serial_and_batch_summary.get_batch_nos",
|
||||||
|
filters: {
|
||||||
|
"item_code": frappe.query_report.get_filter_value('item_code'),
|
||||||
|
"voucher_type": frappe.query_report.get_filter_value('voucher_type'),
|
||||||
|
"voucher_no": frappe.query_report.get_filter_value('voucher_no'),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"add_total_row": 0,
|
||||||
|
"columns": [],
|
||||||
|
"creation": "2023-07-13 16:53:27.735091",
|
||||||
|
"disabled": 0,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Report",
|
||||||
|
"filters": [],
|
||||||
|
"idx": 0,
|
||||||
|
"is_standard": "Yes",
|
||||||
|
"json": "{}",
|
||||||
|
"modified": "2023-07-13 16:53:33.204591",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Stock",
|
||||||
|
"name": "Serial and Batch Summary",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"prepared_report": 0,
|
||||||
|
"ref_doctype": "Serial and Batch Bundle",
|
||||||
|
"report_name": "Serial and Batch Summary",
|
||||||
|
"report_type": "Script Report",
|
||||||
|
"roles": [
|
||||||
|
{
|
||||||
|
"role": "System Manager"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "Sales User"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "Purchase User"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "Stock User"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "Maintenance User"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,245 @@
|
|||||||
|
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
from frappe import _
|
||||||
|
|
||||||
|
|
||||||
|
def execute(filters=None):
|
||||||
|
data = get_data(filters)
|
||||||
|
columns = get_columns(filters, data)
|
||||||
|
|
||||||
|
return columns, data
|
||||||
|
|
||||||
|
|
||||||
|
def get_data(filters):
|
||||||
|
filter_conditions = get_filter_conditions(filters)
|
||||||
|
|
||||||
|
return frappe.get_all(
|
||||||
|
"Serial and Batch Bundle",
|
||||||
|
fields=[
|
||||||
|
"`tabSerial and Batch Bundle`.`voucher_type`",
|
||||||
|
"`tabSerial and Batch Bundle`.`posting_date`",
|
||||||
|
"`tabSerial and Batch Bundle`.`name`",
|
||||||
|
"`tabSerial and Batch Bundle`.`company`",
|
||||||
|
"`tabSerial and Batch Bundle`.`voucher_no`",
|
||||||
|
"`tabSerial and Batch Bundle`.`item_code`",
|
||||||
|
"`tabSerial and Batch Bundle`.`item_name`",
|
||||||
|
"`tabSerial and Batch Entry`.`serial_no`",
|
||||||
|
"`tabSerial and Batch Entry`.`batch_no`",
|
||||||
|
"`tabSerial and Batch Entry`.`warehouse`",
|
||||||
|
"`tabSerial and Batch Entry`.`incoming_rate`",
|
||||||
|
"`tabSerial and Batch Entry`.`stock_value_difference`",
|
||||||
|
"`tabSerial and Batch Entry`.`qty`",
|
||||||
|
],
|
||||||
|
filters=filter_conditions,
|
||||||
|
order_by="posting_date",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_filter_conditions(filters):
|
||||||
|
filter_conditions = [
|
||||||
|
["Serial and Batch Bundle", "docstatus", "=", 1],
|
||||||
|
["Serial and Batch Bundle", "is_cancelled", "=", 0],
|
||||||
|
]
|
||||||
|
|
||||||
|
for field in ["voucher_type", "voucher_no", "item_code", "warehouse", "company"]:
|
||||||
|
if filters.get(field):
|
||||||
|
if field == "voucher_no":
|
||||||
|
filter_conditions.append(["Serial and Batch Bundle", field, "in", filters.get(field)])
|
||||||
|
else:
|
||||||
|
filter_conditions.append(["Serial and Batch Bundle", field, "=", filters.get(field)])
|
||||||
|
|
||||||
|
if filters.get("from_date") and filters.get("to_date"):
|
||||||
|
filter_conditions.append(
|
||||||
|
[
|
||||||
|
"Serial and Batch Bundle",
|
||||||
|
"posting_date",
|
||||||
|
"between",
|
||||||
|
[filters.get("from_date"), filters.get("to_date")],
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
for field in ["serial_no", "batch_no"]:
|
||||||
|
if filters.get(field):
|
||||||
|
filter_conditions.append(["Serial and Batch Entry", field, "=", filters.get(field)])
|
||||||
|
|
||||||
|
return filter_conditions
|
||||||
|
|
||||||
|
|
||||||
|
def get_columns(filters, data):
|
||||||
|
columns = [
|
||||||
|
{
|
||||||
|
"label": _("Company"),
|
||||||
|
"fieldname": "company",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Company",
|
||||||
|
"width": 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Serial and Batch Bundle"),
|
||||||
|
"fieldname": "name",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Serial and Batch Bundle",
|
||||||
|
"width": 110,
|
||||||
|
},
|
||||||
|
{"label": _("Posting Date"), "fieldname": "posting_date", "fieldtype": "Date", "width": 100},
|
||||||
|
]
|
||||||
|
|
||||||
|
item_details = {}
|
||||||
|
|
||||||
|
item_codes = []
|
||||||
|
if filters.get("voucher_type"):
|
||||||
|
item_codes = [d.item_code for d in data]
|
||||||
|
|
||||||
|
if filters.get("item_code") or (item_codes and len(list(set(item_codes))) == 1):
|
||||||
|
item_details = frappe.get_cached_value(
|
||||||
|
"Item",
|
||||||
|
filters.get("item_code") or item_codes[0],
|
||||||
|
["has_serial_no", "has_batch_no"],
|
||||||
|
as_dict=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
if not filters.get("voucher_no"):
|
||||||
|
columns.extend(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"label": _("Voucher Type"),
|
||||||
|
"fieldname": "voucher_type",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "DocType",
|
||||||
|
"width": 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Voucher No"),
|
||||||
|
"fieldname": "voucher_no",
|
||||||
|
"fieldtype": "Dynamic Link",
|
||||||
|
"options": "voucher_type",
|
||||||
|
"width": 160,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
if not filters.get("item_code"):
|
||||||
|
columns.extend(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"label": _("Item Code"),
|
||||||
|
"fieldname": "item_code",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Item",
|
||||||
|
"width": 120,
|
||||||
|
},
|
||||||
|
{"label": _("Item Name"), "fieldname": "item_name", "fieldtype": "Data", "width": 120},
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
if not filters.get("warehouse"):
|
||||||
|
columns.append(
|
||||||
|
{
|
||||||
|
"label": _("Warehouse"),
|
||||||
|
"fieldname": "warehouse",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Warehouse",
|
||||||
|
"width": 120,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if not item_details or item_details.get("has_serial_no"):
|
||||||
|
columns.append(
|
||||||
|
{"label": _("Serial No"), "fieldname": "serial_no", "fieldtype": "Data", "width": 120}
|
||||||
|
)
|
||||||
|
|
||||||
|
if not item_details or item_details.get("has_batch_no"):
|
||||||
|
columns.extend(
|
||||||
|
[
|
||||||
|
{"label": _("Batch No"), "fieldname": "batch_no", "fieldtype": "Data", "width": 120},
|
||||||
|
{"label": _("Batch Qty"), "fieldname": "qty", "fieldtype": "Float", "width": 120},
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
columns.extend(
|
||||||
|
[
|
||||||
|
{"label": _("Incoming Rate"), "fieldname": "incoming_rate", "fieldtype": "Float", "width": 120},
|
||||||
|
{
|
||||||
|
"label": _("Change in Stock Value"),
|
||||||
|
"fieldname": "stock_value_difference",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"width": 120,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
return columns
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
@frappe.validate_and_sanitize_search_inputs
|
||||||
|
def get_voucher_type(doctype, txt, searchfield, start, page_len, filters):
|
||||||
|
child_doctypes = frappe.get_all(
|
||||||
|
"DocField",
|
||||||
|
filters={"fieldname": "serial_and_batch_bundle"},
|
||||||
|
fields=["distinct parent as parent"],
|
||||||
|
)
|
||||||
|
|
||||||
|
query_filters = {"options": ["in", [d.parent for d in child_doctypes]]}
|
||||||
|
if txt:
|
||||||
|
query_filters["parent"] = ["like", "%{}%".format(txt)]
|
||||||
|
|
||||||
|
return frappe.get_all("DocField", filters=query_filters, fields=["distinct parent"], as_list=True)
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
@frappe.validate_and_sanitize_search_inputs
|
||||||
|
def get_serial_nos(doctype, txt, searchfield, start, page_len, filters):
|
||||||
|
query_filters = {}
|
||||||
|
|
||||||
|
if txt:
|
||||||
|
query_filters["serial_no"] = ["like", f"%{txt}%"]
|
||||||
|
|
||||||
|
if filters.get("voucher_no"):
|
||||||
|
serial_batch_bundle = frappe.get_cached_value(
|
||||||
|
"Serial and Batch Bundle",
|
||||||
|
{"voucher_no": ("in", filters.get("voucher_no")), "docstatus": 1, "is_cancelled": 0},
|
||||||
|
"name",
|
||||||
|
)
|
||||||
|
|
||||||
|
query_filters["parent"] = serial_batch_bundle
|
||||||
|
if not txt:
|
||||||
|
query_filters["serial_no"] = ("is", "set")
|
||||||
|
|
||||||
|
return frappe.get_all(
|
||||||
|
"Serial and Batch Entry", filters=query_filters, fields=["serial_no"], as_list=True
|
||||||
|
)
|
||||||
|
|
||||||
|
else:
|
||||||
|
query_filters["item_code"] = filters.get("item_code")
|
||||||
|
return frappe.get_all("Serial No", filters=query_filters, as_list=True)
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
@frappe.validate_and_sanitize_search_inputs
|
||||||
|
def get_batch_nos(doctype, txt, searchfield, start, page_len, filters):
|
||||||
|
query_filters = {}
|
||||||
|
|
||||||
|
if txt:
|
||||||
|
query_filters["batch_no"] = ["like", f"%{txt}%"]
|
||||||
|
|
||||||
|
if filters.get("voucher_no"):
|
||||||
|
serial_batch_bundle = frappe.get_cached_value(
|
||||||
|
"Serial and Batch Bundle",
|
||||||
|
{"voucher_no": ("in", filters.get("voucher_no")), "docstatus": 1, "is_cancelled": 0},
|
||||||
|
"name",
|
||||||
|
)
|
||||||
|
|
||||||
|
query_filters["parent"] = serial_batch_bundle
|
||||||
|
if not txt:
|
||||||
|
query_filters["batch_no"] = ("is", "set")
|
||||||
|
|
||||||
|
return frappe.get_all(
|
||||||
|
"Serial and Batch Entry", filters=query_filters, fields=["batch_no"], as_list=True
|
||||||
|
)
|
||||||
|
|
||||||
|
else:
|
||||||
|
query_filters["item"] = filters.get("item_code")
|
||||||
|
return frappe.get_all("Batch", filters=query_filters, as_list=True)
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
{% for item, taxes in itemised_tax.items() %}
|
{% for item, taxes in itemised_tax.items() %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ item }}</td>
|
<td>{{ item }}</td>
|
||||||
<td class='text-right'>
|
<td class="text-right">
|
||||||
{% if doc.get('is_return') %}
|
{% if doc.get('is_return') %}
|
||||||
{{ frappe.utils.fmt_money((itemised_taxable_amount.get(item, 0))|abs, None, doc.currency) }}
|
{{ frappe.utils.fmt_money((itemised_taxable_amount.get(item, 0))|abs, None, doc.currency) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
{% for tax_account in tax_accounts %}
|
{% for tax_account in tax_accounts %}
|
||||||
{% set tax_details = taxes.get(tax_account) %}
|
{% set tax_details = taxes.get(tax_account) %}
|
||||||
{% if tax_details %}
|
{% if tax_details %}
|
||||||
<td class='text-right'>
|
<td class="text-right">
|
||||||
{% if tax_details.tax_rate or not tax_details.tax_amount %}
|
{% if tax_details.tax_rate or not tax_details.tax_amount %}
|
||||||
({{ tax_details.tax_rate }}%)
|
({{ tax_details.tax_rate }}%)
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
Reference in New Issue
Block a user