mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-16 03:29:16 +00:00
Merge branch 'v12-pre-release' into version-12
This commit is contained in:
@@ -5,7 +5,7 @@ import frappe
|
|||||||
from erpnext.hooks import regional_overrides
|
from erpnext.hooks import regional_overrides
|
||||||
from frappe.utils import getdate
|
from frappe.utils import getdate
|
||||||
|
|
||||||
__version__ = '12.3.1'
|
__version__ = '12.4.0'
|
||||||
|
|
||||||
def get_default_company(user=None):
|
def get_default_company(user=None):
|
||||||
'''Get default company for user'''
|
'''Get default company for user'''
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ class AccountingPeriod(Document):
|
|||||||
|
|
||||||
def get_doctypes_for_closing(self):
|
def get_doctypes_for_closing(self):
|
||||||
docs_for_closing = []
|
docs_for_closing = []
|
||||||
doctypes = ["Sales Invoice", "Purchase Invoice", "Journal Entry", "Payroll Entry", "Bank Reconciliation",
|
doctypes = ["Sales Invoice", "Purchase Invoice", "Journal Entry", "Payroll Entry", \
|
||||||
"Asset", "Purchase Order", "Sales Order", "Leave Application", "Leave Allocation", "Stock Entry"]
|
"Bank Reconciliation", "Asset", "Stock Entry"]
|
||||||
closed_doctypes = [{"document_type": doctype, "closed": 1} for doctype in doctypes]
|
closed_doctypes = [{"document_type": doctype, "closed": 1} for doctype in doctypes]
|
||||||
for closed_doctype in closed_doctypes:
|
for closed_doctype in closed_doctypes:
|
||||||
docs_for_closing.append(closed_doctype)
|
docs_for_closing.append(closed_doctype)
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ class GLEntry(Document):
|
|||||||
self.validate_and_set_fiscal_year()
|
self.validate_and_set_fiscal_year()
|
||||||
self.pl_must_have_cost_center()
|
self.pl_must_have_cost_center()
|
||||||
self.validate_cost_center()
|
self.validate_cost_center()
|
||||||
self.validate_dimensions_for_pl_and_bs()
|
|
||||||
|
|
||||||
if not self.flags.from_repost:
|
if not self.flags.from_repost:
|
||||||
self.check_pl_account()
|
self.check_pl_account()
|
||||||
@@ -39,6 +38,7 @@ class GLEntry(Document):
|
|||||||
def on_update_with_args(self, adv_adj, update_outstanding = 'Yes', from_repost=False):
|
def on_update_with_args(self, adv_adj, update_outstanding = 'Yes', from_repost=False):
|
||||||
if not from_repost:
|
if not from_repost:
|
||||||
self.validate_account_details(adv_adj)
|
self.validate_account_details(adv_adj)
|
||||||
|
self.validate_dimensions_for_pl_and_bs()
|
||||||
check_freezing_date(self.posting_date, adv_adj)
|
check_freezing_date(self.posting_date, adv_adj)
|
||||||
|
|
||||||
validate_frozen_account(self.account, adv_adj)
|
validate_frozen_account(self.account, adv_adj)
|
||||||
|
|||||||
@@ -190,7 +190,6 @@ erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({
|
|||||||
if(jvd.reference_type==="Employee Advance") {
|
if(jvd.reference_type==="Employee Advance") {
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
'status': ['=', 'Unpaid'],
|
|
||||||
'docstatus': 1
|
'docstatus': 1
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ from erpnext.controllers.accounts_controller import AccountsController
|
|||||||
from erpnext.accounts.utils import get_balance_on, get_account_currency
|
from erpnext.accounts.utils import get_balance_on, get_account_currency
|
||||||
from erpnext.accounts.party import get_party_account
|
from erpnext.accounts.party import get_party_account
|
||||||
from erpnext.hr.doctype.expense_claim.expense_claim import update_reimbursed_amount
|
from erpnext.hr.doctype.expense_claim.expense_claim import update_reimbursed_amount
|
||||||
from erpnext.hr.doctype.loan.loan import update_disbursement_status, update_total_amount_paid
|
|
||||||
from erpnext.accounts.doctype.invoice_discounting.invoice_discounting import get_party_account_based_on_invoice_discounting
|
from erpnext.accounts.doctype.invoice_discounting.invoice_discounting import get_party_account_based_on_invoice_discounting
|
||||||
|
|
||||||
from six import string_types, iteritems
|
from six import string_types, iteritems
|
||||||
@@ -606,8 +605,8 @@ class JournalEntry(AccountsController):
|
|||||||
for d in self.accounts:
|
for d in self.accounts:
|
||||||
if d.reference_type=="Loan" and flt(d.debit) > 0:
|
if d.reference_type=="Loan" and flt(d.debit) > 0:
|
||||||
doc = frappe.get_doc("Loan", d.reference_name)
|
doc = frappe.get_doc("Loan", d.reference_name)
|
||||||
update_disbursement_status(doc)
|
doc.update_total_amount_paid()
|
||||||
update_total_amount_paid(doc)
|
doc.set_status()
|
||||||
|
|
||||||
def validate_expense_claim(self):
|
def validate_expense_claim(self):
|
||||||
for d in self.accounts:
|
for d in self.accounts:
|
||||||
@@ -968,7 +967,7 @@ def get_exchange_rate(posting_date, account=None, account_currency=None, company
|
|||||||
|
|
||||||
# The date used to retreive the exchange rate here is the date passed
|
# The date used to retreive the exchange rate here is the date passed
|
||||||
# in as an argument to this function.
|
# in as an argument to this function.
|
||||||
elif (not exchange_rate or exchange_rate==1) and account_currency and posting_date:
|
elif (not exchange_rate or flt(exchange_rate)==1) and account_currency and posting_date:
|
||||||
exchange_rate = get_exchange_rate(account_currency, company_currency, posting_date)
|
exchange_rate = get_exchange_rate(account_currency, company_currency, posting_date)
|
||||||
else:
|
else:
|
||||||
exchange_rate = 1
|
exchange_rate = 1
|
||||||
|
|||||||
@@ -90,7 +90,6 @@
|
|||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "Customer",
|
|
||||||
"fieldname": "party_type",
|
"fieldname": "party_type",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
@@ -272,7 +271,7 @@
|
|||||||
],
|
],
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"modified": "2019-10-02 12:23:21.693443",
|
"modified": "2020-01-13 12:41:33.968025",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Journal Entry Account",
|
"name": "Journal Entry Account",
|
||||||
|
|||||||
@@ -652,14 +652,16 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Student")
|
(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Student")
|
||||||
) {
|
) {
|
||||||
if(total_positive_outstanding > total_negative_outstanding)
|
if(total_positive_outstanding > total_negative_outstanding)
|
||||||
frm.set_value("paid_amount",
|
if (!frm.doc.paid_amount)
|
||||||
total_positive_outstanding - total_negative_outstanding);
|
frm.set_value("paid_amount",
|
||||||
|
total_positive_outstanding - total_negative_outstanding);
|
||||||
} else if (
|
} else if (
|
||||||
total_negative_outstanding &&
|
total_negative_outstanding &&
|
||||||
total_positive_outstanding < total_negative_outstanding
|
total_positive_outstanding < total_negative_outstanding
|
||||||
) {
|
) {
|
||||||
frm.set_value("received_amount",
|
if (!frm.doc.received_amount)
|
||||||
total_negative_outstanding - total_positive_outstanding);
|
frm.set_value("received_amount",
|
||||||
|
total_negative_outstanding - total_positive_outstanding);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -911,7 +911,10 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
|
|||||||
else:
|
else:
|
||||||
party_account = get_party_account(party_type, doc.get(party_type.lower()), doc.company)
|
party_account = get_party_account(party_type, doc.get(party_type.lower()), doc.company)
|
||||||
|
|
||||||
party_account_currency = doc.get("party_account_currency") or get_account_currency(party_account)
|
if dt not in ("Sales Invoice", "Purchase Invoice"):
|
||||||
|
party_account_currency = get_account_currency(party_account)
|
||||||
|
else:
|
||||||
|
party_account_currency = doc.get("party_account_currency") or get_account_currency(party_account)
|
||||||
|
|
||||||
# payment type
|
# payment type
|
||||||
if (dt == "Sales Order" or (dt in ("Sales Invoice", "Fees") and doc.outstanding_amount > 0)) \
|
if (dt == "Sales Order" or (dt in ("Sales Invoice", "Fees") and doc.outstanding_amount > 0)) \
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ class PaymentReconciliation(Document):
|
|||||||
|
|
||||||
if self.party_type in ["Customer", "Supplier"]:
|
if self.party_type in ["Customer", "Supplier"]:
|
||||||
dr_or_cr_notes = self.get_dr_or_cr_notes()
|
dr_or_cr_notes = self.get_dr_or_cr_notes()
|
||||||
|
else:
|
||||||
|
dr_or_cr_notes = []
|
||||||
|
|
||||||
self.add_payment_entries(payment_entries + journal_entries + dr_or_cr_notes)
|
self.add_payment_entries(payment_entries + journal_entries + dr_or_cr_notes)
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,16 @@ cur_frm.add_fetch("payment_gateway_account", "payment_account", "payment_account
|
|||||||
cur_frm.add_fetch("payment_gateway_account", "payment_gateway", "payment_gateway")
|
cur_frm.add_fetch("payment_gateway_account", "payment_gateway", "payment_gateway")
|
||||||
cur_frm.add_fetch("payment_gateway_account", "message", "message")
|
cur_frm.add_fetch("payment_gateway_account", "message", "message")
|
||||||
|
|
||||||
|
frappe.ui.form.on("Payment Request", {
|
||||||
|
setup: function(frm) {
|
||||||
|
frm.set_query("party_type", function() {
|
||||||
|
return {
|
||||||
|
query: "erpnext.setup.doctype.party_type.party_type.get_party_type",
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
frappe.ui.form.on("Payment Request", "onload", function(frm, dt, dn){
|
frappe.ui.form.on("Payment Request", "onload", function(frm, dt, dn){
|
||||||
if (frm.doc.reference_doctype) {
|
if (frm.doc.reference_doctype) {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
|
|||||||
@@ -34,6 +34,9 @@ class PricingRule(Document):
|
|||||||
|
|
||||||
def validate_duplicate_apply_on(self):
|
def validate_duplicate_apply_on(self):
|
||||||
field = apply_on_dict.get(self.apply_on)
|
field = apply_on_dict.get(self.apply_on)
|
||||||
|
if not field:
|
||||||
|
return False
|
||||||
|
|
||||||
values = [d.get(frappe.scrub(self.apply_on)) for d in self.get(field)]
|
values = [d.get(frappe.scrub(self.apply_on)) for d in self.get(field)]
|
||||||
|
|
||||||
if len(values) != len(set(values)):
|
if len(values) != len(set(values)):
|
||||||
@@ -419,4 +422,4 @@ def get_item_uoms(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
|
|
||||||
return frappe.get_all('UOM Conversion Detail',
|
return frappe.get_all('UOM Conversion Detail',
|
||||||
filters = {'parent': ('in', items), 'uom': ("like", "{0}%".format(txt))},
|
filters = {'parent': ('in', items), 'uom': ("like", "{0}%".format(txt))},
|
||||||
fields = ["distinct uom"], as_list=1)
|
fields = ["distinct uom"], as_list=1)
|
||||||
|
|||||||
@@ -495,7 +495,7 @@ def get_pricing_rule_items(pr_doc):
|
|||||||
|
|
||||||
if pr_doc.apply_rule_on_other:
|
if pr_doc.apply_rule_on_other:
|
||||||
apply_on = frappe.scrub(pr_doc.apply_rule_on_other)
|
apply_on = frappe.scrub(pr_doc.apply_rule_on_other)
|
||||||
apply_on_data.append(pr_doc.get(apply_on))
|
apply_on_data.append(pr_doc.get("other_" + apply_on))
|
||||||
|
|
||||||
return list(set(apply_on_data))
|
return list(set(apply_on_data))
|
||||||
|
|
||||||
|
|||||||
@@ -382,21 +382,11 @@ cur_frm.fields_dict['items'].grid.get_field("item_code").get_query = function(do
|
|||||||
|
|
||||||
cur_frm.fields_dict['credit_to'].get_query = function(doc) {
|
cur_frm.fields_dict['credit_to'].get_query = function(doc) {
|
||||||
// filter on Account
|
// filter on Account
|
||||||
if (doc.supplier) {
|
return {
|
||||||
return {
|
filters: {
|
||||||
filters: {
|
'account_type': 'Payable',
|
||||||
'account_type': 'Payable',
|
'is_group': 0,
|
||||||
'is_group': 0,
|
'company': doc.company
|
||||||
'company': doc.company
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
filters: {
|
|
||||||
'report_type': 'Balance Sheet',
|
|
||||||
'is_group': 0,
|
|
||||||
'company': doc.company
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"allow_import": 1,
|
"allow_import": 1,
|
||||||
"autoname": "naming_series:",
|
"autoname": "naming_series:",
|
||||||
"creation": "2013-05-21 16:16:39",
|
"creation": "2013-05-21 16:16:39",
|
||||||
@@ -417,6 +418,7 @@
|
|||||||
"fieldname": "contact_email",
|
"fieldname": "contact_email",
|
||||||
"fieldtype": "Small Text",
|
"fieldtype": "Small Text",
|
||||||
"label": "Contact Email",
|
"label": "Contact Email",
|
||||||
|
"options": "Email",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
@@ -705,7 +707,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "other_charges_calculation",
|
"fieldname": "other_charges_calculation",
|
||||||
"fieldtype": "Text",
|
"fieldtype": "Long Text",
|
||||||
"label": "Taxes and Charges Calculation",
|
"label": "Taxes and Charges Calculation",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"oldfieldtype": "HTML",
|
"oldfieldtype": "HTML",
|
||||||
@@ -1287,7 +1289,8 @@
|
|||||||
"icon": "fa fa-file-text",
|
"icon": "fa fa-file-text",
|
||||||
"idx": 204,
|
"idx": 204,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"modified": "2019-09-17 22:31:42.666601",
|
"links": [],
|
||||||
|
"modified": "2019-12-30 19:13:49.610538",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Purchase Invoice",
|
"name": "Purchase Invoice",
|
||||||
|
|||||||
@@ -556,22 +556,11 @@ cur_frm.cscript.cost_center = function(doc, cdt, cdn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cur_frm.set_query("debit_to", function(doc) {
|
cur_frm.set_query("debit_to", function(doc) {
|
||||||
// filter on Account
|
return {
|
||||||
if (doc.customer) {
|
filters: {
|
||||||
return {
|
'account_type': 'Receivable',
|
||||||
filters: {
|
'is_group': 0,
|
||||||
'account_type': 'Receivable',
|
'company': doc.company
|
||||||
'is_group': 0,
|
|
||||||
'company': doc.company
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
filters: {
|
|
||||||
'report_type': 'Balance Sheet',
|
|
||||||
'is_group': 0,
|
|
||||||
'company': doc.company
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"allow_import": 1,
|
"allow_import": 1,
|
||||||
"autoname": "naming_series:",
|
"autoname": "naming_series:",
|
||||||
"creation": "2013-05-24 19:29:05",
|
"creation": "2013-05-24 19:29:05",
|
||||||
@@ -774,7 +775,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "other_charges_calculation",
|
"fieldname": "other_charges_calculation",
|
||||||
"fieldtype": "Text",
|
"fieldtype": "Long Text",
|
||||||
"label": "Taxes and Charges Calculation",
|
"label": "Taxes and Charges Calculation",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"oldfieldtype": "HTML",
|
"oldfieldtype": "HTML",
|
||||||
@@ -1567,7 +1568,8 @@
|
|||||||
"icon": "fa fa-file-text",
|
"icon": "fa fa-file-text",
|
||||||
"idx": 181,
|
"idx": 181,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"modified": "2019-10-05 21:39:49.235990",
|
"links": [],
|
||||||
|
"modified": "2019-12-30 19:15:59.580414",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Sales Invoice",
|
"name": "Sales Invoice",
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
|
|
||||||
import unittest, copy, time
|
import unittest, copy, time
|
||||||
from frappe.utils import nowdate, flt, getdate, cint
|
from frappe.utils import nowdate, flt, getdate, cint, add_days
|
||||||
from frappe.model.dynamic_links import get_dynamic_link_map
|
from frappe.model.dynamic_links import get_dynamic_link_map
|
||||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry, get_qty_after_transaction
|
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry, get_qty_after_transaction
|
||||||
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import unlink_payment_on_cancel_of_invoice
|
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import unlink_payment_on_cancel_of_invoice
|
||||||
@@ -1847,6 +1847,26 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
self.assertEqual(data['billLists'][0]['vehicleNo'], 'KA12KA1234')
|
self.assertEqual(data['billLists'][0]['vehicleNo'], 'KA12KA1234')
|
||||||
self.assertEqual(data['billLists'][0]['itemList'][0]['taxableAmount'], 60000)
|
self.assertEqual(data['billLists'][0]['itemList'][0]['taxableAmount'], 60000)
|
||||||
|
|
||||||
|
def test_item_tax_validity(self):
|
||||||
|
item = frappe.get_doc("Item", "_Test Item 2")
|
||||||
|
|
||||||
|
if item.taxes:
|
||||||
|
item.taxes = []
|
||||||
|
item.save()
|
||||||
|
|
||||||
|
item.append("taxes", {
|
||||||
|
"item_tax_template": "_Test Item Tax Template 1",
|
||||||
|
"valid_from": add_days(nowdate(), 1)
|
||||||
|
})
|
||||||
|
|
||||||
|
item.save()
|
||||||
|
|
||||||
|
sales_invoice = create_sales_invoice(item = "_Test Item 2", do_not_save=1)
|
||||||
|
sales_invoice.items[0].item_tax_template = "_Test Item Tax Template 1"
|
||||||
|
self.assertRaises(frappe.ValidationError, sales_invoice.save)
|
||||||
|
|
||||||
|
item.taxes = []
|
||||||
|
item.save()
|
||||||
|
|
||||||
def create_sales_invoice(**args):
|
def create_sales_invoice(**args):
|
||||||
si = frappe.new_doc("Sales Invoice")
|
si = frappe.new_doc("Sales Invoice")
|
||||||
|
|||||||
@@ -188,7 +188,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"modified": "2019-11-07 13:31:17.999744",
|
"modified": "2019-12-20 14:48:01.990600",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Share Transfer",
|
"name": "Share Transfer",
|
||||||
@@ -196,6 +196,7 @@
|
|||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 1,
|
"amend": 1,
|
||||||
|
"cancel": 1,
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
@@ -221,6 +222,7 @@
|
|||||||
"write": 1
|
"write": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"cancel": 1,
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
@@ -230,6 +232,7 @@
|
|||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "Accounts Manager",
|
"role": "Accounts Manager",
|
||||||
"share": 1,
|
"share": 1,
|
||||||
|
"submit": 1,
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -338,6 +338,16 @@ class Subscription(Document):
|
|||||||
|
|
||||||
# Check invoice dates and make sure it doesn't have outstanding invoices
|
# Check invoice dates and make sure it doesn't have outstanding invoices
|
||||||
return getdate(nowdate()) >= getdate(self.current_invoice_start) and not self.has_outstanding_invoice()
|
return getdate(nowdate()) >= getdate(self.current_invoice_start) and not self.has_outstanding_invoice()
|
||||||
|
|
||||||
|
def is_current_invoice_paid(self):
|
||||||
|
if self.is_new_subscription():
|
||||||
|
return False
|
||||||
|
|
||||||
|
last_invoice = frappe.get_doc('Sales Invoice', self.invoices[-1].invoice)
|
||||||
|
if getdate(last_invoice.posting_date) == getdate(self.current_invoice_start) and last_invoice.status == 'Paid':
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
def process_for_active(self):
|
def process_for_active(self):
|
||||||
"""
|
"""
|
||||||
@@ -348,7 +358,7 @@ class Subscription(Document):
|
|||||||
2. Change the `Subscription` status to 'Past Due Date'
|
2. Change the `Subscription` status to 'Past Due Date'
|
||||||
3. Change the `Subscription` status to 'Cancelled'
|
3. Change the `Subscription` status to 'Cancelled'
|
||||||
"""
|
"""
|
||||||
if self.is_postpaid_to_invoice() or self.is_prepaid_to_invoice():
|
if not self.is_current_invoice_paid() and (self.is_postpaid_to_invoice() or self.is_prepaid_to_invoice()):
|
||||||
self.generate_invoice()
|
self.generate_invoice()
|
||||||
if self.current_invoice_is_past_due():
|
if self.current_invoice_is_past_due():
|
||||||
self.status = 'Past Due Date'
|
self.status = 'Past Due Date'
|
||||||
|
|||||||
@@ -1,134 +1,134 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"allow_copy": 0,
|
||||||
"allow_events_in_timeline": 0,
|
"allow_events_in_timeline": 0,
|
||||||
"allow_guest_to_view": 0,
|
"allow_guest_to_view": 0,
|
||||||
"allow_import": 0,
|
"allow_import": 0,
|
||||||
"allow_rename": 0,
|
"allow_rename": 0,
|
||||||
"autoname": "field:title",
|
"autoname": "field:title",
|
||||||
"beta": 0,
|
"beta": 0,
|
||||||
"creation": "2018-11-22 23:38:39.668804",
|
"creation": "2018-11-22 23:38:39.668804",
|
||||||
"custom": 0,
|
"custom": 0,
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "",
|
"document_type": "",
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_in_quick_entry": 0,
|
"allow_in_quick_entry": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fieldname": "title",
|
"fieldname": "title",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"in_global_search": 0,
|
"in_global_search": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 0,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Title",
|
"label": "Title",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"translatable": 0,
|
"translatable": 0,
|
||||||
"unique": 1
|
"unique": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
"has_web_view": 0,
|
||||||
"hide_heading": 0,
|
"hide_heading": 0,
|
||||||
"hide_toolbar": 0,
|
"hide_toolbar": 0,
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"image_view": 0,
|
"image_view": 0,
|
||||||
"in_create": 0,
|
"in_create": 0,
|
||||||
"is_submittable": 0,
|
"is_submittable": 0,
|
||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2018-11-22 23:38:39.668804",
|
"modified": "2020-01-15 17:14:28.951793",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Tax Category",
|
"name": "Tax Category",
|
||||||
"name_case": "",
|
"name_case": "",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"amend": 0,
|
||||||
"cancel": 0,
|
"cancel": 0,
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 1,
|
"export": 1,
|
||||||
"if_owner": 0,
|
"if_owner": 0,
|
||||||
"import": 0,
|
"import": 0,
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "System Manager",
|
"role": "System Manager",
|
||||||
"set_user_permissions": 0,
|
"set_user_permissions": 0,
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 0,
|
"submit": 0,
|
||||||
"write": 1
|
"write": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"amend": 0,
|
||||||
"cancel": 0,
|
"cancel": 0,
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 1,
|
"export": 1,
|
||||||
"if_owner": 0,
|
"if_owner": 0,
|
||||||
"import": 0,
|
"import": 0,
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "Accounts Manager",
|
"role": "Accounts Manager",
|
||||||
"set_user_permissions": 0,
|
"set_user_permissions": 0,
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 0,
|
"submit": 0,
|
||||||
"write": 1
|
"write": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"amend": 0,
|
||||||
"cancel": 0,
|
"cancel": 0,
|
||||||
"create": 0,
|
"create": 0,
|
||||||
"delete": 0,
|
"delete": 0,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 1,
|
"export": 1,
|
||||||
"if_owner": 0,
|
"if_owner": 0,
|
||||||
"import": 0,
|
"import": 0,
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "Accounts User",
|
"role": "Accounts User",
|
||||||
"set_user_permissions": 0,
|
"set_user_permissions": 0,
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 0,
|
"submit": 0,
|
||||||
"write": 0
|
"write": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"read_only_onload": 0,
|
"read_only_onload": 0,
|
||||||
"show_name_in_global_search": 0,
|
"show_name_in_global_search": 0,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"track_changes": 1,
|
"track_changes": 1,
|
||||||
"track_seen": 0,
|
"track_seen": 0,
|
||||||
"track_views": 0
|
"track_views": 0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="right" colspan="3" ><strong>Total (debit) </strong></td>
|
<td class="right" colspan="3" ><strong>Total (debit) </strong></td>
|
||||||
<td class="left" >{{ gl | sum(attribute='debit') }}</td>
|
<td class="left" >{{ frappe.format((gl | sum(attribute="debit")), {fieldtype: "Currency"}) }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="top-bottom" colspan="5"><strong>Credit</strong></td>
|
<td class="top-bottom" colspan="5"><strong>Credit</strong></td>
|
||||||
@@ -69,7 +69,7 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="right" colspan="3"><strong>Total (credit) </strong></td>
|
<td class="right" colspan="3"><strong>Total (credit) </strong></td>
|
||||||
<td class="left" >{{ gl | sum(attribute='credit') }}</td>
|
<td class="left" >{{ frappe.format((gl | sum(attribute="credit")), {fieldtype: "Currency"}) }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ class ReceivablePayableReport(object):
|
|||||||
row.outstanding = flt(row.invoiced - row.paid - row.credit_note, self.currency_precision)
|
row.outstanding = flt(row.invoiced - row.paid - row.credit_note, self.currency_precision)
|
||||||
row.invoice_grand_total = row.invoiced
|
row.invoice_grand_total = row.invoiced
|
||||||
|
|
||||||
if abs(row.outstanding) > 0.1/10 ** self.currency_precision:
|
if abs(row.outstanding) > 1.0/10 ** self.currency_precision:
|
||||||
# non-zero oustanding, we must consider this row
|
# non-zero oustanding, we must consider this row
|
||||||
|
|
||||||
if self.is_invoice(row) and self.filters.based_on_payment_terms:
|
if self.is_invoice(row) and self.filters.based_on_payment_terms:
|
||||||
@@ -285,7 +285,7 @@ class ReceivablePayableReport(object):
|
|||||||
|
|
||||||
def set_party_details(self, row):
|
def set_party_details(self, row):
|
||||||
# customer / supplier name
|
# customer / supplier name
|
||||||
party_details = self.get_party_details(row.party)
|
party_details = self.get_party_details(row.party) or {}
|
||||||
row.update(party_details)
|
row.update(party_details)
|
||||||
if self.filters.get(scrub(self.filters.party_type)):
|
if self.filters.get(scrub(self.filters.party_type)):
|
||||||
row.currency = row.account_currency
|
row.currency = row.account_currency
|
||||||
|
|||||||
@@ -46,13 +46,24 @@ frappe.query_reports["Budget Variance Report"] = {
|
|||||||
fieldtype: "Select",
|
fieldtype: "Select",
|
||||||
options: ["Cost Center", "Project"],
|
options: ["Cost Center", "Project"],
|
||||||
default: "Cost Center",
|
default: "Cost Center",
|
||||||
reqd: 1
|
reqd: 1,
|
||||||
|
on_change: function() {
|
||||||
|
frappe.query_report.set_filter_value("budget_against_filter", []);
|
||||||
|
frappe.query_report.refresh();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldname: "cost_center",
|
fieldname:"budget_against_filter",
|
||||||
label: __("Cost Center"),
|
label: __('Dimension Filter'),
|
||||||
fieldtype: "Link",
|
fieldtype: "MultiSelectList",
|
||||||
options: "Cost Center"
|
get_data: function(txt) {
|
||||||
|
if (!frappe.query_report.filters) return;
|
||||||
|
|
||||||
|
let budget_against = frappe.query_report.get_filter_value('budget_against');
|
||||||
|
if (!budget_against) return;
|
||||||
|
|
||||||
|
return frappe.db.get_link_options(budget_against, txt);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldname:"show_cumulative",
|
fieldname:"show_cumulative",
|
||||||
|
|||||||
@@ -12,22 +12,22 @@ from six import iteritems
|
|||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
if not filters: filters = {}
|
if not filters: filters = {}
|
||||||
validate_filters(filters)
|
|
||||||
columns = get_columns(filters)
|
columns = get_columns(filters)
|
||||||
if filters.get("cost_center"):
|
if filters.get("budget_against_filter"):
|
||||||
cost_centers = [filters.get("cost_center")]
|
dimensions = filters.get("budget_against_filter")
|
||||||
else:
|
else:
|
||||||
cost_centers = get_cost_centers(filters)
|
dimensions = get_cost_centers(filters)
|
||||||
|
|
||||||
period_month_ranges = get_period_month_ranges(filters["period"], filters["from_fiscal_year"])
|
period_month_ranges = get_period_month_ranges(filters["period"], filters["from_fiscal_year"])
|
||||||
cam_map = get_cost_center_account_month_map(filters)
|
cam_map = get_dimension_account_month_map(filters)
|
||||||
|
|
||||||
data = []
|
data = []
|
||||||
for cost_center in cost_centers:
|
for dimension in dimensions:
|
||||||
cost_center_items = cam_map.get(cost_center)
|
dimension_items = cam_map.get(dimension)
|
||||||
if cost_center_items:
|
if dimension_items:
|
||||||
for account, monthwise_data in iteritems(cost_center_items):
|
for account, monthwise_data in iteritems(dimension_items):
|
||||||
row = [cost_center, account]
|
row = [dimension, account]
|
||||||
totals = [0, 0, 0]
|
totals = [0, 0, 0]
|
||||||
for year in get_fiscal_years(filters):
|
for year in get_fiscal_years(filters):
|
||||||
last_total = 0
|
last_total = 0
|
||||||
@@ -55,10 +55,6 @@ def execute(filters=None):
|
|||||||
|
|
||||||
return columns, data
|
return columns, data
|
||||||
|
|
||||||
def validate_filters(filters):
|
|
||||||
if filters.get("budget_against") != "Cost Center" and filters.get("cost_center"):
|
|
||||||
frappe.throw(_("Filter based on Cost Center is only applicable if Budget Against is selected as Cost Center"))
|
|
||||||
|
|
||||||
def get_columns(filters):
|
def get_columns(filters):
|
||||||
columns = [_(filters.get("budget_against")) + ":Link/%s:150"%(filters.get("budget_against")), _("Account") + ":Link/Account:150"]
|
columns = [_(filters.get("budget_against")) + ":Link/%s:150"%(filters.get("budget_against")), _("Account") + ":Link/Account:150"]
|
||||||
|
|
||||||
@@ -98,11 +94,12 @@ def get_cost_centers(filters):
|
|||||||
else:
|
else:
|
||||||
return frappe.db.sql_list("""select name from `tab{tab}`""".format(tab=filters.get("budget_against"))) #nosec
|
return frappe.db.sql_list("""select name from `tab{tab}`""".format(tab=filters.get("budget_against"))) #nosec
|
||||||
|
|
||||||
#Get cost center & target details
|
#Get dimension & target details
|
||||||
def get_cost_center_target_details(filters):
|
def get_dimension_target_details(filters):
|
||||||
cond = ""
|
cond = ""
|
||||||
if filters.get("cost_center"):
|
if filters.get("budget_against_filter"):
|
||||||
cond += " and b.cost_center=%s" % frappe.db.escape(filters.get("cost_center"))
|
cond += " and b.{budget_against} in (%s)".format(budget_against = \
|
||||||
|
frappe.scrub(filters.get('budget_against'))) % ', '.join(['%s']* len(filters.get('budget_against_filter')))
|
||||||
|
|
||||||
return frappe.db.sql("""
|
return frappe.db.sql("""
|
||||||
select b.{budget_against} as budget_against, b.monthly_distribution, ba.account, ba.budget_amount,b.fiscal_year
|
select b.{budget_against} as budget_against, b.monthly_distribution, ba.account, ba.budget_amount,b.fiscal_year
|
||||||
@@ -110,8 +107,8 @@ def get_cost_center_target_details(filters):
|
|||||||
where b.name=ba.parent and b.docstatus = 1 and b.fiscal_year between %s and %s
|
where b.name=ba.parent and b.docstatus = 1 and b.fiscal_year between %s and %s
|
||||||
and b.budget_against = %s and b.company=%s {cond} order by b.fiscal_year
|
and b.budget_against = %s and b.company=%s {cond} order by b.fiscal_year
|
||||||
""".format(budget_against=filters.get("budget_against").replace(" ", "_").lower(), cond=cond),
|
""".format(budget_against=filters.get("budget_against").replace(" ", "_").lower(), cond=cond),
|
||||||
(filters.from_fiscal_year,filters.to_fiscal_year,filters.budget_against, filters.company), as_dict=True)
|
tuple([filters.from_fiscal_year,filters.to_fiscal_year,filters.budget_against, filters.company] + filters.get('budget_against_filter')),
|
||||||
|
as_dict=True)
|
||||||
|
|
||||||
|
|
||||||
#Get target distribution details of accounts of cost center
|
#Get target distribution details of accounts of cost center
|
||||||
@@ -153,14 +150,14 @@ def get_actual_details(name, filters):
|
|||||||
|
|
||||||
return cc_actual_details
|
return cc_actual_details
|
||||||
|
|
||||||
def get_cost_center_account_month_map(filters):
|
def get_dimension_account_month_map(filters):
|
||||||
import datetime
|
import datetime
|
||||||
cost_center_target_details = get_cost_center_target_details(filters)
|
dimension_target_details = get_dimension_target_details(filters)
|
||||||
tdd = get_target_distribution_details(filters)
|
tdd = get_target_distribution_details(filters)
|
||||||
|
|
||||||
cam_map = {}
|
cam_map = {}
|
||||||
|
|
||||||
for ccd in cost_center_target_details:
|
for ccd in dimension_target_details:
|
||||||
actual_details = get_actual_details(ccd.budget_against, filters)
|
actual_details = get_actual_details(ccd.budget_against, filters)
|
||||||
|
|
||||||
for month_id in range(1, 13):
|
for month_id in range(1, 13):
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for(var i=0, l=data.length-1; i<l; i++) { %}
|
{% for(var i=0, l=data.length; i<l; i++) { %}
|
||||||
<tr>
|
<tr>
|
||||||
{% if(data[i].posting_date) { %}
|
{% if(data[i].posting_date) { %}
|
||||||
<td>{%= frappe.datetime.str_to_user(data[i].posting_date) %}</td>
|
<td>{%= frappe.datetime.str_to_user(data[i].posting_date) %}</td>
|
||||||
|
|||||||
@@ -38,32 +38,46 @@ def _execute(filters, additional_table_columns=None, additional_query_columns=No
|
|||||||
cost_center = list(set(invoice_cc_wh_map.get(inv.name, {}).get("cost_center", [])))
|
cost_center = list(set(invoice_cc_wh_map.get(inv.name, {}).get("cost_center", [])))
|
||||||
warehouse = list(set(invoice_cc_wh_map.get(inv.name, {}).get("warehouse", [])))
|
warehouse = list(set(invoice_cc_wh_map.get(inv.name, {}).get("warehouse", [])))
|
||||||
|
|
||||||
row = [
|
row = {
|
||||||
inv.name, inv.posting_date, inv.customer, inv.customer_name
|
'invoice': inv.name,
|
||||||
]
|
'posting_date': inv.posting_date,
|
||||||
|
'customer': inv.customer,
|
||||||
|
'customer_name': inv.customer_name
|
||||||
|
}
|
||||||
|
|
||||||
if additional_query_columns:
|
if additional_query_columns:
|
||||||
for col in additional_query_columns:
|
for col in additional_query_columns:
|
||||||
row.append(inv.get(col))
|
row.update({
|
||||||
|
col: inv.get(col)
|
||||||
|
})
|
||||||
|
|
||||||
|
row.update({
|
||||||
|
'customer_group': inv.get("customer_group"),
|
||||||
|
'territory': inv.get("territory"),
|
||||||
|
'tax_id': inv.get("tax_id"),
|
||||||
|
'receivable_account': inv.debit_to,
|
||||||
|
'mode_of_payment': ", ".join(mode_of_payments.get(inv.name, [])),
|
||||||
|
'project': inv.project,
|
||||||
|
'owner': inv.owner,
|
||||||
|
'remarks': inv.remarks,
|
||||||
|
'sales_order': ", ".join(sales_order),
|
||||||
|
'delivery_note': ", ".join(delivery_note),
|
||||||
|
'cost_center': ", ".join(cost_center),
|
||||||
|
'warehouse': ", ".join(warehouse),
|
||||||
|
'currency': company_currency
|
||||||
|
})
|
||||||
|
|
||||||
row +=[
|
|
||||||
inv.get("customer_group"),
|
|
||||||
inv.get("territory"),
|
|
||||||
inv.get("tax_id"),
|
|
||||||
inv.debit_to, ", ".join(mode_of_payments.get(inv.name, [])),
|
|
||||||
inv.project, inv.owner, inv.remarks,
|
|
||||||
", ".join(sales_order), ", ".join(delivery_note),", ".join(cost_center),
|
|
||||||
", ".join(warehouse), company_currency
|
|
||||||
]
|
|
||||||
# map income values
|
# map income values
|
||||||
base_net_total = 0
|
base_net_total = 0
|
||||||
for income_acc in income_accounts:
|
for income_acc in income_accounts:
|
||||||
income_amount = flt(invoice_income_map.get(inv.name, {}).get(income_acc))
|
income_amount = flt(invoice_income_map.get(inv.name, {}).get(income_acc))
|
||||||
base_net_total += income_amount
|
base_net_total += income_amount
|
||||||
row.append(income_amount)
|
row.update({
|
||||||
|
frappe.scrub(income_acc): income_amount
|
||||||
|
})
|
||||||
|
|
||||||
# net total
|
# net total
|
||||||
row.append(base_net_total or inv.base_net_total)
|
row.update({'net_total': base_net_total or inv.base_net_total})
|
||||||
|
|
||||||
# tax account
|
# tax account
|
||||||
total_tax = 0
|
total_tax = 0
|
||||||
@@ -72,10 +86,18 @@ def _execute(filters, additional_table_columns=None, additional_query_columns=No
|
|||||||
tax_amount_precision = get_field_precision(frappe.get_meta("Sales Taxes and Charges").get_field("tax_amount"), currency=company_currency) or 2
|
tax_amount_precision = get_field_precision(frappe.get_meta("Sales Taxes and Charges").get_field("tax_amount"), currency=company_currency) or 2
|
||||||
tax_amount = flt(invoice_tax_map.get(inv.name, {}).get(tax_acc), tax_amount_precision)
|
tax_amount = flt(invoice_tax_map.get(inv.name, {}).get(tax_acc), tax_amount_precision)
|
||||||
total_tax += tax_amount
|
total_tax += tax_amount
|
||||||
row.append(tax_amount)
|
row.update({
|
||||||
|
frappe.scrub(tax_acc): tax_amount
|
||||||
|
})
|
||||||
|
|
||||||
# total tax, grand total, outstanding amount & rounded total
|
# total tax, grand total, outstanding amount & rounded total
|
||||||
row += [total_tax, inv.base_grand_total, inv.base_rounded_total, inv.outstanding_amount]
|
|
||||||
|
row.update({
|
||||||
|
'tax_total': total_tax,
|
||||||
|
'grand_total': inv.base_grand_total,
|
||||||
|
'rounded_total': inv.base_rounded_total,
|
||||||
|
'outstanding_amount': inv.outstanding_amount
|
||||||
|
})
|
||||||
|
|
||||||
data.append(row)
|
data.append(row)
|
||||||
|
|
||||||
@@ -84,19 +106,118 @@ def _execute(filters, additional_table_columns=None, additional_query_columns=No
|
|||||||
def get_columns(invoice_list, additional_table_columns):
|
def get_columns(invoice_list, additional_table_columns):
|
||||||
"""return columns based on filters"""
|
"""return columns based on filters"""
|
||||||
columns = [
|
columns = [
|
||||||
_("Invoice") + ":Link/Sales Invoice:120", _("Posting Date") + ":Date:80",
|
{
|
||||||
_("Customer") + ":Link/Customer:120", _("Customer Name") + "::120"
|
'label': _("Invoice"),
|
||||||
|
'fieldname': 'invoice',
|
||||||
|
'fieldtype': 'Link',
|
||||||
|
'options': 'Sales Invoice',
|
||||||
|
'width': 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'label': _("Posting Date"),
|
||||||
|
'fieldname': 'posting_date',
|
||||||
|
'fieldtype': 'Date',
|
||||||
|
'width': 80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'label': _("Customer"),
|
||||||
|
'fieldname': 'customer',
|
||||||
|
'fieldtype': 'Link',
|
||||||
|
'options': 'Customer',
|
||||||
|
'width': 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'label': _("Customer Name"),
|
||||||
|
'fieldname': 'customer_name',
|
||||||
|
'fieldtype': 'Data',
|
||||||
|
'width': 120
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
if additional_table_columns:
|
if additional_table_columns:
|
||||||
columns += additional_table_columns
|
columns += additional_table_columns
|
||||||
|
|
||||||
columns +=[
|
columns +=[
|
||||||
_("Customer Group") + ":Link/Customer Group:120", _("Territory") + ":Link/Territory:80",
|
{
|
||||||
_("Tax Id") + "::80", _("Receivable Account") + ":Link/Account:120", _("Mode of Payment") + "::120",
|
'label': _("Custmer Group"),
|
||||||
_("Project") +":Link/Project:80", _("Owner") + "::150", _("Remarks") + "::150",
|
'fieldname': 'customer_group',
|
||||||
_("Sales Order") + ":Link/Sales Order:100", _("Delivery Note") + ":Link/Delivery Note:100",
|
'fieldtype': 'Link',
|
||||||
_("Cost Center") + ":Link/Cost Center:100", _("Warehouse") + ":Link/Warehouse:100",
|
'options': 'Customer Group',
|
||||||
|
'width': 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'label': _("Territory"),
|
||||||
|
'fieldname': 'territory',
|
||||||
|
'fieldtype': 'Link',
|
||||||
|
'options': 'Territory',
|
||||||
|
'width': 80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'label': _("Tax Id"),
|
||||||
|
'fieldname': 'tax_id',
|
||||||
|
'fieldtype': 'Data',
|
||||||
|
'width': 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'label': _("Receivable Account"),
|
||||||
|
'fieldname': 'receivable_account',
|
||||||
|
'fieldtype': 'Link',
|
||||||
|
'options': 'Account',
|
||||||
|
'width': 80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'label': _("Mode Of Payment"),
|
||||||
|
'fieldname': 'mode_of_payment',
|
||||||
|
'fieldtype': 'Data',
|
||||||
|
'width': 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'label': _("Project"),
|
||||||
|
'fieldname': 'project',
|
||||||
|
'fieldtype': 'Link',
|
||||||
|
'options': 'project',
|
||||||
|
'width': 80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'label': _("Owner"),
|
||||||
|
'fieldname': 'owner',
|
||||||
|
'fieldtype': 'Data',
|
||||||
|
'width': 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'label': _("Remarks"),
|
||||||
|
'fieldname': 'remarks',
|
||||||
|
'fieldtype': 'Data',
|
||||||
|
'width': 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'label': _("Sales Order"),
|
||||||
|
'fieldname': 'sales_order',
|
||||||
|
'fieldtype': 'Link',
|
||||||
|
'options': 'Sales Order',
|
||||||
|
'width': 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'label': _("Delivery Note"),
|
||||||
|
'fieldname': 'delivery_note',
|
||||||
|
'fieldtype': 'Link',
|
||||||
|
'options': 'Delivery Note',
|
||||||
|
'width': 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'label': _("Cost Center"),
|
||||||
|
'fieldname': 'cost_center',
|
||||||
|
'fieldtype': 'Link',
|
||||||
|
'options': 'Cost Center',
|
||||||
|
'width': 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'label': _("Warehouse"),
|
||||||
|
'fieldname': 'warehouse',
|
||||||
|
'fieldtype': 'Link',
|
||||||
|
'options': 'Warehouse',
|
||||||
|
'width': 100
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "currency",
|
"fieldname": "currency",
|
||||||
"label": _("Currency"),
|
"label": _("Currency"),
|
||||||
@@ -105,7 +226,10 @@ def get_columns(invoice_list, additional_table_columns):
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
income_accounts = tax_accounts = income_columns = tax_columns = []
|
income_accounts = []
|
||||||
|
tax_accounts = []
|
||||||
|
income_columns = []
|
||||||
|
tax_columns = []
|
||||||
|
|
||||||
if invoice_list:
|
if invoice_list:
|
||||||
income_accounts = frappe.db.sql_list("""select distinct income_account
|
income_accounts = frappe.db.sql_list("""select distinct income_account
|
||||||
@@ -119,14 +243,65 @@ def get_columns(invoice_list, additional_table_columns):
|
|||||||
and parent in (%s) order by account_head""" %
|
and parent in (%s) order by account_head""" %
|
||||||
', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]))
|
', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]))
|
||||||
|
|
||||||
income_columns = [(account + ":Currency/currency:120") for account in income_accounts]
|
for account in income_accounts:
|
||||||
|
income_columns.append({
|
||||||
|
"label": account,
|
||||||
|
"fieldname": frappe.scrub(account),
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"options": 'currency',
|
||||||
|
"width": 120
|
||||||
|
})
|
||||||
|
|
||||||
for account in tax_accounts:
|
for account in tax_accounts:
|
||||||
if account not in income_accounts:
|
if account not in income_accounts:
|
||||||
tax_columns.append(account + ":Currency/currency:120")
|
tax_columns.append({
|
||||||
|
"label": account,
|
||||||
|
"fieldname": frappe.scrub(account),
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"options": 'currency',
|
||||||
|
"width": 120
|
||||||
|
})
|
||||||
|
|
||||||
columns = columns + income_columns + [_("Net Total") + ":Currency/currency:120"] + tax_columns + \
|
net_total_column = [{
|
||||||
[_("Total Tax") + ":Currency/currency:120", _("Grand Total") + ":Currency/currency:120",
|
"label": _("Net Total"),
|
||||||
_("Rounded Total") + ":Currency/currency:120", _("Outstanding Amount") + ":Currency/currency:120"]
|
"fieldname": "net_total",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"options": 'currency',
|
||||||
|
"width": 120
|
||||||
|
}]
|
||||||
|
|
||||||
|
total_columns = [
|
||||||
|
{
|
||||||
|
"label": _("Tax Total"),
|
||||||
|
"fieldname": "tax_total",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"options": 'currency',
|
||||||
|
"width": 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Grand Total"),
|
||||||
|
"fieldname": "grand_total",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"options": 'currency',
|
||||||
|
"width": 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Rounded Total"),
|
||||||
|
"fieldname": "rounded_total",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"options": 'currency',
|
||||||
|
"width": 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Outstanding Amount"),
|
||||||
|
"fieldname": "outstanding_amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"options": 'currency',
|
||||||
|
"width": 120
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
columns = columns + income_columns + net_total_column + tax_columns + total_columns
|
||||||
|
|
||||||
return columns, income_accounts, tax_accounts
|
return columns, income_accounts, tax_accounts
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,21 @@ frappe.query_reports["Trial Balance for Party"] = {
|
|||||||
return party_type;
|
return party_type;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "account",
|
||||||
|
"label": __("Account"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Account",
|
||||||
|
"get_query": function() {
|
||||||
|
var company = frappe.query_report.get_filter_value('company');
|
||||||
|
return {
|
||||||
|
"doctype": "Account",
|
||||||
|
"filters": {
|
||||||
|
"company": company,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "show_zero_values",
|
"fieldname": "show_zero_values",
|
||||||
"label": __("Show zero values"),
|
"label": __("Show zero values"),
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ def execute(filters=None):
|
|||||||
def get_data(filters, show_party_name):
|
def get_data(filters, show_party_name):
|
||||||
if filters.get('party_type') in ('Customer', 'Supplier', 'Employee', 'Member'):
|
if filters.get('party_type') in ('Customer', 'Supplier', 'Employee', 'Member'):
|
||||||
party_name_field = "{0}_name".format(frappe.scrub(filters.get('party_type')))
|
party_name_field = "{0}_name".format(frappe.scrub(filters.get('party_type')))
|
||||||
if filters.get('party_type') == 'Student':
|
elif filters.get('party_type') == 'Student':
|
||||||
party_name_field = 'first_name'
|
party_name_field = 'first_name'
|
||||||
elif filters.get('party_type') == 'Shareholder':
|
elif filters.get('party_type') == 'Shareholder':
|
||||||
party_name_field = 'title'
|
party_name_field = 'title'
|
||||||
@@ -96,13 +96,19 @@ def get_data(filters, show_party_name):
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
def get_opening_balances(filters):
|
def get_opening_balances(filters):
|
||||||
|
|
||||||
|
account_filter = ''
|
||||||
|
if filters.get('account'):
|
||||||
|
account_filter = "and account = %s" % (frappe.db.escape(filters.get('account')))
|
||||||
|
|
||||||
gle = frappe.db.sql("""
|
gle = frappe.db.sql("""
|
||||||
select party, sum(debit) as opening_debit, sum(credit) as opening_credit
|
select party, sum(debit) as opening_debit, sum(credit) as opening_credit
|
||||||
from `tabGL Entry`
|
from `tabGL Entry`
|
||||||
where company=%(company)s
|
where company=%(company)s
|
||||||
and ifnull(party_type, '') = %(party_type)s and ifnull(party, '') != ''
|
and ifnull(party_type, '') = %(party_type)s and ifnull(party, '') != ''
|
||||||
and (posting_date < %(from_date)s or ifnull(is_opening, 'No') = 'Yes')
|
and (posting_date < %(from_date)s or ifnull(is_opening, 'No') = 'Yes')
|
||||||
group by party""", {
|
{account_filter}
|
||||||
|
group by party""".format(account_filter=account_filter), {
|
||||||
"company": filters.company,
|
"company": filters.company,
|
||||||
"from_date": filters.from_date,
|
"from_date": filters.from_date,
|
||||||
"party_type": filters.party_type
|
"party_type": filters.party_type
|
||||||
@@ -116,6 +122,11 @@ def get_opening_balances(filters):
|
|||||||
return opening
|
return opening
|
||||||
|
|
||||||
def get_balances_within_period(filters):
|
def get_balances_within_period(filters):
|
||||||
|
|
||||||
|
account_filter = ''
|
||||||
|
if filters.get('account'):
|
||||||
|
account_filter = "and account = %s" % (frappe.db.escape(filters.get('account')))
|
||||||
|
|
||||||
gle = frappe.db.sql("""
|
gle = frappe.db.sql("""
|
||||||
select party, sum(debit) as debit, sum(credit) as credit
|
select party, sum(debit) as debit, sum(credit) as credit
|
||||||
from `tabGL Entry`
|
from `tabGL Entry`
|
||||||
@@ -123,7 +134,8 @@ def get_balances_within_period(filters):
|
|||||||
and ifnull(party_type, '') = %(party_type)s and ifnull(party, '') != ''
|
and ifnull(party_type, '') = %(party_type)s and ifnull(party, '') != ''
|
||||||
and posting_date >= %(from_date)s and posting_date <= %(to_date)s
|
and posting_date >= %(from_date)s and posting_date <= %(to_date)s
|
||||||
and ifnull(is_opening, 'No') = 'No'
|
and ifnull(is_opening, 'No') = 'No'
|
||||||
group by party""", {
|
{account_filter}
|
||||||
|
group by party""".format(account_filter=account_filter), {
|
||||||
"company": filters.company,
|
"company": filters.company,
|
||||||
"from_date": filters.from_date,
|
"from_date": filters.from_date,
|
||||||
"to_date": filters.to_date,
|
"to_date": filters.to_date,
|
||||||
|
|||||||
@@ -891,3 +891,9 @@ def get_allow_cost_center_in_entry_of_bs_account():
|
|||||||
def generator():
|
def generator():
|
||||||
return cint(frappe.db.get_value('Accounts Settings', None, 'allow_cost_center_in_entry_of_bs_account'))
|
return cint(frappe.db.get_value('Accounts Settings', None, 'allow_cost_center_in_entry_of_bs_account'))
|
||||||
return frappe.local_cache("get_allow_cost_center_in_entry_of_bs_account", (), generator, regenerate_if_none=True)
|
return frappe.local_cache("get_allow_cost_center_in_entry_of_bs_account", (), generator, regenerate_if_none=True)
|
||||||
|
|
||||||
|
def get_stock_accounts(company):
|
||||||
|
return frappe.get_all("Account", filters = {
|
||||||
|
"account_type": "Stock",
|
||||||
|
"company": company
|
||||||
|
})
|
||||||
@@ -144,6 +144,10 @@ frappe.ui.form.on('Asset', {
|
|||||||
frm.set_df_property('purchase_invoice', 'read_only', 1);
|
frm.set_df_property('purchase_invoice', 'read_only', 1);
|
||||||
frm.set_df_property('purchase_receipt', 'read_only', 1);
|
frm.set_df_property('purchase_receipt', 'read_only', 1);
|
||||||
}
|
}
|
||||||
|
else if (frm.doc.is_existing_asset) {
|
||||||
|
frm.toggle_reqd('purchase_receipt', 0);
|
||||||
|
frm.toggle_reqd('purchase_invoice', 0);
|
||||||
|
}
|
||||||
else if (frm.doc.purchase_receipt) {
|
else if (frm.doc.purchase_receipt) {
|
||||||
// if purchase receipt link is set then set PI disabled
|
// if purchase receipt link is set then set PI disabled
|
||||||
frm.toggle_reqd('purchase_invoice', 0);
|
frm.toggle_reqd('purchase_invoice', 0);
|
||||||
@@ -256,6 +260,7 @@ frappe.ui.form.on('Asset', {
|
|||||||
},
|
},
|
||||||
|
|
||||||
is_existing_asset: function(frm) {
|
is_existing_asset: function(frm) {
|
||||||
|
frm.trigger("toggle_reference_doc");
|
||||||
// frm.toggle_reqd("next_depreciation_date", (!frm.doc.is_existing_asset && frm.doc.calculate_depreciation));
|
// frm.toggle_reqd("next_depreciation_date", (!frm.doc.is_existing_asset && frm.doc.calculate_depreciation));
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -333,25 +338,12 @@ frappe.ui.form.on('Asset', {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
purchase_receipt: function(frm) {
|
purchase_receipt: (frm) => {
|
||||||
frm.trigger('toggle_reference_doc');
|
frm.trigger('toggle_reference_doc');
|
||||||
|
|
||||||
if (frm.doc.purchase_receipt) {
|
if (frm.doc.purchase_receipt) {
|
||||||
if (frm.doc.item_code) {
|
if (frm.doc.item_code) {
|
||||||
frappe.db.get_doc('Purchase Receipt', frm.doc.purchase_receipt).then(pr_doc => {
|
frappe.db.get_doc('Purchase Receipt', frm.doc.purchase_receipt).then(pr_doc => {
|
||||||
frm.set_value('company', pr_doc.company);
|
frm.events.set_values_from_purchase_doc(frm, 'Purchase Receipt', pr_doc)
|
||||||
frm.set_value('purchase_date', pr_doc.posting_date);
|
|
||||||
const item = pr_doc.items.find(item => item.item_code === frm.doc.item_code);
|
|
||||||
if (!item) {
|
|
||||||
frm.set_value('purchase_receipt', '');
|
|
||||||
frappe.msgprint({
|
|
||||||
title: __('Invalid Purchase Receipt'),
|
|
||||||
message: __("The selected Purchase Receipt doesn't contains selected Asset Item."),
|
|
||||||
indicator: 'red'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
frm.set_value('gross_purchase_amount', item.base_net_rate);
|
|
||||||
frm.set_value('location', item.asset_location);
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
frm.set_value('purchase_receipt', '');
|
frm.set_value('purchase_receipt', '');
|
||||||
@@ -363,24 +355,12 @@ frappe.ui.form.on('Asset', {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
purchase_invoice: function(frm) {
|
purchase_invoice: (frm) => {
|
||||||
frm.trigger('toggle_reference_doc');
|
frm.trigger('toggle_reference_doc');
|
||||||
if (frm.doc.purchase_invoice) {
|
if (frm.doc.purchase_invoice) {
|
||||||
if (frm.doc.item_code) {
|
if (frm.doc.item_code) {
|
||||||
frappe.db.get_doc('Purchase Invoice', frm.doc.purchase_invoice).then(pi_doc => {
|
frappe.db.get_doc('Purchase Invoice', frm.doc.purchase_invoice).then(pi_doc => {
|
||||||
frm.set_value('company', pi_doc.company);
|
frm.events.set_values_from_purchase_doc(frm, 'Purchase Invoice', pi_doc)
|
||||||
frm.set_value('purchase_date', pi_doc.posting_date);
|
|
||||||
const item = pi_doc.items.find(item => item.item_code === frm.doc.item_code);
|
|
||||||
if (!item) {
|
|
||||||
frm.set_value('purchase_invoice', '');
|
|
||||||
frappe.msgprint({
|
|
||||||
title: __('Invalid Purchase Invoice'),
|
|
||||||
message: __("The selected Purchase Invoice doesn't contains selected Asset Item."),
|
|
||||||
indicator: 'red'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
frm.set_value('gross_purchase_amount', item.base_net_rate);
|
|
||||||
frm.set_value('location', item.asset_location);
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
frm.set_value('purchase_invoice', '');
|
frm.set_value('purchase_invoice', '');
|
||||||
@@ -392,6 +372,24 @@ frappe.ui.form.on('Asset', {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
set_values_from_purchase_doc: function(frm, doctype, purchase_doc) {
|
||||||
|
frm.set_value('company', purchase_doc.company);
|
||||||
|
frm.set_value('purchase_date', purchase_doc.posting_date);
|
||||||
|
const item = purchase_doc.items.find(item => item.item_code === frm.doc.item_code);
|
||||||
|
if (!item) {
|
||||||
|
doctype_field = frappe.scrub(doctype)
|
||||||
|
frm.set_value(doctype_field, '');
|
||||||
|
frappe.msgprint({
|
||||||
|
title: __(`Invalid ${doctype}`),
|
||||||
|
message: __(`The selected ${doctype} doesn't contains selected Asset Item.`),
|
||||||
|
indicator: 'red'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
frm.set_value('gross_purchase_amount', item.base_net_rate + item.item_tax_amount);
|
||||||
|
frm.set_value('purchase_receipt_amount', item.base_net_rate + item.item_tax_amount);
|
||||||
|
frm.set_value('location', item.asset_location);
|
||||||
|
},
|
||||||
|
|
||||||
set_depreciation_rate: function(frm, row) {
|
set_depreciation_rate: function(frm, row) {
|
||||||
if (row.total_number_of_depreciations && row.frequency_of_depreciation
|
if (row.total_number_of_depreciations && row.frequency_of_depreciation
|
||||||
&& row.expected_value_after_useful_life) {
|
&& row.expected_value_after_useful_life) {
|
||||||
|
|||||||
@@ -132,9 +132,10 @@ class Asset(AccountsController):
|
|||||||
if len(movements) > 1:
|
if len(movements) > 1:
|
||||||
frappe.throw(_('Asset has multiple Asset Movement Entries which has to be \
|
frappe.throw(_('Asset has multiple Asset Movement Entries which has to be \
|
||||||
cancelled manually to cancel this asset.'))
|
cancelled manually to cancel this asset.'))
|
||||||
movement = frappe.get_doc('Asset Movement', movements[0].get('name'))
|
if movements:
|
||||||
movement.flags.ignore_validate = True
|
movement = frappe.get_doc('Asset Movement', movements[0].get('name'))
|
||||||
movement.cancel()
|
movement.flags.ignore_validate = True
|
||||||
|
movement.cancel()
|
||||||
|
|
||||||
def make_asset_movement(self):
|
def make_asset_movement(self):
|
||||||
reference_doctype = 'Purchase Receipt' if self.purchase_receipt else 'Purchase Invoice'
|
reference_doctype = 'Purchase Receipt' if self.purchase_receipt else 'Purchase Invoice'
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ class AssetMovement(Document):
|
|||||||
ORDER BY
|
ORDER BY
|
||||||
asm.transaction_date asc
|
asm.transaction_date asc
|
||||||
""", (d.asset, self.company, 'Receipt'), as_dict=1)
|
""", (d.asset, self.company, 'Receipt'), as_dict=1)
|
||||||
if auto_gen_movement_entry[0].get('name') == self.name:
|
if auto_gen_movement_entry and auto_gen_movement_entry[0].get('name') == self.name:
|
||||||
frappe.throw(_('{0} will be cancelled automatically on asset cancellation as it was \
|
frappe.throw(_('{0} will be cancelled automatically on asset cancellation as it was \
|
||||||
auto generated for Asset {1}').format(self.name, d.asset))
|
auto generated for Asset {1}').format(self.name, d.asset))
|
||||||
|
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ def get_data(filters):
|
|||||||
filters=conditions,
|
filters=conditions,
|
||||||
fields=["name", "asset_name", "department", "cost_center", "purchase_receipt",
|
fields=["name", "asset_name", "department", "cost_center", "purchase_receipt",
|
||||||
"asset_category", "purchase_date", "gross_purchase_amount", "location",
|
"asset_category", "purchase_date", "gross_purchase_amount", "location",
|
||||||
"available_for_use_date", "status", "purchase_invoice"])
|
"available_for_use_date", "status", "purchase_invoice", "opening_accumulated_depreciation"])
|
||||||
|
|
||||||
for asset in assets_record:
|
for asset in assets_record:
|
||||||
asset_value = asset.gross_purchase_amount - flt(asset.opening_accumulated_depreciation) \
|
asset_value = asset.gross_purchase_amount - flt(asset.opening_accumulated_depreciation) \
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
|
|||||||
if (doc.status != "On Hold") {
|
if (doc.status != "On Hold") {
|
||||||
if(flt(doc.per_received, 2) < 100 && allow_receipt) {
|
if(flt(doc.per_received, 2) < 100 && allow_receipt) {
|
||||||
cur_frm.add_custom_button(__('Receipt'), this.make_purchase_receipt, __('Create'));
|
cur_frm.add_custom_button(__('Receipt'), this.make_purchase_receipt, __('Create'));
|
||||||
if(doc.is_subcontracted==="Yes") {
|
if(doc.is_subcontracted==="Yes" && me.has_unsupplied_items()) {
|
||||||
cur_frm.add_custom_button(__('Material to Supplier'),
|
cur_frm.add_custom_button(__('Material to Supplier'),
|
||||||
function() { me.make_stock_entry(); }, __("Transfer"));
|
function() { me.make_stock_entry(); }, __("Transfer"));
|
||||||
}
|
}
|
||||||
@@ -191,6 +191,10 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
|
|||||||
set_schedule_date(this.frm);
|
set_schedule_date(this.frm);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
has_unsupplied_items: function() {
|
||||||
|
return this.frm.doc['supplied_items'].some(item => item.required_qty != item.supplied_qty)
|
||||||
|
},
|
||||||
|
|
||||||
make_stock_entry: function() {
|
make_stock_entry: function() {
|
||||||
var items = $.map(cur_frm.doc.items, function(d) { return d.bom ? d.item_code : false; });
|
var items = $.map(cur_frm.doc.items, function(d) { return d.bom ? d.item_code : false; });
|
||||||
var me = this;
|
var me = this;
|
||||||
@@ -267,7 +271,7 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
|
|||||||
|
|
||||||
if (me.frm.doc['supplied_items']) {
|
if (me.frm.doc['supplied_items']) {
|
||||||
me.frm.doc['supplied_items'].forEach((item, index) => {
|
me.frm.doc['supplied_items'].forEach((item, index) => {
|
||||||
if (item.rm_item_code && item.main_item_code) {
|
if (item.rm_item_code && item.main_item_code && item.required_qty - item.supplied_qty != 0) {
|
||||||
me.raw_material_data.push ({
|
me.raw_material_data.push ({
|
||||||
'name':item.name,
|
'name':item.name,
|
||||||
'item_code': item.main_item_code,
|
'item_code': item.main_item_code,
|
||||||
|
|||||||
@@ -56,6 +56,7 @@
|
|||||||
"section_break_48",
|
"section_break_48",
|
||||||
"pricing_rules",
|
"pricing_rules",
|
||||||
"raw_material_details",
|
"raw_material_details",
|
||||||
|
"set_reserve_warehouse",
|
||||||
"supplied_items",
|
"supplied_items",
|
||||||
"sb_last_purchase",
|
"sb_last_purchase",
|
||||||
"total_qty",
|
"total_qty",
|
||||||
@@ -340,6 +341,7 @@
|
|||||||
"fieldname": "contact_email",
|
"fieldname": "contact_email",
|
||||||
"fieldtype": "Small Text",
|
"fieldtype": "Small Text",
|
||||||
"label": "Contact Email",
|
"label": "Contact Email",
|
||||||
|
"options": "Email",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
@@ -607,7 +609,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "other_charges_calculation",
|
"fieldname": "other_charges_calculation",
|
||||||
"fieldtype": "Text",
|
"fieldtype": "Long Text",
|
||||||
"label": "Taxes and Charges Calculation",
|
"label": "Taxes and Charges Calculation",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"oldfieldtype": "HTML",
|
"oldfieldtype": "HTML",
|
||||||
@@ -1039,12 +1041,19 @@
|
|||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Tax Category",
|
"label": "Tax Category",
|
||||||
"options": "Tax Category"
|
"options": "Tax Category"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "supplied_items",
|
||||||
|
"fieldname": "set_reserve_warehouse",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Set Reserve Warehouse",
|
||||||
|
"options": "Warehouse"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-file-text",
|
"icon": "fa fa-file-text",
|
||||||
"idx": 105,
|
"idx": 105,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"modified": "2019-07-11 18:25:49.509343",
|
"modified": "2020-01-14 18:54:39.694448",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Purchase Order",
|
"name": "Purchase Order",
|
||||||
|
|||||||
@@ -116,6 +116,73 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
self.assertEqual(po.get("items")[0].amount, 1400)
|
self.assertEqual(po.get("items")[0].amount, 1400)
|
||||||
self.assertEqual(get_ordered_qty(), existing_ordered_qty + 3)
|
self.assertEqual(get_ordered_qty(), existing_ordered_qty + 3)
|
||||||
|
|
||||||
|
|
||||||
|
def test_add_new_item_in_update_child_qty_rate(self):
|
||||||
|
po = create_purchase_order(do_not_save=1)
|
||||||
|
po.items[0].qty = 4
|
||||||
|
po.save()
|
||||||
|
po.submit()
|
||||||
|
pr = make_pr_against_po(po.name, 2)
|
||||||
|
|
||||||
|
po.load_from_db()
|
||||||
|
first_item_of_po = po.get("items")[0]
|
||||||
|
|
||||||
|
trans_item = json.dumps([
|
||||||
|
{
|
||||||
|
'item_code': first_item_of_po.item_code,
|
||||||
|
'rate': first_item_of_po.rate,
|
||||||
|
'qty': first_item_of_po.qty,
|
||||||
|
'docname': first_item_of_po.name
|
||||||
|
},
|
||||||
|
{'item_code' : '_Test Item', 'rate' : 200, 'qty' : 7}
|
||||||
|
])
|
||||||
|
update_child_qty_rate('Purchase Order', trans_item, po.name)
|
||||||
|
|
||||||
|
po.reload()
|
||||||
|
self.assertEquals(len(po.get('items')), 2)
|
||||||
|
self.assertEqual(po.status, 'To Receive and Bill')
|
||||||
|
|
||||||
|
|
||||||
|
def test_remove_item_in_update_child_qty_rate(self):
|
||||||
|
po = create_purchase_order(do_not_save=1)
|
||||||
|
po.items[0].qty = 4
|
||||||
|
po.save()
|
||||||
|
po.submit()
|
||||||
|
pr = make_pr_against_po(po.name, 2)
|
||||||
|
|
||||||
|
po.reload()
|
||||||
|
first_item_of_po = po.get("items")[0]
|
||||||
|
# add an item
|
||||||
|
trans_item = json.dumps([
|
||||||
|
{
|
||||||
|
'item_code': first_item_of_po.item_code,
|
||||||
|
'rate': first_item_of_po.rate,
|
||||||
|
'qty': first_item_of_po.qty,
|
||||||
|
'docname': first_item_of_po.name
|
||||||
|
},
|
||||||
|
{'item_code' : '_Test Item', 'rate' : 200, 'qty' : 7}])
|
||||||
|
update_child_qty_rate('Purchase Order', trans_item, po.name)
|
||||||
|
|
||||||
|
po.reload()
|
||||||
|
# check if can remove received item
|
||||||
|
trans_item = json.dumps([{'item_code' : '_Test Item', 'rate' : 200, 'qty' : 7, 'docname': po.get("items")[1].name}])
|
||||||
|
self.assertRaises(frappe.ValidationError, update_child_qty_rate, 'Purchase Order', trans_item, po.name)
|
||||||
|
|
||||||
|
first_item_of_po = po.get("items")[0]
|
||||||
|
trans_item = json.dumps([
|
||||||
|
{
|
||||||
|
'item_code': first_item_of_po.item_code,
|
||||||
|
'rate': first_item_of_po.rate,
|
||||||
|
'qty': first_item_of_po.qty,
|
||||||
|
'docname': first_item_of_po.name
|
||||||
|
}
|
||||||
|
])
|
||||||
|
update_child_qty_rate('Purchase Order', trans_item, po.name)
|
||||||
|
|
||||||
|
po.reload()
|
||||||
|
self.assertEquals(len(po.get('items')), 1)
|
||||||
|
self.assertEqual(po.status, 'To Receive and Bill')
|
||||||
|
|
||||||
def test_update_qty(self):
|
def test_update_qty(self):
|
||||||
po = create_purchase_order()
|
po = create_purchase_order()
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -138,7 +138,7 @@ def refresh_scorecards():
|
|||||||
# Check to see if any new scorecard periods are created
|
# Check to see if any new scorecard periods are created
|
||||||
if make_all_scorecards(sc.name) > 0:
|
if make_all_scorecards(sc.name) > 0:
|
||||||
# Save the scorecard to update the score and standings
|
# Save the scorecard to update the score and standings
|
||||||
sc.save()
|
frappe.get_doc('Supplier Scorecard', sc.name).save()
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
|
|||||||
89
erpnext/change_log/v12/v12_4_0.md
Normal file
89
erpnext/change_log/v12/v12_4_0.md
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
# Version 12.4.0 Release Note
|
||||||
|
|
||||||
|
### Accounts
|
||||||
|
|
||||||
|
- Validity of item tax. [#20135](https://github.com/frappe/erpnext/pull/20135)
|
||||||
|
|
||||||
|
- Dynamic filters for dimensions in the budget variance report. [#19973](https://github.com/frappe/erpnext/pull/19973)
|
||||||
|
|
||||||
|
- Purchase Receipt and Purchase Invoice is not mandatory for an existing asset. [19980](https://github.com/frappe/erpnext/pull/19980)
|
||||||
|
|
||||||
|
- Allowed multiple Landed Cost Vouchers against a Purchase Receipt / Purchase Invoice. [#20058](https://github.com/frappe/erpnext/pull/20058)
|
||||||
|
|
||||||
|
- Rounding adjustment while both inclusive tax and additional discount amount are applied. [#20078](https://github.com/frappe/erpnext/pull/20078)
|
||||||
|
|
||||||
|
- Fixed an error while doing payment reconciliation for party type Employee. [#20088](https://github.com/frappe/erpnext/pull/20088)
|
||||||
|
|
||||||
|
- Show Closing row in General Ledger print. [#20161](https://github.com/frappe/erpnext/pull/20161)
|
||||||
|
|
||||||
|
- New report - Stock and Account Balance Comparison. [#20226](https://github.com/frappe/erpnext/pull/20226)
|
||||||
|
|
||||||
|
- Paid amount should not be over-written on clicking "Get Outstanding Invoices" button in Payment Entry. [#20050](https://github.com/frappe/erpnext/pull/20050)
|
||||||
|
|
||||||
|
- Currency symbol in Sales / Purchase Register report
|
||||||
|
|
||||||
|
- Currency symbol in "Bank and Cash Payment Voucher" print format.
|
||||||
|
|
||||||
|
|
||||||
|
### Human Resource
|
||||||
|
|
||||||
|
- Fixed leave allocation on the compensatory leave request submission. [#19961](https://github.com/frappe/erpnext/pull/19961)
|
||||||
|
|
||||||
|
- Create Payment Entry against Employee Advance to return any unclaimed amount and update returned amount in Employee Advance. [#19955](https://github.com/frappe/erpnext/pull/19955)
|
||||||
|
|
||||||
|
- Set Party against loan accounts in an accrual journal entry for salary. [#20022](https://github.com/frappe/erpnext/pull/20022)
|
||||||
|
|
||||||
|
- Editable loan repayment schedule after submission [#20122](https://github.com/frappe/erpnext/pull/20112)
|
||||||
|
|
||||||
|
- Update the paid amount and status of a loan after processing salary slip against it. [#20023](https://github.com/frappe/erpnext/pull/20023)
|
||||||
|
|
||||||
|
- Settings to disable rounded total in salary slip via HR Settings. [#20150](https://github.com/frappe/erpnext/pull/20150)
|
||||||
|
|
||||||
|
- Submit Salary button was not showing after creating salary slip in payroll entry. [#19753](https://github.com/frappe/erpnext/pull/19753)
|
||||||
|
|
||||||
|
- Payment Entry against payroll entry should deduct loan amount (if there are any loan deductions in salary slip). [#20194](https://github.com/frappe/erpnext/pull/20194)
|
||||||
|
|
||||||
|
- Show only relevant "Job Offer" in Employee Onboarding based on Job Applicant
|
||||||
|
|
||||||
|
- Added dashboard in Employee Advance
|
||||||
|
|
||||||
|
|
||||||
|
### Manufacturing
|
||||||
|
|
||||||
|
- Fixed backflushed qty for partial receipt against a subcontracted purchase order. [#20026](https://github.com/frappe/erpnext/pull/20026)
|
||||||
|
|
||||||
|
- Added "Set Reserve Warehouse" field in sub-contracted Purchase Order. [19992](https://github.com/frappe/erpnext/pull/19992)
|
||||||
|
- Only shows if the supplied items table is not empty
|
||||||
|
- On entering a warehouse in the field, it sets / overwrites reserve warehouse in Supplied Raw Materials table.
|
||||||
|
|
||||||
|
- In Backflush Stock Entry against Work Order, additional cost for service items (defined in BOM) should come proportionately based on finished goods qty. [#20105](https://github.com/frappe/erpnext/pull/20105)
|
||||||
|
|
||||||
|
- Hide transfer button in a subcontracted PO if full qty is already transferred. [#20155](https://github.com/frappe/erpnext/pull/20155)
|
||||||
|
|
||||||
|
- Set correct valuation rate of finished goods item in case of multiple material consumptions. [#20165](https://github.com/frappe/erpnext/pull/20165)
|
||||||
|
|
||||||
|
- Job Card creation from Work Order dashboard
|
||||||
|
|
||||||
|
|
||||||
|
### Stock
|
||||||
|
|
||||||
|
- Fixed ambiguous column name in the Batch query. Test by searching in any Batch link field.
|
||||||
|
|
||||||
|
- Fixed incorrect reorder level in Stock balance report
|
||||||
|
|
||||||
|
- Validate Batch for serialized items
|
||||||
|
|
||||||
|
- Get the outgoing rate of serial no from SLE if serial no already transferred to another company. [#20171](https://github.com/frappe/erpnext/pull/20171)
|
||||||
|
|
||||||
|
- Deliver Note creation from Sales Order dashboard. [#20199](https://github.com/frappe/erpnext/pull/20199)
|
||||||
|
|
||||||
|
|
||||||
|
### Others
|
||||||
|
|
||||||
|
- Addition and deletion of items in submitted Sales Order / Purchase Order. [#19911](https://github.com/frappe/erpnext/pull/19911)
|
||||||
|
|
||||||
|
- Get item price based on price list considering minimum qty. [#20206](https://github.com/frappe/erpnext/pull/20206)
|
||||||
|
|
||||||
|
- Product Bundle item should not appear in dialog on click of "Create Material Request" button. [#20216](https://github.com/frappe/erpnext/pull/20216)
|
||||||
|
|
||||||
|
- Delete linked communications on the deletion of company transactions. [#19928](https://github.com/frappe/erpnext/pull/19928)
|
||||||
@@ -336,6 +336,24 @@ def get_data():
|
|||||||
"is_query_report": True,
|
"is_query_report": True,
|
||||||
"name": "Item Variant Details",
|
"name": "Item Variant Details",
|
||||||
"doctype": "Item"
|
"doctype": "Item"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "report",
|
||||||
|
"is_query_report": True,
|
||||||
|
"name": "Subcontracted Raw Materials To Be Transferred",
|
||||||
|
"doctype": "Purchase Order"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "report",
|
||||||
|
"is_query_report": True,
|
||||||
|
"name": "Subcontracted Item To Be Received",
|
||||||
|
"doctype": "Purchase Order"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "report",
|
||||||
|
"is_query_report": True,
|
||||||
|
"name": "Stock and Account Value Comparison",
|
||||||
|
"doctype": "Stock Ledger Entry"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1155,6 +1155,30 @@ def set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docna
|
|||||||
child_item.base_amount = 1 # Initiallize value will update in parent validation
|
child_item.base_amount = 1 # Initiallize value will update in parent validation
|
||||||
return child_item
|
return child_item
|
||||||
|
|
||||||
|
def check_and_delete_children(parent, data):
|
||||||
|
deleted_children = []
|
||||||
|
updated_item_names = [d.get("docname") for d in data]
|
||||||
|
for item in parent.items:
|
||||||
|
if item.name not in updated_item_names:
|
||||||
|
deleted_children.append(item)
|
||||||
|
|
||||||
|
for d in deleted_children:
|
||||||
|
if parent.doctype == "Sales Order":
|
||||||
|
if flt(d.delivered_qty):
|
||||||
|
frappe.throw(_("Row #{0}: Cannot delete item {1} which has already been delivered").format(d.idx, d.item_code))
|
||||||
|
if flt(d.work_order_qty):
|
||||||
|
frappe.throw(_("Row #{0}: Cannot delete item {1} which has work order assigned to it.").format(d.idx, d.item_code))
|
||||||
|
if flt(d.ordered_qty):
|
||||||
|
frappe.throw(_("Row #{0}: Cannot delete item {1} which is assigned to customer's purchase order.").format(d.idx, d.item_code))
|
||||||
|
|
||||||
|
if parent.doctype == "Purchase Order" and flt(d.received_qty):
|
||||||
|
frappe.throw(_("Row #{0}: Cannot delete item {1} which has already been received").format(d.idx, d.item_code))
|
||||||
|
|
||||||
|
if flt(d.billed_amt):
|
||||||
|
frappe.throw(_("Row #{0}: Cannot delete item {1} which has already been billed.").format(d.idx, d.item_code))
|
||||||
|
|
||||||
|
d.cancel()
|
||||||
|
d.delete()
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, child_docname="items"):
|
def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, child_docname="items"):
|
||||||
@@ -1163,6 +1187,8 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
|
|||||||
sales_doctypes = ['Sales Order', 'Sales Invoice', 'Delivery Note', 'Quotation']
|
sales_doctypes = ['Sales Order', 'Sales Invoice', 'Delivery Note', 'Quotation']
|
||||||
parent = frappe.get_doc(parent_doctype, parent_doctype_name)
|
parent = frappe.get_doc(parent_doctype, parent_doctype_name)
|
||||||
|
|
||||||
|
check_and_delete_children(parent, data)
|
||||||
|
|
||||||
for d in data:
|
for d in data:
|
||||||
new_child_flag = False
|
new_child_flag = False
|
||||||
if not d.get("docname"):
|
if not d.get("docname"):
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.desk.reportview import get_match_cond, get_filters_cond
|
from frappe.desk.reportview import get_match_cond, get_filters_cond
|
||||||
from frappe.utils import nowdate
|
from frappe.utils import nowdate, getdate
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
from erpnext.stock.get_item_details import _get_item_tax_template
|
||||||
|
|
||||||
# searches for active employees
|
# searches for active employees
|
||||||
def employee_query(doctype, txt, searchfield, start, page_len, filters):
|
def employee_query(doctype, txt, searchfield, start, page_len, filters):
|
||||||
@@ -311,6 +311,7 @@ def get_batch_no(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
and sle.item_code = %(item_code)s
|
and sle.item_code = %(item_code)s
|
||||||
and sle.warehouse = %(warehouse)s
|
and sle.warehouse = %(warehouse)s
|
||||||
and (sle.batch_no like %(txt)s
|
and (sle.batch_no like %(txt)s
|
||||||
|
or batch.expiry_date like %(txt)s
|
||||||
or batch.manufacturing_date like %(txt)s)
|
or batch.manufacturing_date like %(txt)s)
|
||||||
and batch.docstatus < 2
|
and batch.docstatus < 2
|
||||||
{cond}
|
{cond}
|
||||||
@@ -329,6 +330,7 @@ def get_batch_no(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
where batch.disabled = 0
|
where batch.disabled = 0
|
||||||
and item = %(item_code)s
|
and item = %(item_code)s
|
||||||
and (name like %(txt)s
|
and (name like %(txt)s
|
||||||
|
or expiry_date like %(txt)s
|
||||||
or manufacturing_date like %(txt)s)
|
or manufacturing_date like %(txt)s)
|
||||||
and docstatus < 2
|
and docstatus < 2
|
||||||
{0}
|
{0}
|
||||||
@@ -484,7 +486,7 @@ def item_manufacturer_query(doctype, txt, searchfield, start, page_len, filters)
|
|||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_purchase_receipts(doctype, txt, searchfield, start, page_len, filters):
|
def get_purchase_receipts(doctype, txt, searchfield, start, page_len, filters):
|
||||||
query = """
|
query = """
|
||||||
select pr.name
|
select pr.name
|
||||||
from `tabPurchase Receipt` pr, `tabPurchase Receipt Item` pritem
|
from `tabPurchase Receipt` pr, `tabPurchase Receipt Item` pritem
|
||||||
where pr.docstatus = 1 and pritem.parent = pr.name
|
where pr.docstatus = 1 and pritem.parent = pr.name
|
||||||
and pr.name like {txt}""".format(txt = frappe.db.escape('%{0}%'.format(txt)))
|
and pr.name like {txt}""".format(txt = frappe.db.escape('%{0}%'.format(txt)))
|
||||||
@@ -497,7 +499,7 @@ def get_purchase_receipts(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_purchase_invoices(doctype, txt, searchfield, start, page_len, filters):
|
def get_purchase_invoices(doctype, txt, searchfield, start, page_len, filters):
|
||||||
query = """
|
query = """
|
||||||
select pi.name
|
select pi.name
|
||||||
from `tabPurchase Invoice` pi, `tabPurchase Invoice Item` piitem
|
from `tabPurchase Invoice` pi, `tabPurchase Invoice Item` piitem
|
||||||
where pi.docstatus = 1 and piitem.parent = pi.name
|
where pi.docstatus = 1 and piitem.parent = pi.name
|
||||||
and pi.name like {txt}""".format(txt = frappe.db.escape('%{0}%'.format(txt)))
|
and pi.name like {txt}""".format(txt = frappe.db.escape('%{0}%'.format(txt)))
|
||||||
@@ -506,3 +508,27 @@ def get_purchase_invoices(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
query += " and piitem.item_code = {item_code}".format(item_code = frappe.db.escape(filters.get('item_code')))
|
query += " and piitem.item_code = {item_code}".format(item_code = frappe.db.escape(filters.get('item_code')))
|
||||||
|
|
||||||
return frappe.db.sql(query, filters)
|
return frappe.db.sql(query, filters)
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def get_tax_template(doctype, txt, searchfield, start, page_len, filters):
|
||||||
|
|
||||||
|
item_doc = frappe.get_cached_doc('Item', filters.get('item_code'))
|
||||||
|
item_group = filters.get('item_group')
|
||||||
|
taxes = item_doc.taxes or []
|
||||||
|
|
||||||
|
while item_group:
|
||||||
|
item_group_doc = frappe.get_cached_doc('Item Group', item_group)
|
||||||
|
taxes += item_group_doc.taxes or []
|
||||||
|
item_group = item_group_doc.parent_item_group
|
||||||
|
|
||||||
|
if not taxes:
|
||||||
|
return frappe.db.sql(""" SELECT name FROM `tabItem Tax Template` """)
|
||||||
|
else:
|
||||||
|
args = {
|
||||||
|
'item_code': filters.get('item_code'),
|
||||||
|
'posting_date': filters.get('valid_from'),
|
||||||
|
'tax_category': filters.get('tax_category')
|
||||||
|
}
|
||||||
|
|
||||||
|
taxes = _get_item_tax_template(args, taxes, for_validate=True)
|
||||||
|
return [(d,) for d in set(taxes)]
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ class StockController(AccountsController):
|
|||||||
def validate(self):
|
def validate(self):
|
||||||
super(StockController, self).validate()
|
super(StockController, self).validate()
|
||||||
self.validate_inspection()
|
self.validate_inspection()
|
||||||
|
self.validate_serialized_batch()
|
||||||
|
|
||||||
def make_gl_entries(self, gl_entries=None, repost_future_gle=True, from_repost=False):
|
def make_gl_entries(self, gl_entries=None, repost_future_gle=True, from_repost=False):
|
||||||
if self.docstatus == 2:
|
if self.docstatus == 2:
|
||||||
@@ -42,6 +43,18 @@ class StockController(AccountsController):
|
|||||||
gl_entries = self.get_asset_gl_entry(gl_entries)
|
gl_entries = self.get_asset_gl_entry(gl_entries)
|
||||||
make_gl_entries(gl_entries, from_repost=from_repost)
|
make_gl_entries(gl_entries, from_repost=from_repost)
|
||||||
|
|
||||||
|
def validate_serialized_batch(self):
|
||||||
|
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
||||||
|
for d in self.get("items"):
|
||||||
|
if not (hasattr(d, 'serial_no') and d.serial_no and d.batch_no): continue
|
||||||
|
|
||||||
|
serial_nos = get_serial_nos(d.serial_no)
|
||||||
|
for serial_no_data in frappe.get_all("Serial No",
|
||||||
|
filters={"name": ("in", serial_nos)}, fields=["batch_no", "name"]):
|
||||||
|
if serial_no_data.batch_no != d.batch_no:
|
||||||
|
frappe.throw(_("Row #{0}: Serial No {1} does not belong to Batch {2}")
|
||||||
|
.format(d.idx, serial_no_data.name, d.batch_no))
|
||||||
|
|
||||||
def get_gl_entries(self, warehouse_account=None, default_expense_account=None,
|
def get_gl_entries(self, warehouse_account=None, default_expense_account=None,
|
||||||
default_cost_center=None):
|
default_cost_center=None):
|
||||||
|
|
||||||
@@ -54,6 +67,7 @@ class StockController(AccountsController):
|
|||||||
gl_list = []
|
gl_list = []
|
||||||
warehouse_with_no_account = []
|
warehouse_with_no_account = []
|
||||||
|
|
||||||
|
precision = frappe.get_precision("GL Entry", "debit_in_account_currency")
|
||||||
for item_row in voucher_details:
|
for item_row in voucher_details:
|
||||||
sle_list = sle_map.get(item_row.name)
|
sle_list = sle_map.get(item_row.name)
|
||||||
if sle_list:
|
if sle_list:
|
||||||
@@ -79,7 +93,7 @@ class StockController(AccountsController):
|
|||||||
"against": item_row.expense_account,
|
"against": item_row.expense_account,
|
||||||
"cost_center": item_row.cost_center,
|
"cost_center": item_row.cost_center,
|
||||||
"remarks": self.get("remarks") or "Accounting Entry for Stock",
|
"remarks": self.get("remarks") or "Accounting Entry for Stock",
|
||||||
"debit": flt(sle.stock_value_difference, 2),
|
"debit": flt(sle.stock_value_difference, precision),
|
||||||
"is_opening": item_row.get("is_opening") or self.get("is_opening") or "No",
|
"is_opening": item_row.get("is_opening") or self.get("is_opening") or "No",
|
||||||
}, warehouse_account[sle.warehouse]["account_currency"], item=item_row))
|
}, warehouse_account[sle.warehouse]["account_currency"], item=item_row))
|
||||||
|
|
||||||
@@ -89,7 +103,7 @@ class StockController(AccountsController):
|
|||||||
"against": warehouse_account[sle.warehouse]["account"],
|
"against": warehouse_account[sle.warehouse]["account"],
|
||||||
"cost_center": item_row.cost_center,
|
"cost_center": item_row.cost_center,
|
||||||
"remarks": self.get("remarks") or "Accounting Entry for Stock",
|
"remarks": self.get("remarks") or "Accounting Entry for Stock",
|
||||||
"credit": flt(sle.stock_value_difference, 2),
|
"credit": flt(sle.stock_value_difference, precision),
|
||||||
"project": item_row.get("project") or self.get("project"),
|
"project": item_row.get("project") or self.get("project"),
|
||||||
"is_opening": item_row.get("is_opening") or self.get("is_opening") or "No"
|
"is_opening": item_row.get("is_opening") or self.get("is_opening") or "No"
|
||||||
}, item=item_row))
|
}, item=item_row))
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ from frappe import _, scrub
|
|||||||
from frappe.utils import cint, flt, round_based_on_smallest_currency_fraction
|
from frappe.utils import cint, flt, round_based_on_smallest_currency_fraction
|
||||||
from erpnext.controllers.accounts_controller import validate_conversion_rate, \
|
from erpnext.controllers.accounts_controller import validate_conversion_rate, \
|
||||||
validate_taxes_and_charges, validate_inclusive_tax
|
validate_taxes_and_charges, validate_inclusive_tax
|
||||||
|
from erpnext.stock.get_item_details import _get_item_tax_template
|
||||||
|
|
||||||
class calculate_taxes_and_totals(object):
|
class calculate_taxes_and_totals(object):
|
||||||
def __init__(self, doc):
|
def __init__(self, doc):
|
||||||
@@ -34,6 +35,7 @@ class calculate_taxes_and_totals(object):
|
|||||||
def _calculate(self):
|
def _calculate(self):
|
||||||
self.validate_conversion_rate()
|
self.validate_conversion_rate()
|
||||||
self.calculate_item_values()
|
self.calculate_item_values()
|
||||||
|
self.validate_item_tax_template()
|
||||||
self.initialize_taxes()
|
self.initialize_taxes()
|
||||||
self.determine_exclusive_rate()
|
self.determine_exclusive_rate()
|
||||||
self.calculate_net_total()
|
self.calculate_net_total()
|
||||||
@@ -43,6 +45,38 @@ class calculate_taxes_and_totals(object):
|
|||||||
self._cleanup()
|
self._cleanup()
|
||||||
self.calculate_total_net_weight()
|
self.calculate_total_net_weight()
|
||||||
|
|
||||||
|
def validate_item_tax_template(self):
|
||||||
|
for item in self.doc.get('items'):
|
||||||
|
if item.item_code and item.get('item_tax_template'):
|
||||||
|
item_doc = frappe.get_cached_doc("Item", item.item_code)
|
||||||
|
args = {
|
||||||
|
'tax_category': self.doc.get('tax_category'),
|
||||||
|
'posting_date': self.doc.get('posting_date'),
|
||||||
|
'bill_date': self.doc.get('bill_date'),
|
||||||
|
'transaction_date': self.doc.get('transaction_date')
|
||||||
|
}
|
||||||
|
|
||||||
|
item_group = item_doc.item_group
|
||||||
|
item_group_taxes = []
|
||||||
|
|
||||||
|
while item_group:
|
||||||
|
item_group_doc = frappe.get_cached_doc('Item Group', item_group)
|
||||||
|
item_group_taxes += item_group_doc.taxes or []
|
||||||
|
item_group = item_group_doc.parent_item_group
|
||||||
|
|
||||||
|
item_taxes = item_doc.taxes or []
|
||||||
|
|
||||||
|
if not item_group_taxes and (not item_taxes):
|
||||||
|
# No validation if no taxes in item or item group
|
||||||
|
continue
|
||||||
|
|
||||||
|
taxes = _get_item_tax_template(args, item_taxes + item_group_taxes, for_validate=True)
|
||||||
|
|
||||||
|
if item.item_tax_template not in taxes:
|
||||||
|
frappe.throw(_("Row {0}: Invalid Item Tax Template for item {1}").format(
|
||||||
|
item.idx, frappe.bold(item.item_code)
|
||||||
|
))
|
||||||
|
|
||||||
def validate_conversion_rate(self):
|
def validate_conversion_rate(self):
|
||||||
# validate conversion rate
|
# validate conversion rate
|
||||||
company_currency = erpnext.get_company_currency(self.doc.company)
|
company_currency = erpnext.get_company_currency(self.doc.company)
|
||||||
@@ -312,11 +346,19 @@ class calculate_taxes_and_totals(object):
|
|||||||
last_tax = self.doc.get("taxes")[-1]
|
last_tax = self.doc.get("taxes")[-1]
|
||||||
non_inclusive_tax_amount = sum([flt(d.tax_amount_after_discount_amount)
|
non_inclusive_tax_amount = sum([flt(d.tax_amount_after_discount_amount)
|
||||||
for d in self.doc.get("taxes") if not d.included_in_print_rate])
|
for d in self.doc.get("taxes") if not d.included_in_print_rate])
|
||||||
|
|
||||||
diff = self.doc.total + non_inclusive_tax_amount \
|
diff = self.doc.total + non_inclusive_tax_amount \
|
||||||
- flt(last_tax.total, last_tax.precision("total"))
|
- flt(last_tax.total, last_tax.precision("total"))
|
||||||
|
|
||||||
|
# If discount amount applied, deduct the discount amount
|
||||||
|
# because self.doc.total is always without discount, but last_tax.total is after discount
|
||||||
|
if self.discount_amount_applied and self.doc.discount_amount:
|
||||||
|
diff -= flt(self.doc.discount_amount)
|
||||||
|
|
||||||
|
diff = flt(diff, self.doc.precision("rounding_adjustment"))
|
||||||
|
|
||||||
if diff and abs(diff) <= (5.0 / 10**last_tax.precision("tax_amount")):
|
if diff and abs(diff) <= (5.0 / 10**last_tax.precision("tax_amount")):
|
||||||
self.doc.rounding_adjustment = flt(flt(self.doc.rounding_adjustment) +
|
self.doc.rounding_adjustment = diff
|
||||||
flt(diff), self.doc.precision("rounding_adjustment"))
|
|
||||||
|
|
||||||
def calculate_totals(self):
|
def calculate_totals(self):
|
||||||
self.doc.grand_total = flt(self.doc.get("taxes")[-1].total) + flt(self.doc.rounding_adjustment) \
|
self.doc.grand_total = flt(self.doc.get("taxes")[-1].total) + flt(self.doc.rounding_adjustment) \
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ from datetime import timedelta
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils import get_url
|
from frappe.utils import get_url, getdate
|
||||||
from frappe.utils.verified_command import verify_request, get_signed_params
|
from frappe.utils.verified_command import verify_request, get_signed_params
|
||||||
|
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ class Appointment(Document):
|
|||||||
if self._assign:
|
if self._assign:
|
||||||
return
|
return
|
||||||
available_agents = _get_agents_sorted_by_asc_workload(
|
available_agents = _get_agents_sorted_by_asc_workload(
|
||||||
self.scheduled_time.date())
|
getdate(self.scheduled_time))
|
||||||
for agent in available_agents:
|
for agent in available_agents:
|
||||||
if(_check_agent_availability(agent, self.scheduled_time)):
|
if(_check_agent_availability(agent, self.scheduled_time)):
|
||||||
agent = agent[0]
|
agent = agent[0]
|
||||||
@@ -189,7 +189,7 @@ def _get_agents_sorted_by_asc_workload(date):
|
|||||||
assigned_to = frappe.parse_json(appointment._assign)
|
assigned_to = frappe.parse_json(appointment._assign)
|
||||||
if not assigned_to:
|
if not assigned_to:
|
||||||
continue
|
continue
|
||||||
if (assigned_to[0] in agent_list) and appointment.scheduled_time.date() == date:
|
if (assigned_to[0] in agent_list) and getdate(appointment.scheduled_time) == date:
|
||||||
appointment_counter[assigned_to[0]] += 1
|
appointment_counter[assigned_to[0]] += 1
|
||||||
sorted_agent_list = appointment_counter.most_common()
|
sorted_agent_list = appointment_counter.most_common()
|
||||||
sorted_agent_list.reverse()
|
sorted_agent_list.reverse()
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"creation": "2018-10-25 10:02:48.656165",
|
"creation": "2018-10-25 10:02:48.656165",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
@@ -23,48 +24,41 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"depends_on": "eval:doc.enabled==1",
|
"depends_on": "enabled",
|
||||||
"fieldname": "automatic_sync",
|
"fieldname": "automatic_sync",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Synchronize all accounts every hour"
|
"label": "Synchronize all accounts every hour"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:doc.enabled==1",
|
|
||||||
"fieldname": "plaid_client_id",
|
"fieldname": "plaid_client_id",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Plaid Client ID",
|
"label": "Plaid Client ID"
|
||||||
"reqd": 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:doc.enabled==1",
|
|
||||||
"fieldname": "plaid_secret",
|
"fieldname": "plaid_secret",
|
||||||
"fieldtype": "Password",
|
"fieldtype": "Password",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Plaid Secret",
|
"label": "Plaid Secret"
|
||||||
"reqd": 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:doc.enabled==1",
|
|
||||||
"fieldname": "plaid_public_key",
|
"fieldname": "plaid_public_key",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Plaid Public Key",
|
"label": "Plaid Public Key"
|
||||||
"reqd": 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:doc.enabled==1",
|
|
||||||
"fieldname": "plaid_env",
|
"fieldname": "plaid_env",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Plaid Environment",
|
"label": "Plaid Environment"
|
||||||
"reqd": 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_2",
|
"fieldname": "column_break_2",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"depends_on": "enabled",
|
||||||
"fieldname": "section_break_4",
|
"fieldname": "section_break_4",
|
||||||
"fieldtype": "Section Break"
|
"fieldtype": "Section Break"
|
||||||
},
|
},
|
||||||
@@ -74,7 +68,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"modified": "2019-08-13 17:00:06.939422",
|
"links": [],
|
||||||
|
"modified": "2020-01-05 10:00:22.137832",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "ERPNext Integrations",
|
"module": "ERPNext Integrations",
|
||||||
"name": "Plaid Settings",
|
"name": "Plaid Settings",
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ frappe.ui.form.on('Employee Advance', {
|
|||||||
}
|
}
|
||||||
else if (
|
else if (
|
||||||
frm.doc.docstatus === 1
|
frm.doc.docstatus === 1
|
||||||
&& flt(frm.doc.claimed_amount) < flt(frm.doc.paid_amount)
|
&& flt(frm.doc.claimed_amount) < flt(frm.doc.paid_amount) - flt(frm.doc.return_amount)
|
||||||
&& frappe.model.can_create("Expense Claim")
|
&& frappe.model.can_create("Expense Claim")
|
||||||
) {
|
) {
|
||||||
frm.add_custom_button(
|
frm.add_custom_button(
|
||||||
@@ -45,6 +45,15 @@ frappe.ui.form.on('Employee Advance', {
|
|||||||
__('Create')
|
__('Create')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (frm.doc.docstatus === 1
|
||||||
|
&& (flt(frm.doc.claimed_amount) + flt(frm.doc.return_amount) < flt(frm.doc.paid_amount))
|
||||||
|
&& frappe.model.can_create("Journal Entry")) {
|
||||||
|
|
||||||
|
frm.add_custom_button(__("Return"), function() {
|
||||||
|
frm.trigger('make_return_entry');
|
||||||
|
}, __('Create'));
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
make_payment_entry: function(frm) {
|
make_payment_entry: function(frm) {
|
||||||
@@ -83,6 +92,24 @@ frappe.ui.form.on('Employee Advance', {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
make_return_entry: function(frm) {
|
||||||
|
frappe.call({
|
||||||
|
method: 'erpnext.hr.doctype.employee_advance.employee_advance.make_return_entry',
|
||||||
|
args: {
|
||||||
|
'employee': frm.doc.employee,
|
||||||
|
'company': frm.doc.company,
|
||||||
|
'employee_advance_name': frm.doc.name,
|
||||||
|
'return_amount': flt(frm.doc.paid_amount - frm.doc.claimed_amount),
|
||||||
|
'advance_account': frm.doc.advance_account,
|
||||||
|
'mode_of_payment': frm.doc.mode_of_payment
|
||||||
|
},
|
||||||
|
callback: function(r) {
|
||||||
|
const doclist = frappe.model.sync(r.message);
|
||||||
|
frappe.set_route('Form', doclist[0].doctype, doclist[0].name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
employee: function (frm) {
|
employee: function (frm) {
|
||||||
if (frm.doc.employee) {
|
if (frm.doc.employee) {
|
||||||
return frappe.call({
|
return frappe.call({
|
||||||
|
|||||||
@@ -1,737 +1,213 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"actions": [],
|
||||||
"allow_events_in_timeline": 0,
|
"allow_import": 1,
|
||||||
"allow_guest_to_view": 0,
|
"autoname": "naming_series:",
|
||||||
"allow_import": 1,
|
"creation": "2017-10-09 14:26:29.612365",
|
||||||
"allow_rename": 0,
|
"doctype": "DocType",
|
||||||
"autoname": "naming_series:",
|
"editable_grid": 1,
|
||||||
"beta": 0,
|
"engine": "InnoDB",
|
||||||
"creation": "2017-10-09 14:26:29.612365",
|
"field_order": [
|
||||||
"custom": 0,
|
"naming_series",
|
||||||
"docstatus": 0,
|
"employee",
|
||||||
"doctype": "DocType",
|
"employee_name",
|
||||||
"document_type": "",
|
"column_break_4",
|
||||||
"editable_grid": 1,
|
"posting_date",
|
||||||
"engine": "InnoDB",
|
"department",
|
||||||
|
"section_break_8",
|
||||||
|
"purpose",
|
||||||
|
"column_break_11",
|
||||||
|
"advance_amount",
|
||||||
|
"paid_amount",
|
||||||
|
"due_advance_amount",
|
||||||
|
"claimed_amount",
|
||||||
|
"return_amount",
|
||||||
|
"section_break_7",
|
||||||
|
"status",
|
||||||
|
"company",
|
||||||
|
"amended_from",
|
||||||
|
"column_break_18",
|
||||||
|
"advance_account",
|
||||||
|
"mode_of_payment"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "naming_series",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Select",
|
||||||
"allow_on_submit": 0,
|
"label": "Series",
|
||||||
"bold": 0,
|
"options": "HR-EAD-.YYYY.-"
|
||||||
"collapsible": 0,
|
},
|
||||||
"columns": 0,
|
|
||||||
"default": "",
|
|
||||||
"fieldname": "naming_series",
|
|
||||||
"fieldtype": "Select",
|
|
||||||
"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": "Series",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "HR-EAD-.YYYY.-",
|
|
||||||
"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,
|
"fieldname": "employee",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Link",
|
||||||
"allow_on_submit": 0,
|
"in_list_view": 1,
|
||||||
"bold": 0,
|
"label": "Employee",
|
||||||
"collapsible": 0,
|
"options": "Employee",
|
||||||
"columns": 0,
|
"reqd": 1
|
||||||
"fieldname": "employee",
|
},
|
||||||
"fieldtype": "Link",
|
|
||||||
"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": "Employee",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Employee",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fetch_from": "employee.employee_name",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "employee_name",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Read Only",
|
||||||
"bold": 0,
|
"label": "Employee Name"
|
||||||
"collapsible": 0,
|
},
|
||||||
"columns": 0,
|
|
||||||
"fetch_from": "employee.employee_name",
|
|
||||||
"fieldname": "employee_name",
|
|
||||||
"fieldtype": "Read Only",
|
|
||||||
"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": "Employee Name",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"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,
|
"fieldname": "column_break_4",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Column Break"
|
||||||
"allow_on_submit": 0,
|
},
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_4",
|
|
||||||
"fieldtype": "Column Break",
|
|
||||||
"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,
|
"default": "Today",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "posting_date",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Date",
|
||||||
"bold": 0,
|
"in_list_view": 1,
|
||||||
"collapsible": 0,
|
"label": "Posting Date",
|
||||||
"columns": 0,
|
"reqd": 1
|
||||||
"default": "Today",
|
},
|
||||||
"fieldname": "posting_date",
|
|
||||||
"fieldtype": "Date",
|
|
||||||
"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": "Posting Date",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fetch_from": "employee.department",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "department",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Link",
|
||||||
"bold": 0,
|
"label": "Department",
|
||||||
"collapsible": 0,
|
"options": "Department",
|
||||||
"columns": 0,
|
"read_only": 1
|
||||||
"fetch_from": "employee.department",
|
},
|
||||||
"fieldname": "department",
|
|
||||||
"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": "Department",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Department",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"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": "section_break_8",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Section Break"
|
||||||
"allow_on_submit": 0,
|
},
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "section_break_8",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"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,
|
"fieldname": "purpose",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Small Text",
|
||||||
"allow_on_submit": 0,
|
"in_list_view": 1,
|
||||||
"bold": 0,
|
"label": "Purpose",
|
||||||
"collapsible": 0,
|
"reqd": 1
|
||||||
"columns": 0,
|
},
|
||||||
"fieldname": "purpose",
|
|
||||||
"fieldtype": "Small Text",
|
|
||||||
"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": "Purpose",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "column_break_11",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Column Break"
|
||||||
"allow_on_submit": 0,
|
},
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_11",
|
|
||||||
"fieldtype": "Column Break",
|
|
||||||
"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,
|
"fieldname": "advance_amount",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Currency",
|
||||||
"allow_on_submit": 0,
|
"in_list_view": 1,
|
||||||
"bold": 0,
|
"label": "Advance Amount",
|
||||||
"collapsible": 0,
|
"options": "Company:company:default_currency",
|
||||||
"columns": 0,
|
"reqd": 1
|
||||||
"fieldname": "advance_amount",
|
},
|
||||||
"fieldtype": "Currency",
|
|
||||||
"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": "Advance Amount",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Company:company:default_currency",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "paid_amount",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Currency",
|
||||||
"allow_on_submit": 0,
|
"label": "Paid Amount",
|
||||||
"bold": 0,
|
"no_copy": 1,
|
||||||
"collapsible": 0,
|
"options": "Company:company:default_currency",
|
||||||
"columns": 0,
|
"read_only": 1
|
||||||
"fieldname": "paid_amount",
|
},
|
||||||
"fieldtype": "Currency",
|
|
||||||
"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": "Paid Amount",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
|
||||||
"options": "Company:company:default_currency",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"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,
|
"depends_on": "eval:cur_frm.doc.employee",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "due_advance_amount",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Currency",
|
||||||
"bold": 0,
|
"label": "Due Advance Amount",
|
||||||
"collapsible": 0,
|
"options": "Company:company:default_currency",
|
||||||
"columns": 0,
|
"read_only": 1
|
||||||
"depends_on": "eval:cur_frm.doc.employee",
|
},
|
||||||
"fieldname": "due_advance_amount",
|
|
||||||
"fieldtype": "Currency",
|
|
||||||
"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": "Due Advance Amount",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Company:company:default_currency",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"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": "claimed_amount",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Currency",
|
||||||
"allow_on_submit": 0,
|
"label": "Claimed Amount",
|
||||||
"bold": 0,
|
"no_copy": 1,
|
||||||
"collapsible": 0,
|
"options": "Company:company:default_currency",
|
||||||
"columns": 0,
|
"read_only": 1
|
||||||
"fieldname": "claimed_amount",
|
},
|
||||||
"fieldtype": "Currency",
|
|
||||||
"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": "Claimed Amount",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
|
||||||
"options": "Company:company:default_currency",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"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": "section_break_7",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Section Break"
|
||||||
"allow_on_submit": 0,
|
},
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "section_break_7",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"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,
|
"fieldname": "status",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Select",
|
||||||
"allow_on_submit": 0,
|
"label": "Status",
|
||||||
"bold": 0,
|
"no_copy": 1,
|
||||||
"collapsible": 0,
|
"options": "Draft\nPaid\nUnpaid\nClaimed\nCancelled",
|
||||||
"columns": 0,
|
"read_only": 1
|
||||||
"fieldname": "status",
|
},
|
||||||
"fieldtype": "Select",
|
|
||||||
"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": "Status",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
|
||||||
"options": "Draft\nPaid\nUnpaid\nClaimed\nCancelled",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"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": "company",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Link",
|
||||||
"allow_on_submit": 0,
|
"label": "Company",
|
||||||
"bold": 0,
|
"options": "Company",
|
||||||
"collapsible": 0,
|
"reqd": 1
|
||||||
"columns": 0,
|
},
|
||||||
"fieldname": "company",
|
|
||||||
"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": "Company",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Company",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "amended_from",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Link",
|
||||||
"allow_on_submit": 0,
|
"label": "Amended From",
|
||||||
"bold": 0,
|
"no_copy": 1,
|
||||||
"collapsible": 0,
|
"options": "Employee Advance",
|
||||||
"columns": 0,
|
"print_hide": 1,
|
||||||
"fieldname": "amended_from",
|
"read_only": 1
|
||||||
"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": "Amended From",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
|
||||||
"options": "Employee Advance",
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 1,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"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_18",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Column Break"
|
||||||
"allow_on_submit": 0,
|
},
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_18",
|
|
||||||
"fieldtype": "Column Break",
|
|
||||||
"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,
|
"fieldname": "advance_account",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Link",
|
||||||
"allow_on_submit": 0,
|
"ignore_user_permissions": 1,
|
||||||
"bold": 0,
|
"label": "Advance Account",
|
||||||
"collapsible": 0,
|
"options": "Account",
|
||||||
"columns": 0,
|
"reqd": 1
|
||||||
"fieldname": "advance_account",
|
},
|
||||||
"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": "Advance Account",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Account",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "mode_of_payment",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Link",
|
||||||
"allow_on_submit": 0,
|
"label": "Mode of Payment",
|
||||||
"bold": 0,
|
"options": "Mode of Payment"
|
||||||
"collapsible": 0,
|
},
|
||||||
"columns": 0,
|
{
|
||||||
"fieldname": "mode_of_payment",
|
"fieldname": "return_amount",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
"label": "Returned Amount",
|
||||||
"ignore_user_permissions": 0,
|
"options": "Company:company:default_currency",
|
||||||
"ignore_xss_filter": 0,
|
"read_only": 1
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Mode of Payment",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Mode of Payment",
|
|
||||||
"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,
|
"is_submittable": 1,
|
||||||
"hide_heading": 0,
|
"links": [],
|
||||||
"hide_toolbar": 0,
|
"modified": "2019-12-15 19:04:07.044505",
|
||||||
"idx": 0,
|
"modified_by": "Administrator",
|
||||||
"image_view": 0,
|
"module": "HR",
|
||||||
"in_create": 0,
|
"name": "Employee Advance",
|
||||||
"is_submittable": 1,
|
"owner": "Administrator",
|
||||||
"issingle": 0,
|
|
||||||
"istable": 0,
|
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2019-01-30 11:28:15.529649",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "HR",
|
|
||||||
"name": "Employee Advance",
|
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"create": 1,
|
||||||
"cancel": 0,
|
"email": 1,
|
||||||
"create": 1,
|
"export": 1,
|
||||||
"delete": 0,
|
"print": 1,
|
||||||
"email": 1,
|
"read": 1,
|
||||||
"export": 1,
|
"report": 1,
|
||||||
"if_owner": 0,
|
"role": "Employee",
|
||||||
"import": 0,
|
"share": 1,
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "Employee",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 1,
|
"amend": 1,
|
||||||
"cancel": 1,
|
"cancel": 1,
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 1,
|
"export": 1,
|
||||||
"if_owner": 0,
|
"print": 1,
|
||||||
"import": 0,
|
"read": 1,
|
||||||
"permlevel": 0,
|
"report": 1,
|
||||||
"print": 1,
|
"role": "Expense Approver",
|
||||||
"read": 1,
|
"share": 1,
|
||||||
"report": 1,
|
"submit": 1,
|
||||||
"role": "Expense Approver",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 1,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 0,
|
"search_fields": "employee,employee_name",
|
||||||
"read_only": 0,
|
"sort_field": "modified",
|
||||||
"read_only_onload": 0,
|
"sort_order": "DESC",
|
||||||
"search_fields": "employee,employee_name",
|
"track_changes": 1
|
||||||
"show_name_in_global_search": 0,
|
}
|
||||||
"sort_field": "modified",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"track_changes": 1,
|
|
||||||
"track_seen": 0,
|
|
||||||
"track_views": 0
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import frappe, erpnext
|
|||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils import flt, nowdate
|
from frappe.utils import flt, nowdate
|
||||||
|
from erpnext.accounts.doctype.journal_entry.journal_entry import get_default_bank_cash_account
|
||||||
|
|
||||||
class EmployeeAdvanceOverPayment(frappe.ValidationError):
|
class EmployeeAdvanceOverPayment(frappe.ValidationError):
|
||||||
pass
|
pass
|
||||||
@@ -53,11 +54,25 @@ class EmployeeAdvance(Document):
|
|||||||
and party = %s
|
and party = %s
|
||||||
""", (self.name, self.employee), as_dict=1)[0].paid_amount
|
""", (self.name, self.employee), as_dict=1)[0].paid_amount
|
||||||
|
|
||||||
|
return_amount = frappe.db.sql("""
|
||||||
|
select name, ifnull(sum(credit_in_account_currency), 0) as return_amount
|
||||||
|
from `tabGL Entry`
|
||||||
|
where against_voucher_type = 'Employee Advance'
|
||||||
|
and voucher_type != 'Expense Claim'
|
||||||
|
and against_voucher = %s
|
||||||
|
and party_type = 'Employee'
|
||||||
|
and party = %s
|
||||||
|
""", (self.name, self.employee), as_dict=1)[0].return_amount
|
||||||
|
|
||||||
if flt(paid_amount) > self.advance_amount:
|
if flt(paid_amount) > self.advance_amount:
|
||||||
frappe.throw(_("Row {0}# Paid Amount cannot be greater than requested advance amount"),
|
frappe.throw(_("Row {0}# Paid Amount cannot be greater than requested advance amount"),
|
||||||
EmployeeAdvanceOverPayment)
|
EmployeeAdvanceOverPayment)
|
||||||
|
|
||||||
|
if flt(return_amount) > self.paid_amount - self.claimed_amount:
|
||||||
|
frappe.throw(_("Return amount cannot be greater unclaimed amount"))
|
||||||
|
|
||||||
self.db_set("paid_amount", paid_amount)
|
self.db_set("paid_amount", paid_amount)
|
||||||
|
self.db_set("return_amount", return_amount)
|
||||||
self.set_status()
|
self.set_status()
|
||||||
frappe.db.set_value("Employee Advance", self.name , "status", self.status)
|
frappe.db.set_value("Employee Advance", self.name , "status", self.status)
|
||||||
|
|
||||||
@@ -88,8 +103,6 @@ def get_due_advance_amount(employee, posting_date):
|
|||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def make_bank_entry(dt, dn):
|
def make_bank_entry(dt, dn):
|
||||||
from erpnext.accounts.doctype.journal_entry.journal_entry import get_default_bank_cash_account
|
|
||||||
|
|
||||||
doc = frappe.get_doc(dt, dn)
|
doc = frappe.get_doc(dt, dn)
|
||||||
payment_account = get_default_bank_cash_account(doc.company, account_type="Cash",
|
payment_account = get_default_bank_cash_account(doc.company, account_type="Cash",
|
||||||
mode_of_payment=doc.mode_of_payment)
|
mode_of_payment=doc.mode_of_payment)
|
||||||
@@ -118,3 +131,34 @@ def make_bank_entry(dt, dn):
|
|||||||
})
|
})
|
||||||
|
|
||||||
return je.as_dict()
|
return je.as_dict()
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def make_return_entry(employee, company, employee_advance_name,
|
||||||
|
return_amount, advance_account, mode_of_payment=None):
|
||||||
|
return_account = get_default_bank_cash_account(company, account_type='Cash', mode_of_payment = mode_of_payment)
|
||||||
|
je = frappe.new_doc('Journal Entry')
|
||||||
|
je.posting_date = nowdate()
|
||||||
|
je.voucher_type = 'Bank Entry'
|
||||||
|
je.company = company
|
||||||
|
je.remark = 'Return against Employee Advance: ' + employee_advance_name
|
||||||
|
|
||||||
|
je.append('accounts', {
|
||||||
|
'account': advance_account,
|
||||||
|
'credit_in_account_currency': return_amount,
|
||||||
|
'reference_type': 'Employee Advance',
|
||||||
|
'reference_name': employee_advance_name,
|
||||||
|
'party_type': 'Employee',
|
||||||
|
'party': employee,
|
||||||
|
'is_advance': 'Yes'
|
||||||
|
})
|
||||||
|
|
||||||
|
je.append("accounts", {
|
||||||
|
"account": return_account.account,
|
||||||
|
"debit_in_account_currency": return_amount,
|
||||||
|
"account_currency": return_account.account_currency,
|
||||||
|
"account_type": return_account.account_type
|
||||||
|
})
|
||||||
|
|
||||||
|
return je.as_dict()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
from frappe import _
|
||||||
|
|
||||||
|
def get_data():
|
||||||
|
return {
|
||||||
|
'fieldname': 'employee_advance',
|
||||||
|
'non_standard_fieldnames': {
|
||||||
|
'Payment Entry': 'reference_name',
|
||||||
|
'Journal Entry': 'reference_name'
|
||||||
|
},
|
||||||
|
'transactions': [
|
||||||
|
{
|
||||||
|
'items': ['Expense Claim']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'items': ['Payment Entry', 'Journal Entry']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -7,6 +7,14 @@ frappe.ui.form.on('Employee Onboarding', {
|
|||||||
frm.add_fetch("employee_onboarding_template", "department", "department");
|
frm.add_fetch("employee_onboarding_template", "department", "department");
|
||||||
frm.add_fetch("employee_onboarding_template", "designation", "designation");
|
frm.add_fetch("employee_onboarding_template", "designation", "designation");
|
||||||
frm.add_fetch("employee_onboarding_template", "employee_grade", "employee_grade");
|
frm.add_fetch("employee_onboarding_template", "employee_grade", "employee_grade");
|
||||||
|
|
||||||
|
frm.set_query('job_offer', function () {
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
'job_applicant': frm.doc.job_applicant
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh: function(frm) {
|
refresh: function(frm) {
|
||||||
|
|||||||
@@ -213,13 +213,14 @@ frappe.ui.form.on("Expense Claim", {
|
|||||||
},
|
},
|
||||||
|
|
||||||
update_employee_advance_claimed_amount: function(frm) {
|
update_employee_advance_claimed_amount: function(frm) {
|
||||||
|
console.log("update_employee_advance_claimed_amount")
|
||||||
let amount_to_be_allocated = frm.doc.grand_total;
|
let amount_to_be_allocated = frm.doc.grand_total;
|
||||||
$.each(frm.doc.advances || [], function(i, advance){
|
$.each(frm.doc.advances || [], function(i, advance){
|
||||||
if (amount_to_be_allocated >= advance.unclaimed_amount){
|
if (amount_to_be_allocated >= advance.unclaimed_amount){
|
||||||
frm.doc.advances[i].allocated_amount = frm.doc.advances[i].unclaimed_amount;
|
advance.allocated_amount = frm.doc.advances[i].unclaimed_amount;
|
||||||
amount_to_be_allocated -= advance.allocated_amount;
|
amount_to_be_allocated -= advance.allocated_amount;
|
||||||
} else{
|
} else{
|
||||||
frm.doc.advances[i].allocated_amount = amount_to_be_allocated;
|
advance.allocated_amount = amount_to_be_allocated;
|
||||||
amount_to_be_allocated = 0;
|
amount_to_be_allocated = 0;
|
||||||
}
|
}
|
||||||
frm.refresh_field("advances");
|
frm.refresh_field("advances");
|
||||||
@@ -295,6 +296,7 @@ frappe.ui.form.on("Expense Claim", {
|
|||||||
doc: frm.doc,
|
doc: frm.doc,
|
||||||
callback: () => {
|
callback: () => {
|
||||||
refresh_field("taxes");
|
refresh_field("taxes");
|
||||||
|
frm.trigger("update_employee_advance_claimed_amount");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -331,16 +333,12 @@ frappe.ui.form.on("Expense Claim", {
|
|||||||
frappe.ui.form.on("Expense Claim Detail", {
|
frappe.ui.form.on("Expense Claim Detail", {
|
||||||
amount: function(frm, cdt, cdn) {
|
amount: function(frm, cdt, cdn) {
|
||||||
var child = locals[cdt][cdn];
|
var child = locals[cdt][cdn];
|
||||||
var doc = frm.doc;
|
|
||||||
frappe.model.set_value(cdt, cdn, 'sanctioned_amount', child.amount);
|
frappe.model.set_value(cdt, cdn, 'sanctioned_amount', child.amount);
|
||||||
cur_frm.cscript.calculate_total(doc,cdt,cdn);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
sanctioned_amount: function(frm, cdt, cdn) {
|
sanctioned_amount: function(frm, cdt, cdn) {
|
||||||
var doc = frm.doc;
|
cur_frm.cscript.calculate_total(frm.doc, cdt, cdn);
|
||||||
cur_frm.cscript.calculate_total(doc,cdt,cdn);
|
|
||||||
frm.trigger("get_taxes");
|
frm.trigger("get_taxes");
|
||||||
frm.trigger("calculate_grand_total");
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -243,6 +243,7 @@ class ExpenseClaim(AccountsController):
|
|||||||
precision = self.precision("total_advance_amount")
|
precision = self.precision("total_advance_amount")
|
||||||
if flt(self.total_advance_amount, precision) > flt(self.total_claimed_amount, precision):
|
if flt(self.total_advance_amount, precision) > flt(self.total_claimed_amount, precision):
|
||||||
frappe.throw(_("Total advance amount cannot be greater than total claimed amount"))
|
frappe.throw(_("Total advance amount cannot be greater than total claimed amount"))
|
||||||
|
|
||||||
if self.total_sanctioned_amount \
|
if self.total_sanctioned_amount \
|
||||||
and flt(self.total_advance_amount, precision) > flt(self.total_sanctioned_amount, precision):
|
and flt(self.total_advance_amount, precision) > flt(self.total_sanctioned_amount, precision):
|
||||||
frappe.throw(_("Total advance amount cannot be greater than total sanctioned amount"))
|
frappe.throw(_("Total advance amount cannot be greater than total sanctioned amount"))
|
||||||
@@ -321,7 +322,7 @@ def get_expense_claim_account(expense_claim_type, company):
|
|||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_advances(employee, advance_id=None):
|
def get_advances(employee, advance_id=None):
|
||||||
if not advance_id:
|
if not advance_id:
|
||||||
condition = 'docstatus=1 and employee={0} and paid_amount > 0 and paid_amount > claimed_amount'.format(frappe.db.escape(employee))
|
condition = 'docstatus=1 and employee={0} and paid_amount > 0 and paid_amount > claimed_amount + return_amount'.format(frappe.db.escape(employee))
|
||||||
else:
|
else:
|
||||||
condition = 'name={0}'.format(frappe.db.escape(advance_id))
|
condition = 'name={0}'.format(frappe.db.escape(advance_id))
|
||||||
|
|
||||||
|
|||||||
@@ -1,238 +1,93 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"creation": "2017-10-09 16:53:26.410762",
|
||||||
"allow_guest_to_view": 0,
|
"doctype": "DocType",
|
||||||
"allow_import": 0,
|
"document_type": "Document",
|
||||||
"allow_rename": 0,
|
"editable_grid": 1,
|
||||||
"beta": 0,
|
"engine": "InnoDB",
|
||||||
"creation": "2017-10-09 16:53:26.410762",
|
"field_order": [
|
||||||
"custom": 0,
|
"employee_advance",
|
||||||
"docstatus": 0,
|
"posting_date",
|
||||||
"doctype": "DocType",
|
"advance_paid",
|
||||||
"document_type": "Document",
|
"unclaimed_amount",
|
||||||
"editable_grid": 1,
|
"allocated_amount",
|
||||||
"engine": "InnoDB",
|
"advance_account"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"columns": 2,
|
||||||
"allow_on_submit": 0,
|
"fieldname": "employee_advance",
|
||||||
"bold": 0,
|
"fieldtype": "Link",
|
||||||
"collapsible": 0,
|
"in_list_view": 1,
|
||||||
"columns": 2,
|
"label": "Employee Advance",
|
||||||
"fieldname": "employee_advance",
|
"no_copy": 1,
|
||||||
"fieldtype": "Link",
|
"oldfieldname": "journal_voucher",
|
||||||
"hidden": 0,
|
"oldfieldtype": "Link",
|
||||||
"ignore_user_permissions": 0,
|
"options": "Employee Advance",
|
||||||
"ignore_xss_filter": 0,
|
"print_width": "250px",
|
||||||
"in_filter": 0,
|
"reqd": 1,
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Employee Advance",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
|
||||||
"oldfieldname": "journal_voucher",
|
|
||||||
"oldfieldtype": "Link",
|
|
||||||
"options": "Employee Advance",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"print_width": "250px",
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0,
|
|
||||||
"width": "250px"
|
"width": "250px"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"columns": 2,
|
||||||
"allow_on_submit": 0,
|
"fieldname": "posting_date",
|
||||||
"bold": 0,
|
"fieldtype": "Date",
|
||||||
"collapsible": 0,
|
"in_list_view": 1,
|
||||||
"columns": 2,
|
"label": "Posting Date",
|
||||||
"fieldname": "posting_date",
|
"read_only": 1
|
||||||
"fieldtype": "Date",
|
},
|
||||||
"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": "Posting Date",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"columns": 2,
|
||||||
"allow_on_submit": 0,
|
"fieldname": "advance_paid",
|
||||||
"bold": 0,
|
"fieldtype": "Currency",
|
||||||
"collapsible": 0,
|
"in_list_view": 1,
|
||||||
"columns": 2,
|
"label": "Advance Paid",
|
||||||
"fieldname": "advance_paid",
|
"options": "Company:company:default_currency",
|
||||||
"fieldtype": "Currency",
|
"read_only": 1
|
||||||
"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": "Advance Paid",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Company:company.default_currency",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"columns": 2,
|
||||||
"allow_on_submit": 0,
|
"fieldname": "unclaimed_amount",
|
||||||
"bold": 0,
|
"fieldtype": "Currency",
|
||||||
"collapsible": 0,
|
"in_list_view": 1,
|
||||||
"columns": 2,
|
"label": "Unclaimed amount",
|
||||||
"fieldname": "unclaimed_amount",
|
"no_copy": 1,
|
||||||
"fieldtype": "Currency",
|
"oldfieldname": "advance_amount",
|
||||||
"hidden": 0,
|
"oldfieldtype": "Currency",
|
||||||
"ignore_user_permissions": 0,
|
"options": "Company:company:default_currency",
|
||||||
"ignore_xss_filter": 0,
|
"print_width": "120px",
|
||||||
"in_filter": 0,
|
"read_only": 1,
|
||||||
"in_global_search": 0,
|
"reqd": 1,
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Unclaimed amount",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
|
||||||
"oldfieldname": "advance_amount",
|
|
||||||
"oldfieldtype": "Currency",
|
|
||||||
"options": "Company:company.default_currency",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"print_width": "120px",
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0,
|
|
||||||
"width": "120px"
|
"width": "120px"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"columns": 2,
|
||||||
"allow_on_submit": 0,
|
"fieldname": "allocated_amount",
|
||||||
"bold": 0,
|
"fieldtype": "Currency",
|
||||||
"collapsible": 0,
|
"in_list_view": 1,
|
||||||
"columns": 2,
|
"label": "Allocated amount",
|
||||||
"fieldname": "allocated_amount",
|
"no_copy": 1,
|
||||||
"fieldtype": "Currency",
|
"oldfieldname": "allocated_amount",
|
||||||
"hidden": 0,
|
"oldfieldtype": "Currency",
|
||||||
"ignore_user_permissions": 0,
|
"options": "Company:company:default_currency",
|
||||||
"ignore_xss_filter": 0,
|
"print_width": "120px",
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Allocated amount",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
|
||||||
"oldfieldname": "allocated_amount",
|
|
||||||
"oldfieldtype": "Currency",
|
|
||||||
"options": "Company:company.default_currency",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"print_width": "120px",
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0,
|
|
||||||
"width": "120px"
|
"width": "120px"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "advance_account",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Link",
|
||||||
"bold": 0,
|
"hidden": 1,
|
||||||
"collapsible": 0,
|
"label": "Advance Account",
|
||||||
"columns": 0,
|
"options": "Account"
|
||||||
"fieldname": "advance_account",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"hidden": 1,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Advance Account",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Account",
|
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
"istable": 1,
|
||||||
"hide_heading": 0,
|
"modified": "2020-01-14 17:49:17.968373",
|
||||||
"hide_toolbar": 0,
|
"modified_by": "Administrator",
|
||||||
"idx": 0,
|
"module": "HR",
|
||||||
"image_view": 0,
|
"name": "Expense Claim Advance",
|
||||||
"in_create": 0,
|
"owner": "Administrator",
|
||||||
"is_submittable": 0,
|
"permissions": [],
|
||||||
"issingle": 0,
|
"quick_entry": 1,
|
||||||
"istable": 1,
|
"sort_field": "modified",
|
||||||
"max_attachments": 0,
|
"sort_order": "DESC"
|
||||||
"modified": "2017-10-09 19:59:48.818139",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "HR",
|
|
||||||
"name": "Expense Claim Advance",
|
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [],
|
|
||||||
"quick_entry": 1,
|
|
||||||
"read_only": 0,
|
|
||||||
"read_only_onload": 0,
|
|
||||||
"show_name_in_global_search": 0,
|
|
||||||
"sort_field": "modified",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"track_changes": 0,
|
|
||||||
"track_seen": 0
|
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"creation": "2013-08-02 13:45:23",
|
"creation": "2013-08-02 13:45:23",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "Other",
|
"document_type": "Other",
|
||||||
@@ -13,6 +14,7 @@
|
|||||||
"expense_approver_mandatory_in_expense_claim",
|
"expense_approver_mandatory_in_expense_claim",
|
||||||
"payroll_settings",
|
"payroll_settings",
|
||||||
"include_holidays_in_total_working_days",
|
"include_holidays_in_total_working_days",
|
||||||
|
"disable_rounded_total",
|
||||||
"max_working_hours_against_timesheet",
|
"max_working_hours_against_timesheet",
|
||||||
"column_break_11",
|
"column_break_11",
|
||||||
"email_salary_slip_to_employee",
|
"email_salary_slip_to_employee",
|
||||||
@@ -160,12 +162,20 @@
|
|||||||
"fieldname": "auto_leave_encashment",
|
"fieldname": "auto_leave_encashment",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Auto Leave Encashment"
|
"label": "Auto Leave Encashment"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"description": "If checked, hides and disables Rounded Total field in Salary Slips",
|
||||||
|
"fieldname": "disable_rounded_total",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Disable Rounded Total"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-cog",
|
"icon": "fa fa-cog",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"modified": "2019-08-05 13:07:17.993968",
|
"links": [],
|
||||||
|
"modified": "2019-12-31 14:28:32.004121",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "HR Settings",
|
"name": "HR Settings",
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
from frappe.utils import cint
|
||||||
|
from frappe.custom.doctype.property_setter.property_setter import make_property_setter
|
||||||
|
|
||||||
class HRSettings(Document):
|
class HRSettings(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
@@ -22,3 +24,12 @@ class HRSettings(Document):
|
|||||||
if self.email_salary_slip_to_employee and self.encrypt_salary_slips_in_emails:
|
if self.email_salary_slip_to_employee and self.encrypt_salary_slips_in_emails:
|
||||||
if not self.password_policy:
|
if not self.password_policy:
|
||||||
frappe.throw(_("Password policy for Salary Slips is not set"))
|
frappe.throw(_("Password policy for Salary Slips is not set"))
|
||||||
|
|
||||||
|
def on_update(self):
|
||||||
|
self.toggle_rounded_total()
|
||||||
|
frappe.clear_cache()
|
||||||
|
|
||||||
|
def toggle_rounded_total(self):
|
||||||
|
self.disable_rounded_total = cint(self.disable_rounded_total)
|
||||||
|
make_property_setter("Salary Slip", "rounded_total", "hidden", self.disable_rounded_total, "Check")
|
||||||
|
make_property_setter("Salary Slip", "rounded_total", "print_hide", self.disable_rounded_total, "Check")
|
||||||
|
|||||||
@@ -351,7 +351,7 @@ class LeaveApplication(Document):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def create_leave_ledger_entry(self, submit=True):
|
def create_leave_ledger_entry(self, submit=True):
|
||||||
if self.status != 'Approved':
|
if self.status != 'Approved' and submit:
|
||||||
return
|
return
|
||||||
|
|
||||||
expiry_date = get_allocation_expiry(self.employee, self.leave_type,
|
expiry_date = get_allocation_expiry(self.employee, self.leave_type,
|
||||||
|
|||||||
@@ -235,8 +235,8 @@ class TestLeaveApplication(unittest.TestCase):
|
|||||||
frappe.get_doc(dict(
|
frappe.get_doc(dict(
|
||||||
doctype = 'Holiday List',
|
doctype = 'Holiday List',
|
||||||
holiday_list_name = holiday_list,
|
holiday_list_name = holiday_list,
|
||||||
from_date = date(date.today().year, 1, 1),
|
from_date = add_months(today, -6),
|
||||||
to_date = date(date.today().year, 12, 31),
|
to_date = add_months(today, 6),
|
||||||
holidays = [
|
holidays = [
|
||||||
dict(holiday_date = today, description = 'Test')
|
dict(holiday_date = today, description = 'Test')
|
||||||
]
|
]
|
||||||
@@ -597,8 +597,8 @@ def get_leave_period():
|
|||||||
return frappe.get_doc(dict(
|
return frappe.get_doc(dict(
|
||||||
name = 'Test Leave Period',
|
name = 'Test Leave Period',
|
||||||
doctype = 'Leave Period',
|
doctype = 'Leave Period',
|
||||||
from_date = "{0}-12-01".format(now_datetime().year - 1),
|
from_date = add_months(nowdate(), -6),
|
||||||
to_date = "{0}-12-31".format(now_datetime().year),
|
to_date = add_months(nowdate(), 6),
|
||||||
company = "_Test Company",
|
company = "_Test Company",
|
||||||
is_active = 1
|
is_active = 1
|
||||||
)).insert()
|
)).insert()
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -16,6 +16,7 @@ class Loan(AccountsController):
|
|||||||
self.make_repayment_schedule()
|
self.make_repayment_schedule()
|
||||||
self.set_repayment_period()
|
self.set_repayment_period()
|
||||||
self.calculate_totals()
|
self.calculate_totals()
|
||||||
|
self.set_status(from_validate=True)
|
||||||
|
|
||||||
def set_missing_fields(self):
|
def set_missing_fields(self):
|
||||||
if not self.company:
|
if not self.company:
|
||||||
@@ -95,43 +96,57 @@ class Loan(AccountsController):
|
|||||||
self.total_payment = 0
|
self.total_payment = 0
|
||||||
self.total_interest_payable = 0
|
self.total_interest_payable = 0
|
||||||
self.total_amount_paid = 0
|
self.total_amount_paid = 0
|
||||||
for data in self.repayment_schedule:
|
for schedule in self.repayment_schedule:
|
||||||
self.total_payment += data.total_payment
|
self.total_payment += schedule.total_payment
|
||||||
self.total_interest_payable +=data.interest_amount
|
self.total_interest_payable +=schedule.interest_amount
|
||||||
if data.paid:
|
if schedule.paid:
|
||||||
self.total_amount_paid += data.total_payment
|
self.total_amount_paid += schedule.total_payment
|
||||||
|
|
||||||
def update_total_amount_paid(doc):
|
def update_total_amount_paid(self):
|
||||||
total_amount_paid = 0
|
total_amount_paid = 0
|
||||||
for data in doc.repayment_schedule:
|
for schedule in self.repayment_schedule:
|
||||||
if data.paid:
|
if schedule.paid:
|
||||||
total_amount_paid += data.total_payment
|
total_amount_paid += schedule.total_payment
|
||||||
frappe.db.set_value("Loan", doc.name, "total_amount_paid", total_amount_paid)
|
frappe.db.set_value("Loan", self.name, "total_amount_paid", total_amount_paid)
|
||||||
|
|
||||||
def update_disbursement_status(doc):
|
def set_status(self, from_validate=False):
|
||||||
disbursement = frappe.db.sql("""
|
disbursement = self.get_disbursement_entry()
|
||||||
select posting_date, ifnull(sum(credit_in_account_currency), 0) as disbursed_amount
|
disbursement_date = None
|
||||||
from `tabGL Entry`
|
|
||||||
where account = %s and against_voucher_type = 'Loan' and against_voucher = %s
|
|
||||||
""", (doc.payment_account, doc.name), as_dict=1)[0]
|
|
||||||
|
|
||||||
disbursement_date = None
|
self.status = "Draft"
|
||||||
if not disbursement or disbursement.disbursed_amount == 0:
|
|
||||||
status = "Sanctioned"
|
|
||||||
elif disbursement.disbursed_amount == doc.loan_amount:
|
|
||||||
disbursement_date = disbursement.posting_date
|
|
||||||
status = "Disbursed"
|
|
||||||
elif disbursement.disbursed_amount > doc.loan_amount:
|
|
||||||
frappe.throw(_("Disbursed Amount cannot be greater than Loan Amount {0}").format(doc.loan_amount))
|
|
||||||
|
|
||||||
if status == 'Disbursed' and getdate(disbursement_date) > getdate(frappe.db.get_value("Loan", doc.name, "repayment_start_date")):
|
if (not disbursement or disbursement.disbursed_amount == 0) and self.docstatus == 1:
|
||||||
|
self.status = "Sanctioned"
|
||||||
|
if disbursement:
|
||||||
|
self.validate_disbursed_amount_and_loan_amount(disbursement.disbursed_amount)
|
||||||
|
if disbursement.disbursed_amount == self.loan_amount and disbursement.disbursed_amount != 0:
|
||||||
|
self.status = "Disbursed"
|
||||||
|
disbursement_date = disbursement.posting_date
|
||||||
|
self.validate_disbursement_date(disbursement_date, self.status)
|
||||||
|
|
||||||
|
if self.total_amount_paid == self.total_payment:
|
||||||
|
self.status = "Repaid/Closed"
|
||||||
|
|
||||||
|
if not from_validate:
|
||||||
|
frappe.db.set_value("Loan", self.name, "status", self.status)
|
||||||
|
if disbursement_date:
|
||||||
|
frappe.db.set_value("Loan", self.name, "disbursement_date", disbursement_date)
|
||||||
|
|
||||||
|
def validate_disbursement_date(self, disbursement_date, loan_status):
|
||||||
|
if loan_status == 'Disbursed' and getdate(disbursement_date) > getdate(frappe.db.get_value("Loan", self.name, "repayment_start_date")):
|
||||||
frappe.throw(_("Disbursement Date cannot be after Loan Repayment Start Date"))
|
frappe.throw(_("Disbursement Date cannot be after Loan Repayment Start Date"))
|
||||||
|
|
||||||
frappe.db.sql("""
|
|
||||||
update `tabLoan`
|
def validate_disbursed_amount_and_loan_amount(self, disbursed_amount):
|
||||||
set status = %s, disbursement_date = %s
|
if disbursed_amount > self.loan_amount:
|
||||||
where name = %s
|
frappe.throw(_("Disbursed Amount cannot be greater than Loan Amount {0}").format(self.loan_amount))
|
||||||
""", (status, disbursement_date, doc.name))
|
|
||||||
|
def get_disbursement_entry(self):
|
||||||
|
return frappe.db.sql("""
|
||||||
|
select posting_date, ifnull(sum(credit_in_account_currency), 0) as disbursed_amount
|
||||||
|
from `tabGL Entry`
|
||||||
|
where account = %s and against_voucher_type = 'Loan' and against_voucher = %s
|
||||||
|
""", (self.payment_account, self.name), as_dict=1)[0]
|
||||||
|
|
||||||
def validate_repayment_method(repayment_method, loan_amount, monthly_repayment_amount, repayment_periods):
|
def validate_repayment_method(repayment_method, loan_amount, monthly_repayment_amount, repayment_periods):
|
||||||
if repayment_method == "Repay Over Number of Periods" and not repayment_periods:
|
if repayment_method == "Repay Over Number of Periods" and not repayment_periods:
|
||||||
|
|||||||
@@ -31,7 +31,11 @@ frappe.ui.form.on('Payroll Entry', {
|
|||||||
}
|
}
|
||||||
if ((frm.doc.employees || []).length) {
|
if ((frm.doc.employees || []).length) {
|
||||||
frm.page.set_primary_action(__('Create Salary Slips'), () => {
|
frm.page.set_primary_action(__('Create Salary Slips'), () => {
|
||||||
frm.save('Submit');
|
frm.save('Submit').then(()=>{
|
||||||
|
frm.page.clear_primary_action();
|
||||||
|
frm.refresh();
|
||||||
|
frm.events.refresh(frm);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ class PayrollEntry(Document):
|
|||||||
"""
|
"""
|
||||||
cond = self.get_filter_condition()
|
cond = self.get_filter_condition()
|
||||||
return frappe.db.sql(""" select eld.loan_account, eld.loan,
|
return frappe.db.sql(""" select eld.loan_account, eld.loan,
|
||||||
eld.interest_income_account, eld.principal_amount, eld.interest_amount, eld.total_payment
|
eld.interest_income_account, eld.principal_amount, eld.interest_amount, eld.total_payment,t1.employee
|
||||||
from
|
from
|
||||||
`tabSalary Slip` t1, `tabSalary Slip Loan` eld
|
`tabSalary Slip` t1, `tabSalary Slip Loan` eld
|
||||||
where
|
where
|
||||||
@@ -246,6 +246,7 @@ class PayrollEntry(Document):
|
|||||||
accounts.append({
|
accounts.append({
|
||||||
"account": acc,
|
"account": acc,
|
||||||
"debit_in_account_currency": flt(amount, precision),
|
"debit_in_account_currency": flt(amount, precision),
|
||||||
|
"party_type": '',
|
||||||
"cost_center": self.cost_center,
|
"cost_center": self.cost_center,
|
||||||
"project": self.project
|
"project": self.project
|
||||||
})
|
})
|
||||||
@@ -257,6 +258,7 @@ class PayrollEntry(Document):
|
|||||||
"account": acc,
|
"account": acc,
|
||||||
"credit_in_account_currency": flt(amount, precision),
|
"credit_in_account_currency": flt(amount, precision),
|
||||||
"cost_center": self.cost_center,
|
"cost_center": self.cost_center,
|
||||||
|
"party_type": '',
|
||||||
"project": self.project
|
"project": self.project
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -264,7 +266,9 @@ class PayrollEntry(Document):
|
|||||||
for data in loan_details:
|
for data in loan_details:
|
||||||
accounts.append({
|
accounts.append({
|
||||||
"account": data.loan_account,
|
"account": data.loan_account,
|
||||||
"credit_in_account_currency": data.principal_amount
|
"credit_in_account_currency": data.principal_amount,
|
||||||
|
"party_type": "Employee",
|
||||||
|
"party": data.employee
|
||||||
})
|
})
|
||||||
|
|
||||||
if data.interest_amount and not data.interest_income_account:
|
if data.interest_amount and not data.interest_income_account:
|
||||||
@@ -275,14 +279,17 @@ class PayrollEntry(Document):
|
|||||||
"account": data.interest_income_account,
|
"account": data.interest_income_account,
|
||||||
"credit_in_account_currency": data.interest_amount,
|
"credit_in_account_currency": data.interest_amount,
|
||||||
"cost_center": self.cost_center,
|
"cost_center": self.cost_center,
|
||||||
"project": self.project
|
"project": self.project,
|
||||||
|
"party_type": "Employee",
|
||||||
|
"party": data.employee
|
||||||
})
|
})
|
||||||
payable_amount -= flt(data.total_payment, precision)
|
payable_amount -= flt(data.total_payment, precision)
|
||||||
|
|
||||||
# Payable amount
|
# Payable amount
|
||||||
accounts.append({
|
accounts.append({
|
||||||
"account": default_payroll_payable_account,
|
"account": default_payroll_payable_account,
|
||||||
"credit_in_account_currency": flt(payable_amount, precision)
|
"credit_in_account_currency": flt(payable_amount, precision),
|
||||||
|
"party_type": '',
|
||||||
})
|
})
|
||||||
|
|
||||||
journal_entry.set("accounts", accounts)
|
journal_entry.set("accounts", accounts)
|
||||||
@@ -322,6 +329,10 @@ class PayrollEntry(Document):
|
|||||||
statistical_component = frappe.db.get_value("Salary Component", sal_detail.salary_component, 'statistical_component')
|
statistical_component = frappe.db.get_value("Salary Component", sal_detail.salary_component, 'statistical_component')
|
||||||
if statistical_component != 1:
|
if statistical_component != 1:
|
||||||
salary_slip_total -= sal_detail.amount
|
salary_slip_total -= sal_detail.amount
|
||||||
|
|
||||||
|
#loan deduction from bank entry during payroll
|
||||||
|
salary_slip_total -= salary_slip.total_loan_repayment
|
||||||
|
|
||||||
if salary_slip_total > 0:
|
if salary_slip_total > 0:
|
||||||
self.create_journal_entry(salary_slip_total, "salary")
|
self.create_journal_entry(salary_slip_total, "salary")
|
||||||
|
|
||||||
@@ -546,7 +557,6 @@ def submit_salary_slips_for_employees(payroll_entry, salary_slips, publish_progr
|
|||||||
count += 1
|
count += 1
|
||||||
if publish_progress:
|
if publish_progress:
|
||||||
frappe.publish_progress(count*100/len(salary_slips), title = _("Submitting Salary Slips..."))
|
frappe.publish_progress(count*100/len(salary_slips), title = _("Submitting Salary Slips..."))
|
||||||
|
|
||||||
if submitted_ss:
|
if submitted_ss:
|
||||||
payroll_entry.make_accrual_jv_entry()
|
payroll_entry.make_accrual_jv_entry()
|
||||||
frappe.msgprint(_("Salary Slip submitted for period from {0} to {1}")
|
frappe.msgprint(_("Salary Slip submitted for period from {0} to {1}")
|
||||||
|
|||||||
@@ -1,231 +1,82 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"creation": "2016-12-20 15:32:25.078334",
|
||||||
"allow_guest_to_view": 0,
|
"doctype": "DocType",
|
||||||
"allow_import": 0,
|
"editable_grid": 1,
|
||||||
"allow_rename": 0,
|
"engine": "InnoDB",
|
||||||
"beta": 0,
|
"field_order": [
|
||||||
"creation": "2016-12-20 15:32:25.078334",
|
"payment_date",
|
||||||
"custom": 0,
|
"principal_amount",
|
||||||
"docstatus": 0,
|
"interest_amount",
|
||||||
"doctype": "DocType",
|
"total_payment",
|
||||||
"document_type": "",
|
"balance_loan_amount",
|
||||||
"editable_grid": 1,
|
"paid"
|
||||||
"engine": "InnoDB",
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_on_submit": 1,
|
||||||
"allow_on_submit": 0,
|
"columns": 2,
|
||||||
"bold": 0,
|
"fieldname": "payment_date",
|
||||||
"collapsible": 0,
|
"fieldtype": "Date",
|
||||||
"columns": 2,
|
"in_list_view": 1,
|
||||||
"fieldname": "payment_date",
|
"label": "Payment Date"
|
||||||
"fieldtype": "Date",
|
},
|
||||||
"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": "Payment Date",
|
|
||||||
"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,
|
"columns": 2,
|
||||||
"allow_on_submit": 0,
|
"fieldname": "principal_amount",
|
||||||
"bold": 0,
|
"fieldtype": "Currency",
|
||||||
"collapsible": 0,
|
"in_list_view": 1,
|
||||||
"columns": 2,
|
"label": "Principal Amount",
|
||||||
"fieldname": "principal_amount",
|
"no_copy": 1,
|
||||||
"fieldtype": "Currency",
|
"options": "Company:company:default_currency",
|
||||||
"hidden": 0,
|
"read_only": 1
|
||||||
"ignore_user_permissions": 0,
|
},
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Principal Amount",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
|
||||||
"options": "Company:company:default_currency",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"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,
|
"columns": 2,
|
||||||
"allow_on_submit": 0,
|
"fieldname": "interest_amount",
|
||||||
"bold": 0,
|
"fieldtype": "Currency",
|
||||||
"collapsible": 0,
|
"in_list_view": 1,
|
||||||
"columns": 2,
|
"label": "Interest Amount",
|
||||||
"fieldname": "interest_amount",
|
"no_copy": 1,
|
||||||
"fieldtype": "Currency",
|
"options": "Company:company:default_currency",
|
||||||
"hidden": 0,
|
"read_only": 1
|
||||||
"ignore_user_permissions": 0,
|
},
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Interest Amount",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
|
||||||
"options": "Company:company:default_currency",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"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,
|
"columns": 2,
|
||||||
"allow_on_submit": 0,
|
"fieldname": "total_payment",
|
||||||
"bold": 0,
|
"fieldtype": "Currency",
|
||||||
"collapsible": 0,
|
"in_list_view": 1,
|
||||||
"columns": 2,
|
"label": "Total Payment",
|
||||||
"fieldname": "total_payment",
|
"options": "Company:company:default_currency",
|
||||||
"fieldtype": "Currency",
|
"read_only": 1
|
||||||
"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": "Total Payment",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Company:company:default_currency",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"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,
|
"columns": 2,
|
||||||
"allow_on_submit": 0,
|
"fieldname": "balance_loan_amount",
|
||||||
"bold": 0,
|
"fieldtype": "Currency",
|
||||||
"collapsible": 0,
|
"in_list_view": 1,
|
||||||
"columns": 2,
|
"label": "Balance Loan Amount",
|
||||||
"fieldname": "balance_loan_amount",
|
"no_copy": 1,
|
||||||
"fieldtype": "Currency",
|
"options": "Company:company:default_currency",
|
||||||
"hidden": 0,
|
"read_only": 1
|
||||||
"ignore_user_permissions": 0,
|
},
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Balance Loan Amount",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
|
||||||
"options": "Company:company:default_currency",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"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_on_submit": 0,
|
"fieldname": "paid",
|
||||||
"bold": 0,
|
"fieldtype": "Check",
|
||||||
"collapsible": 0,
|
"in_list_view": 1,
|
||||||
"columns": 0,
|
"label": "Paid",
|
||||||
"fieldname": "paid",
|
"read_only": 1
|
||||||
"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": "Paid",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"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,
|
"istable": 1,
|
||||||
"hide_heading": 0,
|
"modified": "2019-10-29 11:45:10.694557",
|
||||||
"hide_toolbar": 0,
|
"modified_by": "Administrator",
|
||||||
"idx": 0,
|
"module": "HR",
|
||||||
"image_view": 0,
|
"name": "Repayment Schedule",
|
||||||
"in_create": 0,
|
"owner": "Administrator",
|
||||||
"is_submittable": 0,
|
"permissions": [],
|
||||||
"issingle": 0,
|
"quick_entry": 1,
|
||||||
"istable": 1,
|
"sort_field": "modified",
|
||||||
"max_attachments": 0,
|
"sort_order": "DESC",
|
||||||
"modified": "2018-03-30 17:37:31.834792",
|
"track_changes": 1
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "HR",
|
|
||||||
"name": "Repayment Schedule",
|
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [],
|
|
||||||
"quick_entry": 1,
|
|
||||||
"read_only": 0,
|
|
||||||
"read_only_onload": 0,
|
|
||||||
"show_name_in_global_search": 0,
|
|
||||||
"sort_field": "modified",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"track_changes": 1,
|
|
||||||
"track_seen": 0
|
|
||||||
}
|
}
|
||||||
@@ -50,7 +50,8 @@ class SalarySlip(TransactionBase):
|
|||||||
self.calculate_net_pay()
|
self.calculate_net_pay()
|
||||||
|
|
||||||
company_currency = erpnext.get_company_currency(self.company)
|
company_currency = erpnext.get_company_currency(self.company)
|
||||||
self.total_in_words = money_in_words(self.rounded_total, company_currency)
|
total = self.net_pay if self.is_rounding_total_disabled() else self.rounded_total
|
||||||
|
self.total_in_words = money_in_words(total, company_currency)
|
||||||
|
|
||||||
if frappe.db.get_single_value("HR Settings", "max_working_hours_against_timesheet"):
|
if frappe.db.get_single_value("HR Settings", "max_working_hours_against_timesheet"):
|
||||||
max_working_hours = frappe.db.get_single_value("HR Settings", "max_working_hours_against_timesheet")
|
max_working_hours = frappe.db.get_single_value("HR Settings", "max_working_hours_against_timesheet")
|
||||||
@@ -62,6 +63,7 @@ class SalarySlip(TransactionBase):
|
|||||||
if self.net_pay < 0:
|
if self.net_pay < 0:
|
||||||
frappe.throw(_("Net Pay cannot be less than 0"))
|
frappe.throw(_("Net Pay cannot be less than 0"))
|
||||||
else:
|
else:
|
||||||
|
self.update_loans()
|
||||||
self.set_status()
|
self.set_status()
|
||||||
self.update_status(self.name)
|
self.update_status(self.name)
|
||||||
self.update_salary_slip_in_additional_salary()
|
self.update_salary_slip_in_additional_salary()
|
||||||
@@ -69,6 +71,7 @@ class SalarySlip(TransactionBase):
|
|||||||
self.email_salary_slip()
|
self.email_salary_slip()
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
|
self.update_loans()
|
||||||
self.set_status()
|
self.set_status()
|
||||||
self.update_status()
|
self.update_status()
|
||||||
self.update_salary_slip_in_additional_salary()
|
self.update_salary_slip_in_additional_salary()
|
||||||
@@ -90,6 +93,9 @@ class SalarySlip(TransactionBase):
|
|||||||
if date_diff(self.end_date, self.start_date) < 0:
|
if date_diff(self.end_date, self.start_date) < 0:
|
||||||
frappe.throw(_("To date cannot be before From date"))
|
frappe.throw(_("To date cannot be before From date"))
|
||||||
|
|
||||||
|
def is_rounding_total_disabled(self):
|
||||||
|
return cint(frappe.db.get_single_value("HR Settings", "disable_rounded_total"))
|
||||||
|
|
||||||
def check_existing(self):
|
def check_existing(self):
|
||||||
if not self.salary_slip_based_on_timesheet:
|
if not self.salary_slip_based_on_timesheet:
|
||||||
ret_exist = frappe.db.sql("""select name from `tabSalary Slip`
|
ret_exist = frappe.db.sql("""select name from `tabSalary Slip`
|
||||||
@@ -764,7 +770,8 @@ class SalarySlip(TransactionBase):
|
|||||||
self.total_principal_amount += loan.principal_amount
|
self.total_principal_amount += loan.principal_amount
|
||||||
|
|
||||||
def get_loan_details(self):
|
def get_loan_details(self):
|
||||||
return frappe.db.sql("""select rps.principal_amount, rps.interest_amount, l.name,
|
return frappe.db.sql("""select rps.principal_amount,
|
||||||
|
rps.name as repayment_name, rps.interest_amount, l.name,
|
||||||
rps.total_payment, l.loan_account, l.interest_income_account
|
rps.total_payment, l.loan_account, l.interest_income_account
|
||||||
from
|
from
|
||||||
`tabRepayment Schedule` as rps, `tabLoan` as l
|
`tabRepayment Schedule` as rps, `tabLoan` as l
|
||||||
@@ -815,6 +822,17 @@ class SalarySlip(TransactionBase):
|
|||||||
timesheet.set_status()
|
timesheet.set_status()
|
||||||
timesheet.save()
|
timesheet.save()
|
||||||
|
|
||||||
|
def update_loans(self):
|
||||||
|
for loan in self.get_loan_details():
|
||||||
|
doc = frappe.get_doc("Loan", loan.name)
|
||||||
|
|
||||||
|
#setting repayment schedule and updating total amount to pay
|
||||||
|
repayment_status = 1 if doc.docstatus == 1 else 0
|
||||||
|
frappe.db.set_value("Repayment Schedule", loan.repayment_name, "paid", repayment_status)
|
||||||
|
doc.reload()
|
||||||
|
doc.update_total_amount_paid()
|
||||||
|
doc.set_status()
|
||||||
|
|
||||||
def set_status(self, status=None):
|
def set_status(self, status=None):
|
||||||
'''Get and update status'''
|
'''Get and update status'''
|
||||||
if not status:
|
if not status:
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,524 +1,170 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"actions": [],
|
||||||
"allow_guest_to_view": 0,
|
"allow_import": 1,
|
||||||
"allow_import": 1,
|
"autoname": "HR-SSA-.YY.-.MM.-.#####",
|
||||||
"allow_rename": 0,
|
"creation": "2018-04-13 16:38:41.769237",
|
||||||
"autoname": "HR-SSA-.YY.-.MM.-.#####",
|
"doctype": "DocType",
|
||||||
"beta": 0,
|
"editable_grid": 1,
|
||||||
"creation": "2018-04-13 16:38:41.769237",
|
"engine": "InnoDB",
|
||||||
"custom": 0,
|
"field_order": [
|
||||||
"docstatus": 0,
|
"employee",
|
||||||
"doctype": "DocType",
|
"employee_name",
|
||||||
"document_type": "",
|
"department",
|
||||||
"editable_grid": 1,
|
"designation",
|
||||||
"engine": "InnoDB",
|
"column_break_6",
|
||||||
|
"salary_structure",
|
||||||
|
"from_date",
|
||||||
|
"company",
|
||||||
|
"section_break_7",
|
||||||
|
"base",
|
||||||
|
"column_break_9",
|
||||||
|
"variable",
|
||||||
|
"amended_from"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "employee",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Link",
|
||||||
"allow_on_submit": 0,
|
"in_list_view": 1,
|
||||||
"bold": 0,
|
"in_standard_filter": 1,
|
||||||
"collapsible": 0,
|
"label": "Employee",
|
||||||
"columns": 0,
|
"options": "Employee",
|
||||||
"fieldname": "employee",
|
"reqd": 1,
|
||||||
"fieldtype": "Link",
|
"search_index": 1
|
||||||
"hidden": 0,
|
},
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 1,
|
|
||||||
"label": "Employee",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Employee",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 1,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fetch_from": "employee.employee_name",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "employee_name",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Data",
|
||||||
"bold": 0,
|
"label": "Employee Name",
|
||||||
"collapsible": 0,
|
"read_only": 1
|
||||||
"columns": 0,
|
},
|
||||||
"fetch_from": "employee.employee_name",
|
|
||||||
"fieldname": "employee_name",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"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": "Employee Name",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"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,
|
"fetch_from": "employee.department",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "department",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Link",
|
||||||
"bold": 0,
|
"in_standard_filter": 1,
|
||||||
"collapsible": 0,
|
"label": "Department",
|
||||||
"columns": 0,
|
"options": "Department",
|
||||||
"fetch_from": "employee.department",
|
"read_only": 1
|
||||||
"fieldname": "department",
|
},
|
||||||
"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": 1,
|
|
||||||
"label": "Department",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Department",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"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,
|
"fetch_from": "employee.designation",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "designation",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Link",
|
||||||
"bold": 0,
|
"in_standard_filter": 1,
|
||||||
"collapsible": 0,
|
"label": "Designation",
|
||||||
"columns": 0,
|
"options": "Designation",
|
||||||
"fetch_from": "employee.designation",
|
"read_only": 1
|
||||||
"fieldname": "designation",
|
},
|
||||||
"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": 1,
|
|
||||||
"label": "Designation",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Designation",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"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_6",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Column Break"
|
||||||
"allow_on_submit": 0,
|
},
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_6",
|
|
||||||
"fieldtype": "Column Break",
|
|
||||||
"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,
|
"fieldname": "salary_structure",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Link",
|
||||||
"allow_on_submit": 0,
|
"in_list_view": 1,
|
||||||
"bold": 0,
|
"in_standard_filter": 1,
|
||||||
"collapsible": 0,
|
"label": "Salary Structure",
|
||||||
"columns": 0,
|
"options": "Salary Structure",
|
||||||
"fieldname": "salary_structure",
|
"reqd": 1,
|
||||||
"fieldtype": "Link",
|
"search_index": 1
|
||||||
"hidden": 0,
|
},
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 1,
|
|
||||||
"label": "Salary Structure",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Salary Structure",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 1,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "from_date",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Date",
|
||||||
"allow_on_submit": 0,
|
"label": "From Date",
|
||||||
"bold": 0,
|
"reqd": 1
|
||||||
"collapsible": 0,
|
},
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "from_date",
|
|
||||||
"fieldtype": "Date",
|
|
||||||
"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": "From Date",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "company",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Link",
|
||||||
"allow_on_submit": 0,
|
"label": "Company",
|
||||||
"bold": 0,
|
"options": "Company",
|
||||||
"collapsible": 0,
|
"read_only": 1,
|
||||||
"columns": 0,
|
"reqd": 1
|
||||||
"fieldname": "company",
|
},
|
||||||
"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": "Company",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Company",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"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": "section_break_7",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Section Break"
|
||||||
"allow_on_submit": 0,
|
},
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "section_break_7",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"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,
|
"fieldname": "base",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Currency",
|
||||||
"allow_on_submit": 0,
|
"label": "Base",
|
||||||
"bold": 0,
|
"options": "Company:company:default_currency"
|
||||||
"collapsible": 0,
|
},
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "base",
|
|
||||||
"fieldtype": "Currency",
|
|
||||||
"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": "Base",
|
|
||||||
"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,
|
"fieldname": "column_break_9",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Column Break"
|
||||||
"allow_on_submit": 0,
|
},
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_9",
|
|
||||||
"fieldtype": "Column Break",
|
|
||||||
"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,
|
"fieldname": "variable",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Currency",
|
||||||
"allow_on_submit": 0,
|
"label": "Variable",
|
||||||
"bold": 0,
|
"options": "Company:company:default_currency"
|
||||||
"collapsible": 0,
|
},
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "variable",
|
|
||||||
"fieldtype": "Currency",
|
|
||||||
"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": "Variable",
|
|
||||||
"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,
|
"fieldname": "amended_from",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Link",
|
||||||
"allow_on_submit": 0,
|
"label": "Amended From",
|
||||||
"bold": 0,
|
"no_copy": 1,
|
||||||
"collapsible": 0,
|
"options": "Salary Structure Assignment",
|
||||||
"columns": 0,
|
"print_hide": 1,
|
||||||
"fieldname": "amended_from",
|
"read_only": 1
|
||||||
"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": "Amended From",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
|
||||||
"options": "Salary Structure Assignment",
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 1,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"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,
|
"is_submittable": 1,
|
||||||
"hide_heading": 0,
|
"links": [],
|
||||||
"hide_toolbar": 0,
|
"modified": "2019-12-31 17:05:28.637510",
|
||||||
"idx": 0,
|
"modified_by": "Administrator",
|
||||||
"image_view": 0,
|
"module": "HR",
|
||||||
"in_create": 0,
|
"name": "Salary Structure Assignment",
|
||||||
"is_submittable": 1,
|
"owner": "Administrator",
|
||||||
"issingle": 0,
|
|
||||||
"istable": 0,
|
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2018-08-21 16:15:48.755450",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "HR",
|
|
||||||
"name": "Salary Structure Assignment",
|
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"create": 1,
|
||||||
"cancel": 0,
|
"delete": 1,
|
||||||
"create": 1,
|
"email": 1,
|
||||||
"delete": 1,
|
"export": 1,
|
||||||
"email": 1,
|
"print": 1,
|
||||||
"export": 1,
|
"read": 1,
|
||||||
"if_owner": 0,
|
"report": 1,
|
||||||
"import": 0,
|
"role": "System Manager",
|
||||||
"permlevel": 0,
|
"share": 1,
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "System Manager",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 1,
|
"amend": 1,
|
||||||
"cancel": 1,
|
"cancel": 1,
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 1,
|
"export": 1,
|
||||||
"if_owner": 0,
|
"print": 1,
|
||||||
"import": 0,
|
"read": 1,
|
||||||
"permlevel": 0,
|
"report": 1,
|
||||||
"print": 1,
|
"role": "HR Manager",
|
||||||
"read": 1,
|
"share": 1,
|
||||||
"report": 1,
|
"submit": 1,
|
||||||
"role": "HR Manager",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 1,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"create": 1,
|
||||||
"cancel": 0,
|
"email": 1,
|
||||||
"create": 1,
|
"export": 1,
|
||||||
"delete": 0,
|
"print": 1,
|
||||||
"email": 1,
|
"read": 1,
|
||||||
"export": 1,
|
"report": 1,
|
||||||
"if_owner": 0,
|
"role": "HR User",
|
||||||
"import": 0,
|
"share": 1,
|
||||||
"permlevel": 0,
|
"submit": 1,
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "HR User",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 1,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 0,
|
"sort_field": "modified",
|
||||||
"read_only": 0,
|
"sort_order": "DESC",
|
||||||
"read_only_onload": 0,
|
"title_field": "employee_name",
|
||||||
"show_name_in_global_search": 0,
|
"track_changes": 1
|
||||||
"sort_field": "modified",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"title_field": "employee_name",
|
|
||||||
"track_changes": 1,
|
|
||||||
"track_seen": 0,
|
|
||||||
"track_views": 0
|
|
||||||
}
|
}
|
||||||
@@ -633,7 +633,7 @@ def get_bom_items_as_dict(bom, company, qty=1, fetch_exploded=1, fetch_scrap_ite
|
|||||||
is_stock_item=is_stock_item,
|
is_stock_item=is_stock_item,
|
||||||
qty_field="stock_qty",
|
qty_field="stock_qty",
|
||||||
select_columns = """, bom_item.source_warehouse, bom_item.operation,
|
select_columns = """, bom_item.source_warehouse, bom_item.operation,
|
||||||
bom_item.include_item_in_manufacturing, bom_item.description,
|
bom_item.include_item_in_manufacturing, bom_item.description, bom_item.rate,
|
||||||
(Select idx from `tabBOM Item` where item_code = bom_item.item_code and parent = %(parent)s limit 1) as idx""")
|
(Select idx from `tabBOM Item` where item_code = bom_item.item_code and parent = %(parent)s limit 1) as idx""")
|
||||||
|
|
||||||
items = frappe.db.sql(query, { "parent": bom, "qty": qty, "bom": bom, "company": company }, as_dict=True)
|
items = frappe.db.sql(query, { "parent": bom, "qty": qty, "bom": bom, "company": company }, as_dict=True)
|
||||||
@@ -647,7 +647,7 @@ def get_bom_items_as_dict(bom, company, qty=1, fetch_exploded=1, fetch_scrap_ite
|
|||||||
qty_field="stock_qty" if fetch_qty_in_stock_uom else "qty",
|
qty_field="stock_qty" if fetch_qty_in_stock_uom else "qty",
|
||||||
select_columns = """, bom_item.uom, bom_item.conversion_factor, bom_item.source_warehouse,
|
select_columns = """, bom_item.uom, bom_item.conversion_factor, bom_item.source_warehouse,
|
||||||
bom_item.idx, bom_item.operation, bom_item.include_item_in_manufacturing,
|
bom_item.idx, bom_item.operation, bom_item.include_item_in_manufacturing,
|
||||||
bom_item.description """)
|
bom_item.description, bom_item.base_rate as rate """)
|
||||||
items = frappe.db.sql(query, { "qty": qty, "bom": bom, "company": company }, as_dict=True)
|
items = frappe.db.sql(query, { "qty": qty, "bom": bom, "company": company }, as_dict=True)
|
||||||
|
|
||||||
for item in items:
|
for item in items:
|
||||||
@@ -760,23 +760,53 @@ def get_boms_in_bottom_up_order(bom_no=None):
|
|||||||
|
|
||||||
def add_additional_cost(stock_entry, work_order):
|
def add_additional_cost(stock_entry, work_order):
|
||||||
# Add non stock items cost in the additional cost
|
# Add non stock items cost in the additional cost
|
||||||
bom = frappe.get_doc('BOM', work_order.bom_no)
|
stock_entry.additional_costs = []
|
||||||
table = 'exploded_items' if work_order.get('use_multi_level_bom') else 'items'
|
|
||||||
expenses_included_in_valuation = frappe.get_cached_value("Company", work_order.company,
|
expenses_included_in_valuation = frappe.get_cached_value("Company", work_order.company,
|
||||||
"expenses_included_in_valuation")
|
"expenses_included_in_valuation")
|
||||||
|
|
||||||
|
add_non_stock_items_cost(stock_entry, work_order, expenses_included_in_valuation)
|
||||||
|
add_operations_cost(stock_entry, work_order, expenses_included_in_valuation)
|
||||||
|
|
||||||
|
def add_non_stock_items_cost(stock_entry, work_order, expense_account):
|
||||||
|
bom = frappe.get_doc('BOM', work_order.bom_no)
|
||||||
|
table = 'exploded_items' if work_order.get('use_multi_level_bom') else 'items'
|
||||||
|
|
||||||
items = {}
|
items = {}
|
||||||
for d in bom.get(table):
|
for d in bom.get(table):
|
||||||
items.setdefault(d.item_code, d.rate)
|
items.setdefault(d.item_code, d.amount)
|
||||||
|
|
||||||
non_stock_items = frappe.get_all('Item',
|
non_stock_items = frappe.get_all('Item',
|
||||||
fields="name", filters={'name': ('in', list(items.keys())), 'ifnull(is_stock_item, 0)': 0}, as_list=1)
|
fields="name", filters={'name': ('in', list(items.keys())), 'ifnull(is_stock_item, 0)': 0}, as_list=1)
|
||||||
|
|
||||||
|
non_stock_items_cost = 0.0
|
||||||
for name in non_stock_items:
|
for name in non_stock_items:
|
||||||
|
non_stock_items_cost += flt(items.get(name[0])) * flt(stock_entry.fg_completed_qty) / flt(bom.quantity)
|
||||||
|
|
||||||
|
stock_entry.append('additional_costs', {
|
||||||
|
'expense_account': expense_account,
|
||||||
|
'description': _("Non stock items"),
|
||||||
|
'amount': non_stock_items_cost
|
||||||
|
})
|
||||||
|
|
||||||
|
def add_operations_cost(stock_entry, work_order=None, expense_account=None):
|
||||||
|
from erpnext.stock.doctype.stock_entry.stock_entry import get_operating_cost_per_unit
|
||||||
|
operating_cost_per_unit = get_operating_cost_per_unit(work_order, stock_entry.bom_no)
|
||||||
|
|
||||||
|
if operating_cost_per_unit:
|
||||||
stock_entry.append('additional_costs', {
|
stock_entry.append('additional_costs', {
|
||||||
'expense_account': expenses_included_in_valuation,
|
"expense_account": expense_account,
|
||||||
'description': name[0],
|
"description": _("Operating Cost as per Work Order / BOM"),
|
||||||
'amount': items.get(name[0])
|
"amount": operating_cost_per_unit * flt(stock_entry.fg_completed_qty)
|
||||||
|
})
|
||||||
|
|
||||||
|
if work_order and work_order.additional_operating_cost and work_order.qty:
|
||||||
|
additional_operating_cost_per_unit = \
|
||||||
|
flt(work_order.additional_operating_cost) / flt(work_order.qty)
|
||||||
|
|
||||||
|
stock_entry.append('additional_costs', {
|
||||||
|
"expense_account": expense_account,
|
||||||
|
"description": "Additional Operating Cost",
|
||||||
|
"amount": additional_operating_cost_per_unit * flt(stock_entry.fg_completed_qty)
|
||||||
})
|
})
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
|
|||||||
@@ -3,6 +3,11 @@
|
|||||||
|
|
||||||
frappe.ui.form.on('Job Card', {
|
frappe.ui.form.on('Job Card', {
|
||||||
refresh: function(frm) {
|
refresh: function(frm) {
|
||||||
|
|
||||||
|
if(frm.doc.docstatus == 0) {
|
||||||
|
frm.set_df_property("operation", "read_only", frm.doc.operation_id ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
if(!frm.doc.__islocal && frm.doc.items && frm.doc.items.length) {
|
if(!frm.doc.__islocal && frm.doc.items && frm.doc.items.length) {
|
||||||
if (frm.doc.for_quantity != frm.doc.transferred_qty) {
|
if (frm.doc.for_quantity != frm.doc.transferred_qty) {
|
||||||
frm.add_custom_button(__("Material Request"), () => {
|
frm.add_custom_button(__("Material Request"), () => {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ frappe.ui.form.on("Work Order", {
|
|||||||
frm.custom_make_buttons = {
|
frm.custom_make_buttons = {
|
||||||
'Stock Entry': 'Start',
|
'Stock Entry': 'Start',
|
||||||
'Pick List': 'Create Pick List',
|
'Pick List': 'Create Pick List',
|
||||||
|
'Job Card': 'Create Job Card',
|
||||||
};
|
};
|
||||||
|
|
||||||
// Set query for warehouses
|
// Set query for warehouses
|
||||||
@@ -136,7 +137,7 @@ frappe.ui.form.on("Work Order", {
|
|||||||
|
|
||||||
if (frm.doc.docstatus === 1
|
if (frm.doc.docstatus === 1
|
||||||
&& frm.doc.operations && frm.doc.operations.length
|
&& frm.doc.operations && frm.doc.operations.length
|
||||||
&& frm.doc.qty != frm.doc.material_transferred_for_manufacturing) {
|
&& frm.doc.qty != frm.doc.produced_qty) {
|
||||||
|
|
||||||
const not_completed = frm.doc.operations.filter(d => {
|
const not_completed = frm.doc.operations.filter(d => {
|
||||||
if(d.status != 'Completed') {
|
if(d.status != 'Completed') {
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ from dateutil.relativedelta import relativedelta
|
|||||||
from erpnext.stock.doctype.item.item import validate_end_of_life
|
from erpnext.stock.doctype.item.item import validate_end_of_life
|
||||||
from erpnext.manufacturing.doctype.workstation.workstation import WorkstationHolidayError
|
from erpnext.manufacturing.doctype.workstation.workstation import WorkstationHolidayError
|
||||||
from erpnext.projects.doctype.timesheet.timesheet import OverlapError
|
from erpnext.projects.doctype.timesheet.timesheet import OverlapError
|
||||||
from erpnext.stock.doctype.stock_entry.stock_entry import get_additional_costs
|
|
||||||
from erpnext.manufacturing.doctype.manufacturing_settings.manufacturing_settings import get_mins_between_operations
|
from erpnext.manufacturing.doctype.manufacturing_settings.manufacturing_settings import get_mins_between_operations
|
||||||
from erpnext.stock.stock_balance import get_planned_qty, update_bin_qty
|
from erpnext.stock.stock_balance import get_planned_qty, update_bin_qty
|
||||||
from frappe.utils.csvutils import getlink
|
from frappe.utils.csvutils import getlink
|
||||||
@@ -671,10 +670,6 @@ def make_stock_entry(work_order_id, purpose, qty=None):
|
|||||||
stock_entry.from_warehouse = wip_warehouse
|
stock_entry.from_warehouse = wip_warehouse
|
||||||
stock_entry.to_warehouse = work_order.fg_warehouse
|
stock_entry.to_warehouse = work_order.fg_warehouse
|
||||||
stock_entry.project = work_order.project
|
stock_entry.project = work_order.project
|
||||||
if purpose=="Manufacture":
|
|
||||||
additional_costs = get_additional_costs(work_order, fg_qty=stock_entry.fg_completed_qty,
|
|
||||||
company=work_order.company)
|
|
||||||
stock_entry.set("additional_costs", additional_costs)
|
|
||||||
|
|
||||||
stock_entry.set_stock_entry_type()
|
stock_entry.set_stock_entry_type()
|
||||||
stock_entry.get_items()
|
stock_entry.get_items()
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ erpnext.patches.v4_0.apply_user_permissions
|
|||||||
erpnext.patches.v4_0.move_warehouse_user_to_restrictions
|
erpnext.patches.v4_0.move_warehouse_user_to_restrictions
|
||||||
erpnext.patches.v4_0.global_defaults_to_system_settings
|
erpnext.patches.v4_0.global_defaults_to_system_settings
|
||||||
erpnext.patches.v4_0.update_incharge_name_to_sales_person_in_maintenance_schedule
|
erpnext.patches.v4_0.update_incharge_name_to_sales_person_in_maintenance_schedule
|
||||||
|
execute:frappe.reload_doc("HR", "doctype", "HR Settings") #2020-01-16
|
||||||
execute:frappe.reload_doc('stock', 'doctype', 'warehouse') # 2017-04-24
|
execute:frappe.reload_doc('stock', 'doctype', 'warehouse') # 2017-04-24
|
||||||
execute:frappe.reload_doc('accounts', 'doctype', 'sales_invoice') # 2016-08-31
|
execute:frappe.reload_doc('accounts', 'doctype', 'sales_invoice') # 2016-08-31
|
||||||
execute:frappe.reload_doc('selling', 'doctype', 'sales_order') # 2014-01-29
|
execute:frappe.reload_doc('selling', 'doctype', 'sales_order') # 2014-01-29
|
||||||
@@ -513,7 +514,6 @@ erpnext.patches.v11_0.rename_employee_loan_to_loan
|
|||||||
erpnext.patches.v11_0.move_leave_approvers_from_employee #13-06-2018
|
erpnext.patches.v11_0.move_leave_approvers_from_employee #13-06-2018
|
||||||
erpnext.patches.v11_0.update_department_lft_rgt
|
erpnext.patches.v11_0.update_department_lft_rgt
|
||||||
erpnext.patches.v11_0.add_default_email_template_for_leave
|
erpnext.patches.v11_0.add_default_email_template_for_leave
|
||||||
execute:frappe.reload_doc("HR", "doctype", "HR Settings")
|
|
||||||
erpnext.patches.v11_0.set_default_email_template_in_hr #08-06-2018
|
erpnext.patches.v11_0.set_default_email_template_in_hr #08-06-2018
|
||||||
erpnext.patches.v11_0.uom_conversion_data #30-06-2018
|
erpnext.patches.v11_0.uom_conversion_data #30-06-2018
|
||||||
erpnext.patches.v10_0.taxes_issue_with_pos
|
erpnext.patches.v10_0.taxes_issue_with_pos
|
||||||
@@ -586,6 +586,7 @@ erpnext.patches.v11_0.add_permissions_in_gst_settings
|
|||||||
erpnext.patches.v11_1.setup_guardian_role
|
erpnext.patches.v11_1.setup_guardian_role
|
||||||
execute:frappe.delete_doc('DocType', 'Notification Control')
|
execute:frappe.delete_doc('DocType', 'Notification Control')
|
||||||
erpnext.patches.v12_0.set_gst_category
|
erpnext.patches.v12_0.set_gst_category
|
||||||
|
erpnext.patches.v12_0.update_gst_category
|
||||||
erpnext.patches.v11_0.remove_barcodes_field_from_copy_fields_to_variants
|
erpnext.patches.v11_0.remove_barcodes_field_from_copy_fields_to_variants
|
||||||
erpnext.patches.v12_0.set_task_status
|
erpnext.patches.v12_0.set_task_status
|
||||||
erpnext.patches.v11_0.make_italian_localization_fields # 26-03-2019
|
erpnext.patches.v11_0.make_italian_localization_fields # 26-03-2019
|
||||||
@@ -644,7 +645,6 @@ erpnext.patches.v12_0.set_expense_account_in_landed_cost_voucher_taxes
|
|||||||
erpnext.patches.v12_0.replace_accounting_with_accounts_in_home_settings
|
erpnext.patches.v12_0.replace_accounting_with_accounts_in_home_settings
|
||||||
erpnext.patches.v12_0.set_payment_entry_status
|
erpnext.patches.v12_0.set_payment_entry_status
|
||||||
erpnext.patches.v12_0.update_owner_fields_in_acc_dimension_custom_fields
|
erpnext.patches.v12_0.update_owner_fields_in_acc_dimension_custom_fields
|
||||||
erpnext.patches.v12_0.set_default_for_add_taxes_from_item_tax_template
|
|
||||||
erpnext.patches.v12_0.remove_denied_leaves_from_leave_ledger
|
erpnext.patches.v12_0.remove_denied_leaves_from_leave_ledger
|
||||||
erpnext.patches.v12_0.update_price_or_product_discount
|
erpnext.patches.v12_0.update_price_or_product_discount
|
||||||
erpnext.patches.v12_0.add_export_type_field_in_party_master
|
erpnext.patches.v12_0.add_export_type_field_in_party_master
|
||||||
|
|||||||
@@ -49,21 +49,22 @@ def execute():
|
|||||||
item_tax_template_name = get_item_tax_template(item_tax_templates, item_tax_map, item_code)
|
item_tax_template_name = get_item_tax_template(item_tax_templates, item_tax_map, item_code)
|
||||||
|
|
||||||
# update the item tax table
|
# update the item tax table
|
||||||
item = frappe.get_doc("Item", item_code)
|
|
||||||
item.set("taxes", [])
|
|
||||||
item.append("taxes", {"item_tax_template": item_tax_template_name, "tax_category": ""})
|
|
||||||
frappe.db.sql("delete from `tabItem Tax` where parent=%s and parenttype='Item'", item_code)
|
frappe.db.sql("delete from `tabItem Tax` where parent=%s and parenttype='Item'", item_code)
|
||||||
for d in item.taxes:
|
if item_tax_template_name:
|
||||||
d.db_insert()
|
item = frappe.get_doc("Item", item_code)
|
||||||
|
item.set("taxes", [])
|
||||||
|
item.append("taxes", {"item_tax_template": item_tax_template_name, "tax_category": ""})
|
||||||
|
for d in item.taxes:
|
||||||
|
d.db_insert()
|
||||||
|
|
||||||
doctypes = [
|
doctypes = [
|
||||||
'Quotation', 'Sales Order', 'Delivery Note', 'Sales Invoice',
|
'Quotation', 'Sales Order', 'Delivery Note', 'Sales Invoice',
|
||||||
'Supplier Quotation', 'Purchase Order', 'Purchase Receipt', 'Purchase Invoice'
|
'Supplier Quotation', 'Purchase Order', 'Purchase Receipt', 'Purchase Invoice'
|
||||||
]
|
]
|
||||||
|
|
||||||
for dt in doctypes:
|
for dt in doctypes:
|
||||||
for d in frappe.db.sql("""select name, parenttype, parent, item_code, item_tax_rate from `tab{0} Item`
|
for d in frappe.db.sql("""select name, parenttype, parent, item_code, item_tax_rate from `tab{0} Item`
|
||||||
where ifnull(item_tax_rate, '') not in ('', '{{}}')
|
where ifnull(item_tax_rate, '') not in ('', '{{}}')
|
||||||
and item_tax_template is NULL""".format(dt), as_dict=1):
|
and item_tax_template is NULL""".format(dt), as_dict=1):
|
||||||
item_tax_map = json.loads(d.item_tax_rate)
|
item_tax_map = json.loads(d.item_tax_rate)
|
||||||
item_tax_template_name = get_item_tax_template(item_tax_templates,
|
item_tax_template_name = get_item_tax_template(item_tax_templates,
|
||||||
@@ -95,27 +96,35 @@ def get_item_tax_template(item_tax_templates, item_tax_map, item_code, parenttyp
|
|||||||
else:
|
else:
|
||||||
parts = tax_type.strip().split(" - ")
|
parts = tax_type.strip().split(" - ")
|
||||||
account_name = " - ".join(parts[:-1])
|
account_name = " - ".join(parts[:-1])
|
||||||
company = get_company(parts[-1], parenttype, parent)
|
if not account_name:
|
||||||
parent_account = frappe.db.get_value("Account",
|
tax_type = None
|
||||||
filters={"account_type": "Tax", "root_type": "Liability", "is_group": 0, "company": company}, fieldname="parent_account")
|
else:
|
||||||
filters = {
|
company = get_company(parts[-1], parenttype, parent)
|
||||||
"account_name": account_name,
|
parent_account = frappe.db.get_value("Account",
|
||||||
"company": company,
|
filters={"account_type": "Tax", "root_type": "Liability", "is_group": 0, "company": company}, fieldname="parent_account")
|
||||||
"account_type": "Tax",
|
if not parent_account:
|
||||||
"parent_account": parent_account
|
parent_account = frappe.db.get_value("Account",
|
||||||
}
|
filters={"account_type": "Tax", "root_type": "Liability", "is_group": 1, "company": company})
|
||||||
tax_type = frappe.db.get_value("Account", filters)
|
filters = {
|
||||||
if not tax_type:
|
"account_name": account_name,
|
||||||
account = frappe.new_doc("Account")
|
"company": company,
|
||||||
account.update(filters)
|
"account_type": "Tax",
|
||||||
account.insert()
|
"parent_account": parent_account
|
||||||
tax_type = account.name
|
}
|
||||||
|
tax_type = frappe.db.get_value("Account", filters)
|
||||||
|
if not tax_type:
|
||||||
|
account = frappe.new_doc("Account")
|
||||||
|
account.update(filters)
|
||||||
|
account.insert()
|
||||||
|
tax_type = account.name
|
||||||
|
|
||||||
item_tax_template.append("taxes", {"tax_type": tax_type, "tax_rate": tax_rate})
|
if tax_type:
|
||||||
item_tax_templates.setdefault(item_tax_template.title, {})
|
item_tax_template.append("taxes", {"tax_type": tax_type, "tax_rate": tax_rate})
|
||||||
item_tax_templates[item_tax_template.title][tax_type] = tax_rate
|
item_tax_templates.setdefault(item_tax_template.title, {})
|
||||||
item_tax_template.save()
|
item_tax_templates[item_tax_template.title][tax_type] = tax_rate
|
||||||
return item_tax_template.name
|
if item_tax_template.get("taxes"):
|
||||||
|
item_tax_template.save()
|
||||||
|
return item_tax_template.name
|
||||||
|
|
||||||
def get_company(company_abbr, parenttype=None, parent=None):
|
def get_company(company_abbr, parenttype=None, parent=None):
|
||||||
if parenttype and parent:
|
if parenttype and parent:
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
import frappe
|
|
||||||
|
|
||||||
def execute():
|
|
||||||
frappe.db.set_value("Accounts Settings", None, "add_taxes_from_item_tax_template", 1)
|
|
||||||
frappe.db.set_default("add_taxes_from_item_tax_template", 1)
|
|
||||||
19
erpnext/patches/v12_0/update_gst_category.py
Normal file
19
erpnext/patches/v12_0/update_gst_category.py
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
|
||||||
|
company = frappe.get_all('Company', filters = {'country': 'India'})
|
||||||
|
if not company:
|
||||||
|
return
|
||||||
|
|
||||||
|
frappe.db.sql(""" UPDATE `tabSales Invoice` set gst_category = 'Unregistered'
|
||||||
|
where gst_category = 'Registered Regular'
|
||||||
|
and ifnull(customer_gstin, '')=''
|
||||||
|
and ifnull(billing_address_gstin,'')=''
|
||||||
|
""")
|
||||||
|
|
||||||
|
frappe.db.sql(""" UPDATE `tabPurchase Invoice` set gst_category = 'Unregistered'
|
||||||
|
where gst_category = 'Registered Regular'
|
||||||
|
and ifnull(supplier_gstin, '')=''
|
||||||
|
""")
|
||||||
@@ -13,6 +13,8 @@ def execute():
|
|||||||
frappe.reload_doc('hr', 'doctype', 'employee_tax_exemption_declaration_category')
|
frappe.reload_doc('hr', 'doctype', 'employee_tax_exemption_declaration_category')
|
||||||
frappe.reload_doc('hr', 'doctype', 'employee_tax_exemption_proof_submission_detail')
|
frappe.reload_doc('hr', 'doctype', 'employee_tax_exemption_proof_submission_detail')
|
||||||
|
|
||||||
|
frappe.reload_doc('accounts', 'doctype', 'tax_category')
|
||||||
|
|
||||||
for doctype in ["Sales Invoice", "Delivery Note", "Purchase Invoice"]:
|
for doctype in ["Sales Invoice", "Delivery Note", "Purchase Invoice"]:
|
||||||
frappe.db.sql("""delete from `tabCustom Field` where dt = %s
|
frappe.db.sql("""delete from `tabCustom Field` where dt = %s
|
||||||
and fieldname in ('port_code', 'shipping_bill_number', 'shipping_bill_date')""", doctype)
|
and fieldname in ('port_code', 'shipping_bill_number', 'shipping_bill_date')""", doctype)
|
||||||
@@ -29,4 +31,4 @@ def execute():
|
|||||||
update tabAddress
|
update tabAddress
|
||||||
set gst_state_number=concat("0", gst_state_number)
|
set gst_state_number=concat("0", gst_state_number)
|
||||||
where ifnull(gst_state_number, '') != '' and gst_state_number<10
|
where ifnull(gst_state_number, '') != '' and gst_state_number<10
|
||||||
""")
|
""")
|
||||||
|
|||||||
@@ -107,6 +107,12 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({
|
|||||||
filters:{ 'item_code': row.item_code }
|
filters:{ 'item_code': row.item_code }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if(this.frm.fields_dict["items"].grid.get_field('item_code')) {
|
||||||
|
this.frm.set_query("item_tax_template", "items", function(doc, cdt, cdn) {
|
||||||
|
return me.set_query_for_item_tax_template(doc, cdt, cdn)
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh: function(doc) {
|
refresh: function(doc) {
|
||||||
|
|||||||
@@ -388,9 +388,14 @@ erpnext.taxes_and_totals = erpnext.payments.extend({
|
|||||||
var diff = me.frm.doc.total + non_inclusive_tax_amount
|
var diff = me.frm.doc.total + non_inclusive_tax_amount
|
||||||
- flt(last_tax.total, precision("grand_total"));
|
- flt(last_tax.total, precision("grand_total"));
|
||||||
|
|
||||||
|
if(me.discount_amount_applied && me.frm.doc.discount_amount) {
|
||||||
|
diff -= flt(me.frm.doc.discount_amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
diff = flt(diff, precision("rounding_adjustment"));
|
||||||
|
|
||||||
if ( diff && Math.abs(diff) <= (5.0 / Math.pow(10, precision("tax_amount", last_tax))) ) {
|
if ( diff && Math.abs(diff) <= (5.0 / Math.pow(10, precision("tax_amount", last_tax))) ) {
|
||||||
this.frm.doc.rounding_adjustment = flt(flt(this.frm.doc.rounding_adjustment) + diff,
|
me.frm.doc.rounding_adjustment = diff;
|
||||||
precision("rounding_adjustment"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -968,7 +968,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
|
|
||||||
qty: function(doc, cdt, cdn) {
|
qty: function(doc, cdt, cdn) {
|
||||||
let item = frappe.get_doc(cdt, cdn);
|
let item = frappe.get_doc(cdt, cdn);
|
||||||
this.conversion_factor(doc, cdt, cdn, true);
|
this.conversion_factor(doc, cdt, cdn, false);
|
||||||
this.apply_pricing_rule(item, true);
|
this.apply_pricing_rule(item, true);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -1398,7 +1398,8 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
|
|
||||||
remove_pricing_rule: function(item) {
|
remove_pricing_rule: function(item) {
|
||||||
let me = this;
|
let me = this;
|
||||||
const fields = ["discount_percentage", "discount_amount", "pricing_rules"];
|
const fields = ["discount_percentage",
|
||||||
|
"discount_amount", "margin_rate_or_amount", "rate_with_margin"];
|
||||||
|
|
||||||
if(item.remove_free_item) {
|
if(item.remove_free_item) {
|
||||||
var items = [];
|
var items = [];
|
||||||
@@ -1418,6 +1419,12 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
fields.forEach(f => {
|
fields.forEach(f => {
|
||||||
row[f] = 0;
|
row[f] = 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
["pricing_rules", "margin_type"].forEach(field => {
|
||||||
|
if (row[field]) {
|
||||||
|
row[field] = '';
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1693,6 +1700,29 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
set_query_for_item_tax_template: function(doc, cdt, cdn) {
|
||||||
|
|
||||||
|
var item = frappe.get_doc(cdt, cdn);
|
||||||
|
if(!item.item_code) {
|
||||||
|
frappe.throw(__("Please enter Item Code to get item taxes"));
|
||||||
|
} else {
|
||||||
|
|
||||||
|
let filters = {
|
||||||
|
'item_code': item.item_code,
|
||||||
|
'valid_from': doc.transaction_date || doc.bill_date || doc.posting_date,
|
||||||
|
'item_group': item.item_group,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doc.tax_category)
|
||||||
|
filters['tax_category'] = doc.tax_category;
|
||||||
|
|
||||||
|
return {
|
||||||
|
query: "erpnext.controllers.queries.get_tax_template",
|
||||||
|
filters: filters
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
payment_terms_template: function() {
|
payment_terms_template: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
const doc = this.frm.doc;
|
const doc = this.frm.doc;
|
||||||
@@ -1767,14 +1797,28 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
set_reserve_warehouse: function() {
|
||||||
|
this.autofill_warehouse("reserve_warehouse");
|
||||||
|
},
|
||||||
|
|
||||||
set_warehouse: function() {
|
set_warehouse: function() {
|
||||||
|
this.autofill_warehouse("warehouse");
|
||||||
|
},
|
||||||
|
|
||||||
|
autofill_warehouse : function (warehouse_field) {
|
||||||
|
// set warehouse in all child table rows
|
||||||
var me = this;
|
var me = this;
|
||||||
if(this.frm.doc.set_warehouse) {
|
let warehouse = (warehouse_field === "warehouse") ? me.frm.doc.set_warehouse : me.frm.doc.set_reserve_warehouse;
|
||||||
$.each(this.frm.doc.items || [], function(i, item) {
|
let child_table = (warehouse_field === "warehouse") ? me.frm.doc.items : me.frm.doc.supplied_items;
|
||||||
frappe.model.set_value(me.frm.doctype + " Item", item.name, "warehouse", me.frm.doc.set_warehouse);
|
let doctype = (warehouse_field === "warehouse") ? (me.frm.doctype + " Item") : (me.frm.doctype + " Item Supplied");
|
||||||
|
|
||||||
|
if(warehouse) {
|
||||||
|
$.each(child_table || [], function(i, item) {
|
||||||
|
frappe.model.set_value(doctype, item.name, warehouse_field, warehouse);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
coupon_code: function() {
|
coupon_code: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
frappe.run_serially([
|
frappe.run_serially([
|
||||||
|
|||||||
@@ -458,7 +458,8 @@ erpnext.utils.update_child_items = function(opts) {
|
|||||||
fieldname:"item_code",
|
fieldname:"item_code",
|
||||||
options: 'Item',
|
options: 'Item',
|
||||||
in_list_view: 1,
|
in_list_view: 1,
|
||||||
read_only: 1,
|
read_only: 0,
|
||||||
|
disabled: 0,
|
||||||
label: __('Item Code')
|
label: __('Item Code')
|
||||||
}, {
|
}, {
|
||||||
fieldtype:'Float',
|
fieldtype:'Float',
|
||||||
@@ -501,6 +502,7 @@ erpnext.utils.update_child_items = function(opts) {
|
|||||||
frm.doc[opts.child_docname].forEach(d => {
|
frm.doc[opts.child_docname].forEach(d => {
|
||||||
dialog.fields_dict.trans_items.df.data.push({
|
dialog.fields_dict.trans_items.df.data.push({
|
||||||
"docname": d.name,
|
"docname": d.name,
|
||||||
|
"name": d.name,
|
||||||
"item_code": d.item_code,
|
"item_code": d.item_code,
|
||||||
"qty": d.qty,
|
"qty": d.qty,
|
||||||
"rate": d.rate,
|
"rate": d.rate,
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ erpnext.SerialNoBatchSelector = Class.extend({
|
|||||||
this.dialog.set_value('serial_no', d.serial_no);
|
this.dialog.set_value('serial_no', d.serial_no);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d.batch_no) {
|
if (d.has_batch_no && d.batch_no) {
|
||||||
this.frm.doc.items.forEach(data => {
|
this.frm.doc.items.forEach(data => {
|
||||||
if(data.item_code == d.item_code) {
|
if(data.item_code == d.item_code) {
|
||||||
this.dialog.fields_dict.batches.df.data.push({
|
this.dialog.fields_dict.batches.df.data.push({
|
||||||
|
|||||||
@@ -3,6 +3,26 @@
|
|||||||
|
|
||||||
frappe.ui.form.on('GST HSN Code', {
|
frappe.ui.form.on('GST HSN Code', {
|
||||||
refresh: function(frm) {
|
refresh: function(frm) {
|
||||||
|
if(! frm.doc.__islocal && frm.doc.taxes.length){
|
||||||
|
frm.add_custom_button(__('Update Taxes for Items'), function(){
|
||||||
|
frappe.confirm(
|
||||||
|
'Are you sure? It will overwrite taxes for all items with HSN Code <b>'+frm.doc.name+'</b>.',
|
||||||
|
function(){
|
||||||
|
frappe.call({
|
||||||
|
args:{
|
||||||
|
taxes: frm.doc.taxes,
|
||||||
|
hsn_code: frm.doc.name
|
||||||
|
},
|
||||||
|
method: 'erpnext.regional.doctype.gst_hsn_code.gst_hsn_code.update_taxes_in_item_master',
|
||||||
|
callback: function(r) {
|
||||||
|
if(r.message){
|
||||||
|
frappe.show_alert(__('Item taxes updated'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,104 +1,48 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"actions": [],
|
||||||
"allow_guest_to_view": 0,
|
"autoname": "field:hsn_code",
|
||||||
"allow_import": 0,
|
"creation": "2017-06-21 10:48:56.422086",
|
||||||
"allow_rename": 0,
|
"doctype": "DocType",
|
||||||
"autoname": "field:hsn_code",
|
"editable_grid": 1,
|
||||||
"beta": 0,
|
"engine": "InnoDB",
|
||||||
"creation": "2017-06-21 10:48:56.422086",
|
"field_order": [
|
||||||
"custom": 0,
|
"hsn_code",
|
||||||
"docstatus": 0,
|
"description",
|
||||||
"doctype": "DocType",
|
"taxes"
|
||||||
"document_type": "",
|
],
|
||||||
"editable_grid": 1,
|
|
||||||
"engine": "InnoDB",
|
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "hsn_code",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Data",
|
||||||
"bold": 0,
|
"in_list_view": 1,
|
||||||
"collapsible": 0,
|
"label": "HSN Code",
|
||||||
"columns": 0,
|
"reqd": 1,
|
||||||
"fieldname": "hsn_code",
|
"unique": 1
|
||||||
"fieldtype": "Data",
|
},
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "HSN Code",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "description",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Small Text",
|
||||||
"bold": 0,
|
"in_list_view": 1,
|
||||||
"collapsible": 0,
|
"label": "Description"
|
||||||
"columns": 0,
|
},
|
||||||
"fieldname": "description",
|
{
|
||||||
"fieldtype": "Small Text",
|
"fieldname": "taxes",
|
||||||
"hidden": 0,
|
"fieldtype": "Table",
|
||||||
"ignore_user_permissions": 0,
|
"label": "Taxes",
|
||||||
"ignore_xss_filter": 0,
|
"options": "Item Tax"
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Description",
|
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
"links": [],
|
||||||
"hide_heading": 0,
|
"modified": "2019-12-29 11:32:06.849631",
|
||||||
"hide_toolbar": 0,
|
"modified_by": "Administrator",
|
||||||
"idx": 0,
|
"module": "Regional",
|
||||||
"image_view": 0,
|
"name": "GST HSN Code",
|
||||||
"in_create": 0,
|
"owner": "Administrator",
|
||||||
"is_submittable": 0,
|
"permissions": [],
|
||||||
"issingle": 0,
|
"quick_entry": 1,
|
||||||
"istable": 0,
|
"search_fields": "hsn_code, description",
|
||||||
"max_attachments": 0,
|
"sort_field": "modified",
|
||||||
"modified": "2017-09-29 14:38:52.220743",
|
"sort_order": "DESC",
|
||||||
"modified_by": "Administrator",
|
"title_field": "hsn_code",
|
||||||
"module": "Regional",
|
"track_changes": 1
|
||||||
"name": "GST HSN Code",
|
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [],
|
|
||||||
"quick_entry": 1,
|
|
||||||
"read_only": 0,
|
|
||||||
"read_only_onload": 0,
|
|
||||||
"search_fields": "hsn_code, description",
|
|
||||||
"show_name_in_global_search": 0,
|
|
||||||
"sort_field": "modified",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"title_field": "hsn_code",
|
|
||||||
"track_changes": 1,
|
|
||||||
"track_seen": 0
|
|
||||||
}
|
}
|
||||||
@@ -8,3 +8,26 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
class GSTHSNCode(Document):
|
class GSTHSNCode(Document):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def update_taxes_in_item_master(taxes, hsn_code):
|
||||||
|
items = frappe.get_list("Item", filters={
|
||||||
|
'gst_hsn_code': hsn_code
|
||||||
|
})
|
||||||
|
|
||||||
|
taxes = frappe.parse_json(taxes)
|
||||||
|
frappe.enqueue(update_item_document, items=items, taxes=taxes)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
def update_item_document(items, taxes):
|
||||||
|
for item in items:
|
||||||
|
item_to_be_updated=frappe.get_doc("Item", item.name)
|
||||||
|
item_to_be_updated.taxes = []
|
||||||
|
for tax in taxes:
|
||||||
|
tax = frappe._dict(tax)
|
||||||
|
item_to_be_updated.append("taxes", {
|
||||||
|
'item_tax_template': tax.item_tax_template,
|
||||||
|
'tax_category': tax.tax_category,
|
||||||
|
'valid_from': tax.valid_from
|
||||||
|
})
|
||||||
|
item_to_be_updated.save()
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ Provide a report and downloadable CSV according to the German DATEV format.
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import datetime
|
import datetime
|
||||||
import json
|
import json
|
||||||
|
import six
|
||||||
from six import string_types
|
from six import string_types
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
@@ -158,7 +160,7 @@ def get_gl_entries(filters, as_dict):
|
|||||||
where gl.company = %(company)s
|
where gl.company = %(company)s
|
||||||
and DATE(gl.posting_date) >= %(from_date)s
|
and DATE(gl.posting_date) >= %(from_date)s
|
||||||
and DATE(gl.posting_date) <= %(to_date)s
|
and DATE(gl.posting_date) <= %(to_date)s
|
||||||
order by 'Belegdatum', gl.voucher_no""", filters, as_dict=as_dict)
|
order by 'Belegdatum', gl.voucher_no""", filters, as_dict=as_dict, as_utf8=1)
|
||||||
|
|
||||||
return gl_entries
|
return gl_entries
|
||||||
|
|
||||||
@@ -404,7 +406,8 @@ def get_datev_csv(data, filters):
|
|||||||
|
|
||||||
header = ';'.join(header).encode('latin_1')
|
header = ';'.join(header).encode('latin_1')
|
||||||
data = result.to_csv(
|
data = result.to_csv(
|
||||||
sep=b';',
|
# Reason for str(';'): https://github.com/pandas-dev/pandas/issues/6035
|
||||||
|
sep=str(';'),
|
||||||
# European decimal seperator
|
# European decimal seperator
|
||||||
decimal=',',
|
decimal=',',
|
||||||
# Windows "ANSI" encoding
|
# Windows "ANSI" encoding
|
||||||
@@ -412,13 +415,16 @@ def get_datev_csv(data, filters):
|
|||||||
# format date as DDMM
|
# format date as DDMM
|
||||||
date_format='%d%m',
|
date_format='%d%m',
|
||||||
# Windows line terminator
|
# Windows line terminator
|
||||||
line_terminator=b'\r\n',
|
line_terminator='\r\n',
|
||||||
# Do not number rows
|
# Do not number rows
|
||||||
index=False,
|
index=False,
|
||||||
# Use all columns defined above
|
# Use all columns defined above
|
||||||
columns=columns
|
columns=columns
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if not six.PY2:
|
||||||
|
data = data.encode('latin_1')
|
||||||
|
|
||||||
return header + b'\r\n' + data
|
return header + b'\r\n' + data
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"allow_import": 1,
|
"allow_import": 1,
|
||||||
"autoname": "naming_series:",
|
"autoname": "naming_series:",
|
||||||
"creation": "2013-05-24 19:29:08",
|
"creation": "2013-05-24 19:29:08",
|
||||||
@@ -536,7 +537,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "other_charges_calculation",
|
"fieldname": "other_charges_calculation",
|
||||||
"fieldtype": "Text",
|
"fieldtype": "Long Text",
|
||||||
"label": "Taxes and Charges Calculation",
|
"label": "Taxes and Charges Calculation",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"oldfieldtype": "HTML",
|
"oldfieldtype": "HTML",
|
||||||
@@ -927,8 +928,9 @@
|
|||||||
"icon": "fa fa-shopping-cart",
|
"icon": "fa fa-shopping-cart",
|
||||||
"idx": 82,
|
"idx": 82,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
|
"links": [],
|
||||||
"max_attachments": 1,
|
"max_attachments": 1,
|
||||||
"modified": "2019-11-12 13:19:11.895715",
|
"modified": "2019-12-30 19:14:56.630270",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Selling",
|
"module": "Selling",
|
||||||
"name": "Quotation",
|
"name": "Quotation",
|
||||||
|
|||||||
@@ -6,13 +6,14 @@
|
|||||||
frappe.ui.form.on("Sales Order", {
|
frappe.ui.form.on("Sales Order", {
|
||||||
setup: function(frm) {
|
setup: function(frm) {
|
||||||
frm.custom_make_buttons = {
|
frm.custom_make_buttons = {
|
||||||
'Delivery Note': 'Delivery',
|
'Delivery Note': 'Delivery Note',
|
||||||
'Pick List': 'Pick List',
|
'Pick List': 'Pick List',
|
||||||
'Sales Invoice': 'Invoice',
|
'Sales Invoice': 'Invoice',
|
||||||
'Material Request': 'Material Request',
|
'Material Request': 'Material Request',
|
||||||
'Purchase Order': 'Purchase Order',
|
'Purchase Order': 'Purchase Order',
|
||||||
'Project': 'Project',
|
'Project': 'Project',
|
||||||
'Payment Entry': "Payment"
|
'Payment Entry': "Payment",
|
||||||
|
'Work Order': "Work Order"
|
||||||
}
|
}
|
||||||
frm.add_fetch('customer', 'tax_id', 'tax_id');
|
frm.add_fetch('customer', 'tax_id', 'tax_id');
|
||||||
|
|
||||||
@@ -134,7 +135,6 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
|
|||||||
}
|
}
|
||||||
if(doc.status !== 'Closed') {
|
if(doc.status !== 'Closed') {
|
||||||
if(doc.status !== 'On Hold') {
|
if(doc.status !== 'On Hold') {
|
||||||
|
|
||||||
allow_delivery = this.frm.doc.items.some(item => item.delivered_by_supplier === 0 && item.qty > flt(item.delivered_qty))
|
allow_delivery = this.frm.doc.items.some(item => item.delivered_by_supplier === 0 && item.qty > flt(item.delivered_qty))
|
||||||
&& !this.frm.doc.skip_delivery_note
|
&& !this.frm.doc.skip_delivery_note
|
||||||
|
|
||||||
@@ -696,4 +696,4 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$.extend(cur_frm.cscript, new erpnext.selling.SalesOrderController({frm: cur_frm}));
|
$.extend(cur_frm.cscript, new erpnext.selling.SalesOrderController({frm: cur_frm}));
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"allow_import": 1,
|
"allow_import": 1,
|
||||||
"autoname": "naming_series:",
|
"autoname": "naming_series:",
|
||||||
"creation": "2013-06-18 12:39:59",
|
"creation": "2013-06-18 12:39:59",
|
||||||
@@ -619,7 +620,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "other_charges_calculation",
|
"fieldname": "other_charges_calculation",
|
||||||
"fieldtype": "Text",
|
"fieldtype": "Long Text",
|
||||||
"label": "Taxes and Charges Calculation",
|
"label": "Taxes and Charges Calculation",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"oldfieldtype": "HTML",
|
"oldfieldtype": "HTML",
|
||||||
@@ -1194,7 +1195,8 @@
|
|||||||
"icon": "fa fa-file-text",
|
"icon": "fa fa-file-text",
|
||||||
"idx": 105,
|
"idx": 105,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"modified": "2019-10-23 14:26:42.767189",
|
"links": [],
|
||||||
|
"modified": "2019-12-30 19:15:28.605085",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Selling",
|
"module": "Selling",
|
||||||
"name": "Sales Order",
|
"name": "Sales Order",
|
||||||
|
|||||||
@@ -380,6 +380,9 @@ class SalesOrder(SellingController):
|
|||||||
def get_work_order_items(self, for_raw_material_request=0):
|
def get_work_order_items(self, for_raw_material_request=0):
|
||||||
'''Returns items with BOM that already do not have a linked work order'''
|
'''Returns items with BOM that already do not have a linked work order'''
|
||||||
items = []
|
items = []
|
||||||
|
item_codes = [i.item_code for i in self.items]
|
||||||
|
product_bundle_parents = [pb.new_item_code for pb in frappe.get_all("Product Bundle", {"new_item_code": ["in", item_codes]}, ["new_item_code"])]
|
||||||
|
|
||||||
for table in [self.items, self.packed_items]:
|
for table in [self.items, self.packed_items]:
|
||||||
for i in table:
|
for i in table:
|
||||||
bom = get_default_bom_item(i.item_code)
|
bom = get_default_bom_item(i.item_code)
|
||||||
@@ -391,7 +394,7 @@ class SalesOrder(SellingController):
|
|||||||
else:
|
else:
|
||||||
pending_qty = stock_qty
|
pending_qty = stock_qty
|
||||||
|
|
||||||
if pending_qty:
|
if pending_qty and i.item_code not in product_bundle_parents:
|
||||||
if bom:
|
if bom:
|
||||||
items.append(dict(
|
items.append(dict(
|
||||||
name= i.name,
|
name= i.name,
|
||||||
@@ -420,7 +423,7 @@ class SalesOrder(SellingController):
|
|||||||
|
|
||||||
def _get_delivery_date(ref_doc_delivery_date, red_doc_transaction_date, transaction_date):
|
def _get_delivery_date(ref_doc_delivery_date, red_doc_transaction_date, transaction_date):
|
||||||
delivery_date = get_next_schedule_date(ref_doc_delivery_date,
|
delivery_date = get_next_schedule_date(ref_doc_delivery_date,
|
||||||
auto_repeat_doc.frequency, cint(auto_repeat_doc.repeat_on_day))
|
auto_repeat_doc.frequency, auto_repeat_doc.start_date, cint(auto_repeat_doc.repeat_on_day))
|
||||||
|
|
||||||
if delivery_date <= transaction_date:
|
if delivery_date <= transaction_date:
|
||||||
delivery_date_diff = frappe.utils.date_diff(ref_doc_delivery_date, red_doc_transaction_date)
|
delivery_date_diff = frappe.utils.date_diff(ref_doc_delivery_date, red_doc_transaction_date)
|
||||||
|
|||||||
@@ -320,7 +320,12 @@ class TestSalesOrder(unittest.TestCase):
|
|||||||
create_dn_against_so(so.name, 4)
|
create_dn_against_so(so.name, 4)
|
||||||
make_sales_invoice(so.name)
|
make_sales_invoice(so.name)
|
||||||
|
|
||||||
trans_item = json.dumps([{'item_code' : '_Test Item 2', 'rate' : 200, 'qty' : 7}])
|
first_item_of_so = so.get("items")[0]
|
||||||
|
trans_item = json.dumps([
|
||||||
|
{'item_code' : first_item_of_so.item_code, 'rate' : first_item_of_so.rate, \
|
||||||
|
'qty' : first_item_of_so.qty, 'docname': first_item_of_so.name},
|
||||||
|
{'item_code' : '_Test Item 2', 'rate' : 200, 'qty' : 7}
|
||||||
|
])
|
||||||
update_child_qty_rate('Sales Order', trans_item, so.name)
|
update_child_qty_rate('Sales Order', trans_item, so.name)
|
||||||
|
|
||||||
so.reload()
|
so.reload()
|
||||||
@@ -329,6 +334,48 @@ class TestSalesOrder(unittest.TestCase):
|
|||||||
self.assertEqual(so.get("items")[-1].qty, 7)
|
self.assertEqual(so.get("items")[-1].qty, 7)
|
||||||
self.assertEqual(so.get("items")[-1].amount, 1400)
|
self.assertEqual(so.get("items")[-1].amount, 1400)
|
||||||
self.assertEqual(so.status, 'To Deliver and Bill')
|
self.assertEqual(so.status, 'To Deliver and Bill')
|
||||||
|
|
||||||
|
def test_remove_item_in_update_child_qty_rate(self):
|
||||||
|
so = make_sales_order(**{
|
||||||
|
"item_list": [{
|
||||||
|
"item_code": '_Test Item',
|
||||||
|
"qty": 5,
|
||||||
|
"rate":1000
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
create_dn_against_so(so.name, 2)
|
||||||
|
make_sales_invoice(so.name)
|
||||||
|
|
||||||
|
# add an item so as to try removing items
|
||||||
|
trans_item = json.dumps([
|
||||||
|
{"item_code": '_Test Item', "qty": 5, "rate":1000, "docname": so.get("items")[0].name},
|
||||||
|
{"item_code": '_Test Item 2', "qty": 2, "rate":500}
|
||||||
|
])
|
||||||
|
update_child_qty_rate('Sales Order', trans_item, so.name)
|
||||||
|
so.reload()
|
||||||
|
self.assertEqual(len(so.get("items")), 2)
|
||||||
|
|
||||||
|
# check if delivered items can be removed
|
||||||
|
trans_item = json.dumps([{
|
||||||
|
"item_code": '_Test Item 2',
|
||||||
|
"qty": 2,
|
||||||
|
"rate":500,
|
||||||
|
"docname": so.get("items")[1].name
|
||||||
|
}])
|
||||||
|
self.assertRaises(frappe.ValidationError, update_child_qty_rate, 'Sales Order', trans_item, so.name)
|
||||||
|
|
||||||
|
#remove last added item
|
||||||
|
trans_item = json.dumps([{
|
||||||
|
"item_code": '_Test Item',
|
||||||
|
"qty": 5,
|
||||||
|
"rate":1000,
|
||||||
|
"docname": so.get("items")[0].name
|
||||||
|
}])
|
||||||
|
update_child_qty_rate('Sales Order', trans_item, so.name)
|
||||||
|
|
||||||
|
so.reload()
|
||||||
|
self.assertEqual(len(so.get("items")), 1)
|
||||||
|
self.assertEqual(so.status, 'To Deliver and Bill')
|
||||||
|
|
||||||
|
|
||||||
def test_update_child_qty_rate(self):
|
def test_update_child_qty_rate(self):
|
||||||
|
|||||||
@@ -84,6 +84,13 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
|
|||||||
return me.set_query_for_batch(doc, cdt, cdn)
|
return me.set_query_for_batch(doc, cdt, cdn)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(this.frm.fields_dict["items"].grid.get_field('item_code')) {
|
||||||
|
this.frm.set_query("item_tax_template", "items", function(doc, cdt, cdn) {
|
||||||
|
return me.set_query_for_item_tax_template(doc, cdt, cdn)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh: function() {
|
refresh: function() {
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ class AuthorizationControl(TransactionBase):
|
|||||||
add_cond = ''
|
add_cond = ''
|
||||||
auth_value = av_dis
|
auth_value = av_dis
|
||||||
|
|
||||||
if val == 1: add_cond += " and system_user = '"+session['user'].replace("'", "\\'")+"'"
|
if val == 1: add_cond += " and system_user = '"+ frappe.db.escape(session['user']) +"'"
|
||||||
elif val == 2: add_cond += " and system_role IN %s" % ("('"+"','".join(frappe.get_roles())+"')")
|
elif val == 2: add_cond += " and system_role IN %s" % ("('"+"','".join(frappe.get_roles())+"')")
|
||||||
else: add_cond += " and ifnull(system_user,'') = '' and ifnull(system_role,'') = ''"
|
else: add_cond += " and ifnull(system_user,'') = '' and ifnull(system_role,'') = ''"
|
||||||
|
|
||||||
@@ -85,7 +85,7 @@ class AuthorizationControl(TransactionBase):
|
|||||||
if doc_obj:
|
if doc_obj:
|
||||||
if doc_obj.doctype == 'Sales Invoice': customer = doc_obj.customer
|
if doc_obj.doctype == 'Sales Invoice': customer = doc_obj.customer
|
||||||
else: customer = doc_obj.customer_name
|
else: customer = doc_obj.customer_name
|
||||||
add_cond = " and master_name = '"+cstr(customer).replace("'", "\\'")+"'"
|
add_cond = " and master_name = '"+ frappe.db.escape(customer) +"'"
|
||||||
if based_on == 'Itemwise Discount':
|
if based_on == 'Itemwise Discount':
|
||||||
if doc_obj:
|
if doc_obj:
|
||||||
for t in doc_obj.get("items"):
|
for t in doc_obj.get("items"):
|
||||||
|
|||||||
@@ -106,7 +106,11 @@ def delete_lead_addresses(company_name):
|
|||||||
frappe.db.sql("""update tabCustomer set lead_name=NULL where lead_name in ({leads})""".format(leads=",".join(leads)))
|
frappe.db.sql("""update tabCustomer set lead_name=NULL where lead_name in ({leads})""".format(leads=",".join(leads)))
|
||||||
|
|
||||||
def delete_communications(doctype, company_name, company_fieldname):
|
def delete_communications(doctype, company_name, company_fieldname):
|
||||||
frappe.db.sql("""
|
|
||||||
DELETE FROM `tabCommunication` WHERE reference_doctype = %s AND
|
refrence_docs = frappe.get_all(doctype, filters={company_fieldname:company_name})
|
||||||
EXISTS (SELECT name FROM `tab{0}` WHERE {1} = %s AND `tabCommunication`.reference_name = name)
|
reference_doctype_names = [r.name for r in refrence_docs]
|
||||||
""".format(doctype, company_fieldname), (doctype, company_name))
|
|
||||||
|
communications = frappe.get_all("Communication", filters={"reference_doctype":doctype,"reference_name":["in",reference_doctype_names]})
|
||||||
|
communication_names = [c.name for c in communications]
|
||||||
|
|
||||||
|
frappe.delete_doc("Communication",communication_names)
|
||||||
|
|||||||
@@ -88,6 +88,56 @@ class TestCompany(unittest.TestCase):
|
|||||||
self.delete_mode_of_payment(template)
|
self.delete_mode_of_payment(template)
|
||||||
frappe.delete_doc("Company", template)
|
frappe.delete_doc("Company", template)
|
||||||
|
|
||||||
|
def test_delete_communication(self):
|
||||||
|
from erpnext.setup.doctype.company.delete_company_transactions import delete_communications
|
||||||
|
company = create_child_company()
|
||||||
|
lead = create_test_lead_in_company(company)
|
||||||
|
communication = create_company_communication("Lead", lead)
|
||||||
|
delete_communications("Lead", "Test Company", "company")
|
||||||
|
self.assertFalse(frappe.db.exists("Communcation", communication))
|
||||||
|
self.assertFalse(frappe.db.exists({"doctype":"Comunication Link", "link_name": communication}))
|
||||||
|
|
||||||
def delete_mode_of_payment(self, company):
|
def delete_mode_of_payment(self, company):
|
||||||
frappe.db.sql(""" delete from `tabMode of Payment Account`
|
frappe.db.sql(""" delete from `tabMode of Payment Account`
|
||||||
where company =%s """, (company))
|
where company =%s """, (company))
|
||||||
|
|
||||||
|
def create_company_communication(doctype, docname):
|
||||||
|
comm = frappe.get_doc({
|
||||||
|
"doctype": "Communication",
|
||||||
|
"communication_type": "Communication",
|
||||||
|
"content": "Deduplication of Links",
|
||||||
|
"communication_medium": "Email",
|
||||||
|
"reference_doctype":doctype,
|
||||||
|
"reference_name":docname
|
||||||
|
})
|
||||||
|
comm.insert()
|
||||||
|
|
||||||
|
def create_child_company():
|
||||||
|
child_company = frappe.db.exists("Company", "Test Company")
|
||||||
|
if not child_company:
|
||||||
|
child_company = frappe.get_doc({
|
||||||
|
"doctype":"Company",
|
||||||
|
"company_name":"Test Company",
|
||||||
|
"abbr":"test_company",
|
||||||
|
"default_currency":"INR"
|
||||||
|
})
|
||||||
|
child_company.insert()
|
||||||
|
else:
|
||||||
|
child_company = frappe.get_doc("Company", child_company)
|
||||||
|
|
||||||
|
return child_company.name
|
||||||
|
|
||||||
|
def create_test_lead_in_company(company):
|
||||||
|
lead = frappe.db.exists("Lead", "Test Lead in new company")
|
||||||
|
if not lead:
|
||||||
|
lead = frappe.get_doc({
|
||||||
|
"doctype": "Lead",
|
||||||
|
"lead_name": "Test Lead in new company",
|
||||||
|
"scompany": company
|
||||||
|
})
|
||||||
|
lead.insert()
|
||||||
|
else:
|
||||||
|
lead = frappe.get_doc("Lead", lead)
|
||||||
|
lead.company = company
|
||||||
|
lead.save()
|
||||||
|
return lead.name
|
||||||
|
|||||||
@@ -226,16 +226,14 @@ def set_batch_nos(doc, warehouse_field, throw=False):
|
|||||||
warehouse = d.get(warehouse_field, None)
|
warehouse = d.get(warehouse_field, None)
|
||||||
if has_batch_no and warehouse and qty > 0:
|
if has_batch_no and warehouse and qty > 0:
|
||||||
if not d.batch_no:
|
if not d.batch_no:
|
||||||
d.batch_no = get_batch_no(d.item_code, warehouse, qty, throw)
|
d.batch_no = get_batch_no(d.item_code, warehouse, qty, throw, d.serial_no)
|
||||||
else:
|
else:
|
||||||
batch_qty = get_batch_qty(batch_no=d.batch_no, warehouse=warehouse)
|
batch_qty = get_batch_qty(batch_no=d.batch_no, warehouse=warehouse)
|
||||||
if flt(batch_qty, d.precision("qty")) < flt(qty, d.precision("qty")):
|
if flt(batch_qty, d.precision("qty")) < flt(qty, d.precision("qty")):
|
||||||
frappe.throw(_("Row #{0}: The batch {1} has only {2} qty. Please select another batch which has {3} qty available or split the row into multiple rows, to deliver/issue from multiple batches").format(d.idx, d.batch_no, batch_qty, qty))
|
frappe.throw(_("Row #{0}: The batch {1} has only {2} qty. Please select another batch which has {3} qty available or split the row into multiple rows, to deliver/issue from multiple batches").format(d.idx, d.batch_no, batch_qty, qty))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_batch_no(item_code, warehouse, qty=1, throw=False):
|
def get_batch_no(item_code, warehouse, qty=1, throw=False, serial_no=None):
|
||||||
"""
|
"""
|
||||||
Get batch number using First Expiring First Out method.
|
Get batch number using First Expiring First Out method.
|
||||||
:param item_code: `item_code` of Item Document
|
:param item_code: `item_code` of Item Document
|
||||||
@@ -245,7 +243,7 @@ def get_batch_no(item_code, warehouse, qty=1, throw=False):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
batch_no = None
|
batch_no = None
|
||||||
batches = get_batches(item_code, warehouse, qty, throw)
|
batches = get_batches(item_code, warehouse, qty, throw, serial_no)
|
||||||
|
|
||||||
for batch in batches:
|
for batch in batches:
|
||||||
if cint(qty) <= cint(batch.qty):
|
if cint(qty) <= cint(batch.qty):
|
||||||
@@ -260,16 +258,31 @@ def get_batch_no(item_code, warehouse, qty=1, throw=False):
|
|||||||
return batch_no
|
return batch_no
|
||||||
|
|
||||||
|
|
||||||
def get_batches(item_code, warehouse, qty=1, throw=False):
|
def get_batches(item_code, warehouse, qty=1, throw=False, serial_no=None):
|
||||||
batches = frappe.db.sql(
|
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
||||||
'select batch_id, sum(actual_qty) as qty from `tabBatch` join `tabStock Ledger Entry` ignore index (item_code, warehouse) '
|
cond = ''
|
||||||
'on (`tabBatch`.batch_id = `tabStock Ledger Entry`.batch_no )'
|
if serial_no:
|
||||||
'where `tabStock Ledger Entry`.item_code = %s and `tabStock Ledger Entry`.warehouse = %s '
|
batch = frappe.get_all("Serial No",
|
||||||
'and (`tabBatch`.expiry_date >= CURDATE() or `tabBatch`.expiry_date IS NULL)'
|
fields = ["distinct batch_no"],
|
||||||
'group by batch_id '
|
filters= {
|
||||||
'order by `tabBatch`.expiry_date ASC, `tabBatch`.creation ASC',
|
"item_code": item_code,
|
||||||
(item_code, warehouse),
|
"warehouse": warehouse,
|
||||||
as_dict=True
|
"name": ("in", get_serial_nos(serial_no))
|
||||||
)
|
}
|
||||||
|
)
|
||||||
|
|
||||||
return batches
|
if batch and len(batch) > 1:
|
||||||
|
return []
|
||||||
|
|
||||||
|
cond = " and `tabBatch`.name = %s" %(frappe.db.escape(batch[0].batch_no))
|
||||||
|
|
||||||
|
return frappe.db.sql("""
|
||||||
|
select batch_id, sum(`tabStock Ledger Entry`.actual_qty) as qty
|
||||||
|
from `tabBatch`
|
||||||
|
join `tabStock Ledger Entry` ignore index (item_code, warehouse)
|
||||||
|
on (`tabBatch`.batch_id = `tabStock Ledger Entry`.batch_no )
|
||||||
|
where `tabStock Ledger Entry`.item_code = %s and `tabStock Ledger Entry`.warehouse = %s
|
||||||
|
and (`tabBatch`.expiry_date >= CURDATE() or `tabBatch`.expiry_date IS NULL) {0}
|
||||||
|
group by batch_id
|
||||||
|
order by `tabBatch`.expiry_date ASC, `tabBatch`.creation ASC
|
||||||
|
""".format(cond), (item_code, warehouse), as_dict=True)
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"allow_import": 1,
|
"allow_import": 1,
|
||||||
"autoname": "naming_series:",
|
"autoname": "naming_series:",
|
||||||
"creation": "2013-05-24 19:29:09",
|
"creation": "2013-05-24 19:29:09",
|
||||||
@@ -682,7 +683,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "other_charges_calculation",
|
"fieldname": "other_charges_calculation",
|
||||||
"fieldtype": "Text",
|
"fieldtype": "Long Text",
|
||||||
"label": "Taxes and Charges Calculation",
|
"label": "Taxes and Charges Calculation",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"oldfieldtype": "HTML",
|
"oldfieldtype": "HTML",
|
||||||
@@ -1238,7 +1239,8 @@
|
|||||||
"icon": "fa fa-truck",
|
"icon": "fa fa-truck",
|
||||||
"idx": 146,
|
"idx": 146,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"modified": "2019-09-27 14:24:20.269682",
|
"links": [],
|
||||||
|
"modified": "2019-12-30 19:17:13.122644",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Delivery Note",
|
"name": "Delivery Note",
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ frappe.ui.form.on("Item", {
|
|||||||
if (!frm.doc.is_fixed_asset) {
|
if (!frm.doc.is_fixed_asset) {
|
||||||
erpnext.item.make_dashboard(frm);
|
erpnext.item.make_dashboard(frm);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frm.doc.is_fixed_asset) {
|
if (frm.doc.is_fixed_asset) {
|
||||||
frm.trigger('is_fixed_asset');
|
frm.trigger('is_fixed_asset');
|
||||||
frm.trigger('auto_create_assets');
|
frm.trigger('auto_create_assets');
|
||||||
@@ -136,6 +136,20 @@ frappe.ui.form.on("Item", {
|
|||||||
frm.toggle_reqd('customer', frm.doc.is_customer_provided_item ? 1:0);
|
frm.toggle_reqd('customer', frm.doc.is_customer_provided_item ? 1:0);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
gst_hsn_code: function(frm) {
|
||||||
|
if(!frm.doc.taxes || !frm.doc.taxes.length) {
|
||||||
|
frappe.db.get_doc("GST HSN Code", frm.doc.gst_hsn_code).then(hsn_doc => {
|
||||||
|
$.each(hsn_doc.taxes || [], function(i, tax) {
|
||||||
|
let a = frappe.model.add_child(frm.doc, 'Item Tax', 'taxes');
|
||||||
|
a.item_tax_template = tax.item_tax_template;
|
||||||
|
a.tax_category = tax.tax_category;
|
||||||
|
a.valid_from = tax.valid_from;
|
||||||
|
frm.refresh_field('taxes');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
is_fixed_asset: function(frm) {
|
is_fixed_asset: function(frm) {
|
||||||
// set serial no to false & toggles its visibility
|
// set serial no to false & toggles its visibility
|
||||||
frm.set_value('has_serial_no', 0);
|
frm.set_value('has_serial_no', 0);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"allow_guest_to_view": 1,
|
"allow_guest_to_view": 1,
|
||||||
"allow_import": 1,
|
"allow_import": 1,
|
||||||
"allow_rename": 1,
|
"allow_rename": 1,
|
||||||
@@ -569,6 +570,7 @@
|
|||||||
{
|
{
|
||||||
"default": "0.00",
|
"default": "0.00",
|
||||||
"depends_on": "is_stock_item",
|
"depends_on": "is_stock_item",
|
||||||
|
"description": "Minimum quantity should be as per Stock UOM",
|
||||||
"fieldname": "min_order_qty",
|
"fieldname": "min_order_qty",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"label": "Minimum Order Qty",
|
"label": "Minimum Order Qty",
|
||||||
@@ -1041,8 +1043,9 @@
|
|||||||
"icon": "fa fa-tag",
|
"icon": "fa fa-tag",
|
||||||
"idx": 2,
|
"idx": 2,
|
||||||
"image_field": "image",
|
"image_field": "image",
|
||||||
|
"links": [],
|
||||||
"max_attachments": 1,
|
"max_attachments": 1,
|
||||||
"modified": "2019-12-13 12:15:56.197246",
|
"modified": "2020-01-02 19:13:59.295963",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Item",
|
"name": "Item",
|
||||||
|
|||||||
@@ -551,7 +551,7 @@ class Item(WebsiteGenerator):
|
|||||||
"""select parent from `tabItem Barcode` where barcode = %s and parent != %s""", (item_barcode.barcode, self.name))
|
"""select parent from `tabItem Barcode` where barcode = %s and parent != %s""", (item_barcode.barcode, self.name))
|
||||||
if duplicate:
|
if duplicate:
|
||||||
frappe.throw(_("Barcode {0} already used in Item {1}").format(
|
frappe.throw(_("Barcode {0} already used in Item {1}").format(
|
||||||
item_barcode.barcode, duplicate[0][0]), frappe.DuplicateEntryError)
|
item_barcode.barcode, duplicate[0][0]))
|
||||||
|
|
||||||
item_barcode.barcode_type = "" if item_barcode.barcode_type not in options else item_barcode.barcode_type
|
item_barcode.barcode_type = "" if item_barcode.barcode_type not in options else item_barcode.barcode_type
|
||||||
if item_barcode.barcode_type and item_barcode.barcode_type.upper() in ('EAN', 'UPC-A', 'EAN-13', 'EAN-8'):
|
if item_barcode.barcode_type and item_barcode.barcode_type.upper() in ('EAN', 'UPC-A', 'EAN-13', 'EAN-8'):
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,107 +1,50 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"actions": [],
|
||||||
"allow_events_in_timeline": 0,
|
"creation": "2013-02-22 01:28:01",
|
||||||
"allow_guest_to_view": 0,
|
"doctype": "DocType",
|
||||||
"allow_import": 0,
|
"editable_grid": 1,
|
||||||
"allow_rename": 0,
|
"engine": "InnoDB",
|
||||||
"beta": 0,
|
"field_order": [
|
||||||
"creation": "2013-02-22 01:28:01",
|
"item_tax_template",
|
||||||
"custom": 0,
|
"tax_category",
|
||||||
"docstatus": 0,
|
"valid_from"
|
||||||
"doctype": "DocType",
|
],
|
||||||
"editable_grid": 1,
|
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "item_tax_template",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Link",
|
||||||
"allow_on_submit": 0,
|
"in_list_view": 1,
|
||||||
"bold": 0,
|
"label": "Item Tax Template",
|
||||||
"collapsible": 0,
|
"oldfieldname": "tax_type",
|
||||||
"columns": 0,
|
"oldfieldtype": "Link",
|
||||||
"fieldname": "item_tax_template",
|
"options": "Item Tax Template",
|
||||||
"fieldtype": "Link",
|
"reqd": 1
|
||||||
"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": "Item Tax Template",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"oldfieldname": "tax_type",
|
|
||||||
"oldfieldtype": "Link",
|
|
||||||
"options": "Item Tax Template",
|
|
||||||
"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": "tax_category",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Link",
|
||||||
"allow_on_submit": 0,
|
"in_list_view": 1,
|
||||||
"bold": 0,
|
"label": "Tax Category",
|
||||||
"collapsible": 0,
|
"oldfieldname": "tax_rate",
|
||||||
"columns": 0,
|
"oldfieldtype": "Currency",
|
||||||
"fetch_from": "",
|
"options": "Tax Category"
|
||||||
"fieldname": "tax_category",
|
},
|
||||||
"fieldtype": "Link",
|
{
|
||||||
"hidden": 0,
|
"fieldname": "valid_from",
|
||||||
"ignore_user_permissions": 0,
|
"fieldtype": "Date",
|
||||||
"ignore_xss_filter": 0,
|
"in_list_view": 1,
|
||||||
"in_filter": 0,
|
"label": "Valid From"
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Tax Category",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"oldfieldname": "tax_rate",
|
|
||||||
"oldfieldtype": "Currency",
|
|
||||||
"options": "Tax Category",
|
|
||||||
"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
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
"idx": 1,
|
||||||
"hide_heading": 0,
|
"istable": 1,
|
||||||
"hide_toolbar": 0,
|
"links": [],
|
||||||
"idx": 1,
|
"modified": "2019-12-28 21:54:40.807849",
|
||||||
"image_view": 0,
|
"modified_by": "Administrator",
|
||||||
"in_create": 0,
|
"module": "Stock",
|
||||||
"is_submittable": 0,
|
"name": "Item Tax",
|
||||||
"issingle": 0,
|
"owner": "Administrator",
|
||||||
"istable": 1,
|
"permissions": [],
|
||||||
"max_attachments": 0,
|
"sort_field": "modified",
|
||||||
"modified": "2018-12-21 23:52:40.798944",
|
"sort_order": "DESC"
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "Stock",
|
|
||||||
"name": "Item Tax",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [],
|
|
||||||
"quick_entry": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"read_only_onload": 0,
|
|
||||||
"show_name_in_global_search": 0,
|
|
||||||
"track_changes": 0,
|
|
||||||
"track_seen": 0,
|
|
||||||
"track_views": 0
|
|
||||||
}
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user