Merge branch 'develop' into razorpay-subscription
This commit is contained in:
commit
88c1f28351
@ -89,7 +89,7 @@ class Account(NestedSet):
|
|||||||
throw(_("Root cannot be edited."), RootNotEditable)
|
throw(_("Root cannot be edited."), RootNotEditable)
|
||||||
|
|
||||||
if not self.parent_account and not self.is_group:
|
if not self.parent_account and not self.is_group:
|
||||||
frappe.throw(_("Root Account must be a group"))
|
frappe.throw(_("The root account {0} must be a group").format(frappe.bold(self.name)))
|
||||||
|
|
||||||
def validate_root_company_and_sync_account_to_children(self):
|
def validate_root_company_and_sync_account_to_children(self):
|
||||||
# ignore validation while creating new compnay or while syncing to child companies
|
# ignore validation while creating new compnay or while syncing to child companies
|
||||||
|
@ -178,7 +178,8 @@ def filter_pricing_rules(args, pricing_rules, doc=None):
|
|||||||
|
|
||||||
if pricing_rules[0].mixed_conditions and doc:
|
if pricing_rules[0].mixed_conditions and doc:
|
||||||
stock_qty, amount, items = get_qty_and_rate_for_mixed_conditions(doc, pr_doc, args)
|
stock_qty, amount, items = get_qty_and_rate_for_mixed_conditions(doc, pr_doc, args)
|
||||||
pricing_rules[0].apply_rule_on_other_items = items
|
for pricing_rule_args in pricing_rules:
|
||||||
|
pricing_rule_args.apply_rule_on_other_items = items
|
||||||
|
|
||||||
elif pricing_rules[0].is_cumulative:
|
elif pricing_rules[0].is_cumulative:
|
||||||
items = [args.get(frappe.scrub(pr_doc.get('apply_on')))]
|
items = [args.get(frappe.scrub(pr_doc.get('apply_on')))]
|
||||||
@ -329,9 +330,9 @@ def get_qty_and_rate_for_mixed_conditions(doc, pr_doc, args):
|
|||||||
if pr_doc.mixed_conditions:
|
if pr_doc.mixed_conditions:
|
||||||
amt = args.get('qty') * args.get("price_list_rate")
|
amt = args.get('qty') * args.get("price_list_rate")
|
||||||
if args.get("item_code") != row.get("item_code"):
|
if args.get("item_code") != row.get("item_code"):
|
||||||
amt = row.get('qty') * row.get("price_list_rate")
|
amt = row.get('qty') * (row.get("price_list_rate") or args.get("rate"))
|
||||||
|
|
||||||
sum_qty += row.get("stock_qty") or args.get("stock_qty")
|
sum_qty += row.get("stock_qty") or args.get("stock_qty") or args.get("qty")
|
||||||
sum_amt += amt
|
sum_amt += amt
|
||||||
|
|
||||||
if pr_doc.is_cumulative:
|
if pr_doc.is_cumulative:
|
||||||
|
@ -754,8 +754,7 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "manufacturer_part_no",
|
"fieldname": "manufacturer_part_no",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Manufacturer Part Number",
|
"label": "Manufacturer Part Number"
|
||||||
"read_only": 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "is_fixed_asset",
|
"depends_on": "is_fixed_asset",
|
||||||
@ -777,7 +776,7 @@
|
|||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-04-01 14:20:17.297284",
|
"modified": "2020-04-07 18:34:35.104178",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Purchase Invoice Item",
|
"name": "Purchase Invoice Item",
|
||||||
|
@ -440,11 +440,12 @@ class SalesInvoice(SellingController):
|
|||||||
if pos.get("company_address"):
|
if pos.get("company_address"):
|
||||||
self.company_address = pos.get("company_address")
|
self.company_address = pos.get("company_address")
|
||||||
|
|
||||||
customer_price_list, customer_group = frappe.get_value("Customer", self.customer, ['default_price_list', 'customer_group'])
|
if self.customer:
|
||||||
|
customer_price_list, customer_group = frappe.get_value("Customer", self.customer, ['default_price_list', 'customer_group'])
|
||||||
customer_group_price_list = frappe.get_value("Customer Group", customer_group, 'default_price_list')
|
customer_group_price_list = frappe.get_value("Customer Group", customer_group, 'default_price_list')
|
||||||
|
selling_price_list = customer_price_list or customer_group_price_list or pos.get('selling_price_list')
|
||||||
selling_price_list = customer_price_list or customer_group_price_list or pos.get('selling_price_list')
|
else:
|
||||||
|
selling_price_list = pos.get('selling_price_list')
|
||||||
|
|
||||||
if selling_price_list:
|
if selling_price_list:
|
||||||
self.set('selling_price_list', selling_price_list)
|
self.set('selling_price_list', selling_price_list)
|
||||||
|
@ -702,8 +702,7 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "manufacturer_part_no",
|
"fieldname": "manufacturer_part_no",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Manufacturer Part Number",
|
"label": "Manufacturer Part Number"
|
||||||
"read_only": 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
@ -723,7 +722,7 @@
|
|||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2019-12-06 13:17:12.142799",
|
"modified": "2020-04-07 18:35:17.558928",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Purchase Order Item",
|
"name": "Purchase Order Item",
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"autoname": "hash",
|
"autoname": "hash",
|
||||||
"creation": "2013-05-22 12:43:10",
|
"creation": "2013-05-22 12:43:10",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
@ -522,8 +523,7 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "manufacturer_part_no",
|
"fieldname": "manufacturer_part_no",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Manufacturer Part Number",
|
"label": "Manufacturer Part Number"
|
||||||
"read_only": 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_15",
|
"fieldname": "column_break_15",
|
||||||
@ -532,7 +532,8 @@
|
|||||||
],
|
],
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"modified": "2019-06-02 05:32:46.019237",
|
"links": [],
|
||||||
|
"modified": "2020-04-07 18:35:51.175947",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Supplier Quotation Item",
|
"name": "Supplier Quotation Item",
|
||||||
|
@ -1123,36 +1123,39 @@ def get_supplier_block_status(party_name):
|
|||||||
}
|
}
|
||||||
return info
|
return info
|
||||||
|
|
||||||
def set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, item_code):
|
def set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, trans_item):
|
||||||
"""
|
"""
|
||||||
Returns a Sales Order Item child item containing the default values
|
Returns a Sales Order Item child item containing the default values
|
||||||
"""
|
"""
|
||||||
p_doc = frappe.get_doc(parent_doctype, parent_doctype_name)
|
p_doc = frappe.get_doc(parent_doctype, parent_doctype_name)
|
||||||
child_item = frappe.new_doc('Sales Order Item', p_doc, child_docname)
|
child_item = frappe.new_doc('Sales Order Item', p_doc, child_docname)
|
||||||
item = frappe.get_doc("Item", item_code)
|
item = frappe.get_doc("Item", trans_item.get('item_code'))
|
||||||
child_item.item_code = item.item_code
|
child_item.item_code = item.item_code
|
||||||
child_item.item_name = item.item_name
|
child_item.item_name = item.item_name
|
||||||
child_item.description = item.description
|
child_item.description = item.description
|
||||||
child_item.reqd_by_date = p_doc.delivery_date
|
child_item.delivery_date = trans_item.get('delivery_date') or p_doc.delivery_date
|
||||||
child_item.uom = item.stock_uom
|
child_item.uom = item.stock_uom
|
||||||
child_item.conversion_factor = get_conversion_factor(item_code, item.stock_uom).get("conversion_factor") or 1.0
|
child_item.conversion_factor = get_conversion_factor(item.item_code, item.stock_uom).get("conversion_factor") or 1.0
|
||||||
child_item.warehouse = get_item_warehouse(item, p_doc, overwrite_warehouse=True)
|
child_item.warehouse = get_item_warehouse(item, p_doc, overwrite_warehouse=True)
|
||||||
|
if not child_item.warehouse:
|
||||||
|
frappe.throw(_("Cannot find {} for item {}. Please set the same in Item Master or Stock Settings.")
|
||||||
|
.format(frappe.bold("default warehouse"), frappe.bold(item.item_code)))
|
||||||
return child_item
|
return child_item
|
||||||
|
|
||||||
|
|
||||||
def set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docname, item_code):
|
def set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docname, trans_item):
|
||||||
"""
|
"""
|
||||||
Returns a Purchase Order Item child item containing the default values
|
Returns a Purchase Order Item child item containing the default values
|
||||||
"""
|
"""
|
||||||
p_doc = frappe.get_doc(parent_doctype, parent_doctype_name)
|
p_doc = frappe.get_doc(parent_doctype, parent_doctype_name)
|
||||||
child_item = frappe.new_doc('Purchase Order Item', p_doc, child_docname)
|
child_item = frappe.new_doc('Purchase Order Item', p_doc, child_docname)
|
||||||
item = frappe.get_doc("Item", item_code)
|
item = frappe.get_doc("Item", trans_item.get('item_code'))
|
||||||
child_item.item_code = item.item_code
|
child_item.item_code = item.item_code
|
||||||
child_item.item_name = item.item_name
|
child_item.item_name = item.item_name
|
||||||
child_item.description = item.description
|
child_item.description = item.description
|
||||||
child_item.schedule_date = p_doc.schedule_date
|
child_item.schedule_date = trans_item.get('schedule_date') or p_doc.schedule_date
|
||||||
child_item.uom = item.stock_uom
|
child_item.uom = item.stock_uom
|
||||||
child_item.conversion_factor = get_conversion_factor(item_code, item.stock_uom).get("conversion_factor") or 1.0
|
child_item.conversion_factor = get_conversion_factor(item.item_code, item.stock_uom).get("conversion_factor") or 1.0
|
||||||
child_item.base_rate = 1 # Initiallize value will update in parent validation
|
child_item.base_rate = 1 # Initiallize value will update in parent validation
|
||||||
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
|
||||||
@ -1196,9 +1199,9 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
|
|||||||
if not d.get("docname"):
|
if not d.get("docname"):
|
||||||
new_child_flag = True
|
new_child_flag = True
|
||||||
if parent_doctype == "Sales Order":
|
if parent_doctype == "Sales Order":
|
||||||
child_item = set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, d.get("item_code"))
|
child_item = set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, d)
|
||||||
if parent_doctype == "Purchase Order":
|
if parent_doctype == "Purchase Order":
|
||||||
child_item = set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docname, d.get("item_code"))
|
child_item = set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docname, d)
|
||||||
else:
|
else:
|
||||||
child_item = frappe.get_doc(parent_doctype + ' Item', d.get("docname"))
|
child_item = frappe.get_doc(parent_doctype + ' Item', d.get("docname"))
|
||||||
if flt(child_item.get("rate")) == flt(d.get("rate")) and flt(child_item.get("qty")) == flt(d.get("qty")):
|
if flt(child_item.get("rate")) == flt(d.get("rate")) and flt(child_item.get("qty")) == flt(d.get("qty")):
|
||||||
@ -1243,6 +1246,7 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
|
|||||||
|
|
||||||
child_item.flags.ignore_validate_update_after_submit = True
|
child_item.flags.ignore_validate_update_after_submit = True
|
||||||
if new_child_flag:
|
if new_child_flag:
|
||||||
|
parent.load_from_db()
|
||||||
child_item.idx = len(parent.items) + 1
|
child_item.idx = len(parent.items) + 1
|
||||||
child_item.insert()
|
child_item.insert()
|
||||||
else:
|
else:
|
||||||
|
@ -667,8 +667,7 @@ def get_itemised_tax_breakup_html(doc):
|
|||||||
itemised_tax=itemised_tax,
|
itemised_tax=itemised_tax,
|
||||||
itemised_taxable_amount=itemised_taxable_amount,
|
itemised_taxable_amount=itemised_taxable_amount,
|
||||||
tax_accounts=tax_accounts,
|
tax_accounts=tax_accounts,
|
||||||
conversion_rate=doc.conversion_rate,
|
doc=doc
|
||||||
currency=doc.currency
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -336,3 +336,27 @@ def make_opportunity_from_communication(communication, ignore_communication_link
|
|||||||
link_communication_to_document(doc, "Opportunity", opportunity.name, ignore_communication_links)
|
link_communication_to_document(doc, "Opportunity", opportunity.name, ignore_communication_links)
|
||||||
|
|
||||||
return opportunity.name
|
return opportunity.name
|
||||||
|
@frappe.whitelist()
|
||||||
|
def get_events(start, end, filters=None):
|
||||||
|
"""Returns events for Gantt / Calendar view rendering.
|
||||||
|
:param start: Start date-time.
|
||||||
|
:param end: End date-time.
|
||||||
|
:param filters: Filters (JSON).
|
||||||
|
"""
|
||||||
|
from frappe.desk.calendar import get_event_conditions
|
||||||
|
conditions = get_event_conditions("Opportunity", filters)
|
||||||
|
|
||||||
|
data = frappe.db.sql("""
|
||||||
|
select
|
||||||
|
distinct `tabOpportunity`.name, `tabOpportunity`.customer_name, `tabOpportunity`.opportunity_amount,
|
||||||
|
`tabOpportunity`.title, `tabOpportunity`.contact_date
|
||||||
|
from
|
||||||
|
`tabOpportunity`
|
||||||
|
where
|
||||||
|
(`tabOpportunity`.contact_date between %(start)s and %(end)s)
|
||||||
|
{conditions}
|
||||||
|
""".format(conditions=conditions), {
|
||||||
|
"start": start,
|
||||||
|
"end": end
|
||||||
|
}, as_dict=True, update={"allDay": 0})
|
||||||
|
return data
|
19
erpnext/crm/doctype/opportunity/opportunity_calendar.js
Normal file
19
erpnext/crm/doctype/opportunity/opportunity_calendar.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
// License: GNU General Public License v3. See license.txt
|
||||||
|
frappe.views.calendar["Opportunity"] = {
|
||||||
|
field_map: {
|
||||||
|
"start": "contact_date",
|
||||||
|
"end": "contact_date",
|
||||||
|
"id": "name",
|
||||||
|
"title": "customer_name",
|
||||||
|
"allDay": "allDay"
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
header: {
|
||||||
|
left: 'prev,next today',
|
||||||
|
center: 'title',
|
||||||
|
right: 'month'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get_events_method: 'erpnext.crm.doctype.opportunity.opportunity.get_events'
|
||||||
|
}
|
@ -347,6 +347,8 @@ get_site_info = 'erpnext.utilities.get_site_info'
|
|||||||
|
|
||||||
payment_gateway_enabled = "erpnext.accounts.utils.create_payment_gateway_account"
|
payment_gateway_enabled = "erpnext.accounts.utils.create_payment_gateway_account"
|
||||||
|
|
||||||
|
communication_doctypes = ["Customer", "Supplier"]
|
||||||
|
|
||||||
regional_overrides = {
|
regional_overrides = {
|
||||||
'France': {
|
'France': {
|
||||||
'erpnext.tests.test_regional.test_method': 'erpnext.regional.france.utils.test_method'
|
'erpnext.tests.test_regional.test_method': 'erpnext.regional.france.utils.test_method'
|
||||||
|
@ -58,18 +58,16 @@ class TestLoanDisbursement(unittest.TestCase):
|
|||||||
|
|
||||||
process_loan_interest_accrual_for_demand_loans(posting_date=add_days(last_date, 1))
|
process_loan_interest_accrual_for_demand_loans(posting_date=add_days(last_date, 1))
|
||||||
|
|
||||||
# Paid 511095.89 amount includes 5,00,000 principal amount and 11095.89 interest amount
|
# Should not be able to create loan disbursement entry before repayment
|
||||||
|
self.assertRaises(frappe.ValidationError, make_loan_disbursement_entry, loan.name,
|
||||||
|
500000, first_date)
|
||||||
|
|
||||||
repayment_entry = create_repayment_entry(loan.name, self.applicant, add_days(get_last_day(nowdate()), 5),
|
repayment_entry = create_repayment_entry(loan.name, self.applicant, add_days(get_last_day(nowdate()), 5),
|
||||||
"Regular Payment", 611095.89)
|
"Regular Payment", 611095.89)
|
||||||
repayment_entry.submit()
|
|
||||||
|
|
||||||
|
repayment_entry.submit()
|
||||||
loan.reload()
|
loan.reload()
|
||||||
|
|
||||||
|
# After repayment loan disbursement entry should go through
|
||||||
make_loan_disbursement_entry(loan.name, 500000, disbursement_date=add_days(last_date, 16))
|
make_loan_disbursement_entry(loan.name, 500000, disbursement_date=add_days(last_date, 16))
|
||||||
|
|
||||||
total_principal_paid = loan.total_principal_paid
|
|
||||||
|
|
||||||
loan.reload()
|
|
||||||
|
|
||||||
# Loan Topup will result in decreasing the Total Principal Paid
|
|
||||||
self.assertEqual(flt(loan.total_principal_paid, 2), flt(total_principal_paid - 500000, 2))
|
|
||||||
|
@ -119,6 +119,7 @@
|
|||||||
"label": "Penalty Interest Rate (%) Per Day"
|
"label": "Penalty Interest Rate (%) Per Day"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"description": "No. of days from due date until which penalty won't be charged in case of delay in loan repayment",
|
||||||
"fieldname": "grace_period_in_days",
|
"fieldname": "grace_period_in_days",
|
||||||
"fieldtype": "Int",
|
"fieldtype": "Int",
|
||||||
"label": "Grace Period in Days"
|
"label": "Grace Period in Days"
|
||||||
@ -142,7 +143,7 @@
|
|||||||
],
|
],
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-02-03 05:03:00.334813",
|
"modified": "2020-04-15 00:24:43.259963",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Loan Management",
|
"module": "Loan Management",
|
||||||
"name": "Loan Type",
|
"name": "Loan Type",
|
||||||
|
@ -100,7 +100,7 @@ def execute():
|
|||||||
|
|
||||||
for entry in encounter_details:
|
for entry in encounter_details:
|
||||||
doc = frappe.get_doc('Patient Encounter', entry.name)
|
doc = frappe.get_doc('Patient Encounter', entry.name)
|
||||||
symptoms = entry.symptoms.split('\n')
|
symptoms = entry.symptoms.split('\n') if entry.symptoms else []
|
||||||
for symptom in symptoms:
|
for symptom in symptoms:
|
||||||
if not frappe.db.exists('Complaint', symptom):
|
if not frappe.db.exists('Complaint', symptom):
|
||||||
frappe.get_doc({
|
frappe.get_doc({
|
||||||
@ -112,7 +112,7 @@ def execute():
|
|||||||
})
|
})
|
||||||
row.db_update()
|
row.db_update()
|
||||||
|
|
||||||
diagnosis = entry.diagnosis.split('\n')
|
diagnosis = entry.diagnosis.split('\n') if entry.diagnosis else []
|
||||||
for d in diagnosis:
|
for d in diagnosis:
|
||||||
if not frappe.db.exists('Diagnosis', d):
|
if not frappe.db.exists('Diagnosis', d):
|
||||||
frappe.get_doc({
|
frappe.get_doc({
|
||||||
|
@ -379,7 +379,31 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
|
manufacturer_part_no: function(doc, cdt, cdn) {
|
||||||
|
const row = locals[cdt][cdn];
|
||||||
|
|
||||||
|
if (row.manufacturer_part_no) {
|
||||||
|
frappe.model.get_value('Item Manufacturer',
|
||||||
|
{
|
||||||
|
'item_code': row.item_code,
|
||||||
|
'manufacturer': row.manufacturer,
|
||||||
|
'manufacturer_part_no': row.manufacturer_part_no
|
||||||
|
},
|
||||||
|
'name',
|
||||||
|
function(data) {
|
||||||
|
if (!data) {
|
||||||
|
let msg = {
|
||||||
|
message: __("Manufacturer Part Number <b>{0}</b> is invalid", [row.manufacturer_part_no]),
|
||||||
|
title: __("Invalid Part Number")
|
||||||
|
}
|
||||||
|
frappe.throw(msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
cur_frm.add_fetch('project', 'cost_center', 'cost_center');
|
cur_frm.add_fetch('project', 'cost_center', 'cost_center');
|
||||||
|
@ -559,7 +559,13 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
() => me.conversion_factor(doc, cdt, cdn, true),
|
() => me.conversion_factor(doc, cdt, cdn, true),
|
||||||
() => me.remove_pricing_rule(item)
|
() => me.remove_pricing_rule(item),
|
||||||
|
() => {
|
||||||
|
if (item.apply_rule_on_other_items) {
|
||||||
|
let key = item.name;
|
||||||
|
me.apply_rule_on_other_items({key: item});
|
||||||
|
}
|
||||||
|
}
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1394,20 +1400,22 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
|
|
||||||
apply_rule_on_other_items: function(args) {
|
apply_rule_on_other_items: function(args) {
|
||||||
const me = this;
|
const me = this;
|
||||||
const fields = ["discount_percentage", "discount_amount", "rate"];
|
const fields = ["discount_percentage", "pricing_rules", "discount_amount", "rate"];
|
||||||
|
|
||||||
for(var k in args) {
|
for(var k in args) {
|
||||||
let data = args[k];
|
let data = args[k];
|
||||||
|
|
||||||
me.frm.doc.items.forEach(d => {
|
if (data && data.apply_rule_on_other_items) {
|
||||||
if (in_list(data.apply_rule_on_other_items, d[data.apply_rule_on])) {
|
me.frm.doc.items.forEach(d => {
|
||||||
for(var k in data) {
|
if (in_list(data.apply_rule_on_other_items, d[data.apply_rule_on])) {
|
||||||
if (in_list(fields, k)) {
|
for(var k in data) {
|
||||||
frappe.model.set_value(d.doctype, d.name, k, data[k]);
|
if (in_list(fields, k) && data[k]) {
|
||||||
|
frappe.model.set_value(d.doctype, d.name, k, data[k]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -436,6 +436,44 @@ erpnext.utils.update_child_items = function(opts) {
|
|||||||
const cannot_add_row = (typeof opts.cannot_add_row === 'undefined') ? true : opts.cannot_add_row;
|
const cannot_add_row = (typeof opts.cannot_add_row === 'undefined') ? true : opts.cannot_add_row;
|
||||||
const child_docname = (typeof opts.cannot_add_row === 'undefined') ? "items" : opts.child_docname;
|
const child_docname = (typeof opts.cannot_add_row === 'undefined') ? "items" : opts.child_docname;
|
||||||
this.data = [];
|
this.data = [];
|
||||||
|
const fields = [{
|
||||||
|
fieldtype:'Data',
|
||||||
|
fieldname:"docname",
|
||||||
|
read_only: 1,
|
||||||
|
hidden: 1,
|
||||||
|
}, {
|
||||||
|
fieldtype:'Link',
|
||||||
|
fieldname:"item_code",
|
||||||
|
options: 'Item',
|
||||||
|
in_list_view: 1,
|
||||||
|
read_only: 0,
|
||||||
|
disabled: 0,
|
||||||
|
label: __('Item Code')
|
||||||
|
}, {
|
||||||
|
fieldtype:'Float',
|
||||||
|
fieldname:"qty",
|
||||||
|
default: 0,
|
||||||
|
read_only: 0,
|
||||||
|
in_list_view: 1,
|
||||||
|
label: __('Qty')
|
||||||
|
}, {
|
||||||
|
fieldtype:'Currency',
|
||||||
|
fieldname:"rate",
|
||||||
|
default: 0,
|
||||||
|
read_only: 0,
|
||||||
|
in_list_view: 1,
|
||||||
|
label: __('Rate')
|
||||||
|
}];
|
||||||
|
|
||||||
|
if (frm.doc.doctype == 'Sales Order' || frm.doc.doctype == 'Purchase Order' ) {
|
||||||
|
fields.splice(2, 0, {
|
||||||
|
fieldtype: 'Date',
|
||||||
|
fieldname: frm.doc.doctype == 'Sales Order' ? "delivery_date" : "schedule_date",
|
||||||
|
in_list_view: 1,
|
||||||
|
label: frm.doc.doctype == 'Sales Order' ? __("Delivery Date") : __("Reqd by date")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const dialog = new frappe.ui.Dialog({
|
const dialog = new frappe.ui.Dialog({
|
||||||
title: __("Update Items"),
|
title: __("Update Items"),
|
||||||
fields: [
|
fields: [
|
||||||
@ -450,34 +488,7 @@ erpnext.utils.update_child_items = function(opts) {
|
|||||||
get_data: () => {
|
get_data: () => {
|
||||||
return this.data;
|
return this.data;
|
||||||
},
|
},
|
||||||
fields: [{
|
fields: fields
|
||||||
fieldtype:'Data',
|
|
||||||
fieldname:"docname",
|
|
||||||
read_only: 1,
|
|
||||||
hidden: 1,
|
|
||||||
}, {
|
|
||||||
fieldtype:'Link',
|
|
||||||
fieldname:"item_code",
|
|
||||||
options: 'Item',
|
|
||||||
in_list_view: 1,
|
|
||||||
read_only: 0,
|
|
||||||
disabled: 0,
|
|
||||||
label: __('Item Code')
|
|
||||||
}, {
|
|
||||||
fieldtype:'Float',
|
|
||||||
fieldname:"qty",
|
|
||||||
default: 0,
|
|
||||||
read_only: 0,
|
|
||||||
in_list_view: 1,
|
|
||||||
label: __('Qty')
|
|
||||||
}, {
|
|
||||||
fieldtype:'Currency',
|
|
||||||
fieldname:"rate",
|
|
||||||
default: 0,
|
|
||||||
read_only: 0,
|
|
||||||
in_list_view: 1,
|
|
||||||
label: __('Rate')
|
|
||||||
}]
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
primary_action: function() {
|
primary_action: function() {
|
||||||
@ -506,6 +517,8 @@ erpnext.utils.update_child_items = function(opts) {
|
|||||||
"docname": d.name,
|
"docname": d.name,
|
||||||
"name": d.name,
|
"name": d.name,
|
||||||
"item_code": d.item_code,
|
"item_code": d.item_code,
|
||||||
|
"delivery_date": d.delivery_date,
|
||||||
|
"schedule_date": d.schedule_date,
|
||||||
"qty": d.qty,
|
"qty": d.qty,
|
||||||
"rate": d.rate,
|
"rate": d.rate,
|
||||||
});
|
});
|
||||||
|
@ -1176,7 +1176,7 @@ class POSCart {
|
|||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="list-item indicator ${indicator_class}" data-item-code="${escape(item.item_code)}"
|
<div class="list-item indicator ${indicator_class}" data-item-code="${escape(item.item_code)}"
|
||||||
data-batch-no="${batch_no}" title="Item: ${item.item_name} Available Qty: ${item.actual_qty}">
|
data-batch-no="${batch_no}" title="Item: ${item.item_name} Available Qty: ${item.actual_qty} ${item.stock_uom}">
|
||||||
<div class="item-name list-item__content list-item__content--flex-1.5 ellipsis">
|
<div class="item-name list-item__content list-item__content--flex-1.5 ellipsis">
|
||||||
${item.item_name}
|
${item.item_name}
|
||||||
</div>
|
</div>
|
||||||
|
@ -37,20 +37,33 @@ def get_items(start, page_length, price_list, item_group, search_value="", pos_p
|
|||||||
lft, rgt = frappe.db.get_value('Item Group', item_group, ['lft', 'rgt'])
|
lft, rgt = frappe.db.get_value('Item Group', item_group, ['lft', 'rgt'])
|
||||||
# locate function is used to sort by closest match from the beginning of the value
|
# locate function is used to sort by closest match from the beginning of the value
|
||||||
|
|
||||||
|
|
||||||
result = []
|
result = []
|
||||||
|
|
||||||
items_data = frappe.db.sql(""" SELECT name as item_code,
|
items_data = frappe.db.sql("""
|
||||||
item_name, image as item_image, idx as idx,is_stock_item
|
SELECT
|
||||||
|
name AS item_code,
|
||||||
|
item_name,
|
||||||
|
stock_uom,
|
||||||
|
image AS item_image,
|
||||||
|
idx AS idx,
|
||||||
|
is_stock_item
|
||||||
FROM
|
FROM
|
||||||
`tabItem`
|
`tabItem`
|
||||||
WHERE
|
WHERE
|
||||||
disabled = 0 and has_variants = 0 and is_sales_item = 1
|
disabled = 0
|
||||||
and item_group in (select name from `tabItem Group` where lft >= {lft} and rgt <= {rgt})
|
AND has_variants = 0
|
||||||
and {condition} order by idx desc limit {start}, {page_length}"""
|
AND is_sales_item = 1
|
||||||
|
AND item_group in (SELECT name FROM `tabItem Group` WHERE lft >= {lft} AND rgt <= {rgt})
|
||||||
|
AND {condition}
|
||||||
|
ORDER BY
|
||||||
|
idx desc
|
||||||
|
LIMIT
|
||||||
|
{start}, {page_length}"""
|
||||||
.format(
|
.format(
|
||||||
start=start, page_length=page_length,
|
start=start,
|
||||||
lft=lft, rgt=rgt,
|
page_length=page_length,
|
||||||
|
lft=lft,
|
||||||
|
rgt=rgt,
|
||||||
condition=condition
|
condition=condition
|
||||||
), as_dict=1)
|
), as_dict=1)
|
||||||
|
|
||||||
|
@ -114,6 +114,8 @@
|
|||||||
"is_sub_contracted_item",
|
"is_sub_contracted_item",
|
||||||
"column_break_74",
|
"column_break_74",
|
||||||
"customer_code",
|
"customer_code",
|
||||||
|
"default_item_manufacturer",
|
||||||
|
"default_manufacturer_part_no",
|
||||||
"website_section",
|
"website_section",
|
||||||
"show_in_website",
|
"show_in_website",
|
||||||
"show_variant_in_website",
|
"show_variant_in_website",
|
||||||
@ -1038,6 +1040,18 @@
|
|||||||
"fieldname": "auto_create_assets",
|
"fieldname": "auto_create_assets",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Auto Create Assets on Purchase"
|
"label": "Auto Create Assets on Purchase"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "default_item_manufacturer",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"label": "Default Item Manufacturer",
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "default_manufacturer_part_no",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"label": "Default Manufacturer Part No",
|
||||||
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 1,
|
"has_web_view": 1,
|
||||||
@ -1046,7 +1060,7 @@
|
|||||||
"image_field": "image",
|
"image_field": "image",
|
||||||
"links": [],
|
"links": [],
|
||||||
"max_attachments": 1,
|
"max_attachments": 1,
|
||||||
"modified": "2020-03-24 16:14:36.950677",
|
"modified": "2020-04-07 15:56:06.195722",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Item",
|
"name": "Item",
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"allow_import": 1,
|
"allow_import": 1,
|
||||||
"creation": "2019-06-02 04:41:37.332911",
|
"creation": "2019-06-02 04:41:37.332911",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
@ -10,7 +11,8 @@
|
|||||||
"manufacturer_part_no",
|
"manufacturer_part_no",
|
||||||
"column_break_3",
|
"column_break_3",
|
||||||
"item_name",
|
"item_name",
|
||||||
"description"
|
"description",
|
||||||
|
"is_default"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@ -52,9 +54,17 @@
|
|||||||
"fieldtype": "Small Text",
|
"fieldtype": "Small Text",
|
||||||
"label": "Description",
|
"label": "Description",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "is_default",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Is Default"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"modified": "2019-06-06 19:07:31.175919",
|
"links": [],
|
||||||
|
"modified": "2020-04-07 20:25:55.507905",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Item Manufacturer",
|
"name": "Item Manufacturer",
|
||||||
|
@ -11,6 +11,10 @@ from frappe.model.document import Document
|
|||||||
class ItemManufacturer(Document):
|
class ItemManufacturer(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_duplicate_entry()
|
self.validate_duplicate_entry()
|
||||||
|
self.manage_default_item_manufacturer()
|
||||||
|
|
||||||
|
def on_trash(self):
|
||||||
|
self.manage_default_item_manufacturer(delete=True)
|
||||||
|
|
||||||
def validate_duplicate_entry(self):
|
def validate_duplicate_entry(self):
|
||||||
if self.is_new():
|
if self.is_new():
|
||||||
@ -24,6 +28,40 @@ class ItemManufacturer(Document):
|
|||||||
frappe.throw(_("Duplicate entry against the item code {0} and manufacturer {1}")
|
frappe.throw(_("Duplicate entry against the item code {0} and manufacturer {1}")
|
||||||
.format(self.item_code, self.manufacturer))
|
.format(self.item_code, self.manufacturer))
|
||||||
|
|
||||||
|
def manage_default_item_manufacturer(self, delete=False):
|
||||||
|
from frappe.model.utils import set_default
|
||||||
|
|
||||||
|
item = frappe.get_doc("Item", self.item_code)
|
||||||
|
default_manufacturer = item.default_item_manufacturer
|
||||||
|
default_part_no = item.default_manufacturer_part_no
|
||||||
|
|
||||||
|
if not self.is_default:
|
||||||
|
# if unchecked and default in Item master, clear it.
|
||||||
|
if default_manufacturer == self.manufacturer and default_part_no == self.manufacturer_part_no:
|
||||||
|
frappe.db.set_value("Item", item.name,
|
||||||
|
{
|
||||||
|
"default_item_manufacturer": None,
|
||||||
|
"default_manufacturer_part_no": None
|
||||||
|
})
|
||||||
|
|
||||||
|
elif self.is_default:
|
||||||
|
set_default(self, "item_code")
|
||||||
|
manufacturer, manufacturer_part_no = default_manufacturer, default_part_no
|
||||||
|
|
||||||
|
if delete:
|
||||||
|
manufacturer, manufacturer_part_no = None, None
|
||||||
|
|
||||||
|
elif (default_manufacturer != self.manufacturer) or \
|
||||||
|
(default_manufacturer == self.manufacturer and default_part_no != self.manufacturer_part_no):
|
||||||
|
manufacturer = self.manufacturer
|
||||||
|
manufacturer_part_no = self.manufacturer_part_no
|
||||||
|
|
||||||
|
frappe.db.set_value("Item", item.name,
|
||||||
|
{
|
||||||
|
"default_item_manufacturer": manufacturer,
|
||||||
|
"default_manufacturer_part_no": manufacturer_part_no
|
||||||
|
})
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_item_manufacturer_part_no(item_code, manufacturer):
|
def get_item_manufacturer_part_no(item_code, manufacturer):
|
||||||
return frappe.db.get_value("Item Manufacturer",
|
return frappe.db.get_value("Item Manufacturer",
|
||||||
|
@ -404,14 +404,13 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "manufacturer_part_no",
|
"fieldname": "manufacturer_part_no",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Manufacturer Part Number",
|
"label": "Manufacturer Part Number"
|
||||||
"read_only": 1
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-02-25 03:09:10.698967",
|
"modified": "2020-04-07 18:37:54.495112",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Material Request Item",
|
"name": "Material Request Item",
|
||||||
|
@ -801,8 +801,7 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "manufacturer_part_no",
|
"fieldname": "manufacturer_part_no",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Manufacturer Part Number",
|
"label": "Manufacturer Part Number"
|
||||||
"read_only": 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "is_fixed_asset",
|
"depends_on": "is_fixed_asset",
|
||||||
@ -832,7 +831,7 @@
|
|||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-03-11 14:19:48.799370",
|
"modified": "2020-04-07 18:38:21.141558",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Purchase Receipt Item",
|
"name": "Purchase Receipt Item",
|
||||||
|
@ -220,8 +220,8 @@ frappe.ui.form.on('Stock Entry', {
|
|||||||
},
|
},
|
||||||
get_query_filters: {
|
get_query_filters: {
|
||||||
docstatus: 1,
|
docstatus: 1,
|
||||||
material_request_type: "Material Transfer",
|
material_request_type: ["in", ["Material Transfer", "Material Issue"]],
|
||||||
status: ['!=', 'Transferred']
|
status: ["not in", ["Transferred", "Issued"]]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}, __("Get items from"));
|
}, __("Get items from"));
|
||||||
|
@ -341,6 +341,9 @@ def get_basic_details(args, item, overwrite_warehouse=True):
|
|||||||
else:
|
else:
|
||||||
out["manufacturer_part_no"] = None
|
out["manufacturer_part_no"] = None
|
||||||
out["manufacturer"] = None
|
out["manufacturer"] = None
|
||||||
|
else:
|
||||||
|
out["manufacturer"], out["manufacturer_part_no"] = frappe.get_value("Item", item.name,
|
||||||
|
["default_item_manufacturer", "default_manufacturer_part_no"] )
|
||||||
|
|
||||||
child_doctype = args.doctype + ' Item'
|
child_doctype = args.doctype + ' Item'
|
||||||
meta = frappe.get_meta(child_doctype)
|
meta = frappe.get_meta(child_doctype)
|
||||||
|
@ -16,7 +16,11 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>{{ item }}</td>
|
<td>{{ item }}</td>
|
||||||
<td class='text-right'>
|
<td class='text-right'>
|
||||||
{{ frappe.utils.fmt_money(itemised_taxable_amount.get(item, 0), None, currency) }}
|
{% if doc.get('is_return') %}
|
||||||
|
{{ frappe.utils.fmt_money((itemised_taxable_amount.get(item, 0))|abs, None, doc.currency) }}
|
||||||
|
{% else %}
|
||||||
|
{{ frappe.utils.fmt_money(itemised_taxable_amount.get(item, 0), None, doc.currency) }}
|
||||||
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
{% for tax_account in tax_accounts %}
|
{% for tax_account in tax_accounts %}
|
||||||
{% set tax_details = taxes.get(tax_account) %}
|
{% set tax_details = taxes.get(tax_account) %}
|
||||||
@ -25,7 +29,11 @@
|
|||||||
{% if tax_details.tax_rate or not tax_details.tax_amount %}
|
{% if tax_details.tax_rate or not tax_details.tax_amount %}
|
||||||
({{ tax_details.tax_rate }}%)
|
({{ tax_details.tax_rate }}%)
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{{ frappe.utils.fmt_money(tax_details.tax_amount / conversion_rate, None, currency) }}
|
{% if doc.get('is_return') %}
|
||||||
|
{{ frappe.utils.fmt_money((tax_details.tax_amount / doc.conversion_rate)|abs, None, doc.currency) }}
|
||||||
|
{% else %}
|
||||||
|
{{ frappe.utils.fmt_money(tax_details.tax_amount / doc.conversion_rate, None, doc.currency) }}
|
||||||
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
{% else %}
|
{% else %}
|
||||||
<td></td>
|
<td></td>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user