Merge branch 'develop' of https://github.com/frappe/erpnext into navbar_links

This commit is contained in:
Deepesh Garg 2020-08-21 12:36:21 +05:30
commit 1b760cb278
13 changed files with 109 additions and 49 deletions

View File

@ -1,5 +1,4 @@
{
"actions": [],
"autoname": "hash",
"creation": "2013-05-22 12:43:10",
"doctype": "DocType",
@ -82,6 +81,7 @@
"item_tax_rate",
"bom",
"include_exploded_items",
"purchase_invoice_item",
"col_break6",
"purchase_order",
"po_detail",
@ -769,12 +769,21 @@
"collapsible": 1,
"fieldname": "col_break7",
"fieldtype": "Column Break"
},
{
"depends_on": "eval:parent.update_stock == 1",
"fieldname": "purchase_invoice_item",
"fieldtype": "Data",
"ignore_user_permissions": 1,
"label": "Purchase Invoice Item",
"no_copy": 1,
"print_hide": 1,
"read_only": 1
}
],
"idx": 1,
"istable": 1,
"links": [],
"modified": "2020-04-22 10:37:35.103176",
"modified": "2020-08-20 11:48:01.398356",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice Item",

View File

@ -1,5 +1,4 @@
{
"actions": [],
"autoname": "hash",
"creation": "2013-06-04 11:02:19",
"doctype": "DocType",
@ -87,6 +86,7 @@
"edit_references",
"sales_order",
"so_detail",
"sales_invoice_item",
"column_break_74",
"delivery_note",
"dn_detail",
@ -790,12 +790,22 @@
"fieldtype": "Link",
"label": "Project",
"options": "Project"
}
},
{
"depends_on": "eval:parent.update_stock == 1",
"fieldname": "sales_invoice_item",
"fieldtype": "Data",
"ignore_user_permissions": 1,
"label": "Sales Invoice Item",
"no_copy": 1,
"print_hide": 1,
"read_only": 1
}
],
"idx": 1,
"istable": 1,
"links": [],
"modified": "2020-07-18 12:24:41.749986",
"modified": "2020-08-20 11:24:41.749986",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Item",

View File

@ -559,9 +559,19 @@ class BuyingController(StockController):
"serial_no": cstr(d.serial_no).strip()
})
if self.is_return:
original_incoming_rate = frappe.db.get_value("Stock Ledger Entry",
{"voucher_type": "Purchase Receipt", "voucher_no": self.return_against,
"item_code": d.item_code}, "incoming_rate")
filters = {
"voucher_type": self.doctype,
"voucher_no": self.return_against,
"item_code": d.item_code
}
if (self.doctype == "Purchase Invoice" and self.update_stock
and d.get("purchase_invoice_item")):
filters["voucher_detail_no"] = d.purchase_invoice_item
elif self.doctype == "Purchase Receipt" and d.get("purchase_receipt_item"):
filters["voucher_detail_no"] = d.purchase_receipt_item
original_incoming_rate = frappe.db.get_value("Stock Ledger Entry", filters, "incoming_rate")
sle.update({
"outgoing_rate": original_incoming_rate

View File

@ -497,24 +497,18 @@ def warehouse_query(doctype, txt, searchfield, start, page_len, filters):
conditions, bin_conditions = [], []
filter_dict = get_doctype_wise_filters(filters)
sub_query = """ select round(`tabBin`.actual_qty, 2) from `tabBin`
where `tabBin`.warehouse = `tabWarehouse`.name
{bin_conditions} """.format(
bin_conditions=get_filters_cond(doctype, filter_dict.get("Bin"),
bin_conditions, ignore_permissions=True))
query = """select `tabWarehouse`.name,
CONCAT_WS(" : ", "Actual Qty", ifnull( ({sub_query}), 0) ) as actual_qty
from `tabWarehouse`
CONCAT_WS(" : ", "Actual Qty", ifnull(round(`tabBin`.actual_qty, 2), 0 )) actual_qty
from `tabWarehouse` left join `tabBin`
on `tabBin`.warehouse = `tabWarehouse`.name {bin_conditions}
where
`tabWarehouse`.`{key}` like {txt}
`tabWarehouse`.`{key}` like {txt}
{fcond} {mcond}
order by
`tabWarehouse`.name desc
order by ifnull(`tabBin`.actual_qty, 0) desc
limit
{start}, {page_len}
""".format(
sub_query=sub_query,
bin_conditions=get_filters_cond(doctype, filter_dict.get("Bin"),bin_conditions, ignore_permissions=True),
key=searchfield,
fcond=get_filters_cond(doctype, filter_dict.get("Warehouse"), conditions),
mcond=get_match_cond(doctype),

View File

@ -281,6 +281,8 @@ def make_return_doc(doctype, source_name, target_doc=None):
target_doc.rejected_warehouse = source_doc.rejected_warehouse
target_doc.po_detail = source_doc.po_detail
target_doc.pr_detail = source_doc.pr_detail
target_doc.purchase_invoice_item = source_doc.name
elif doctype == "Delivery Note":
target_doc.against_sales_order = source_doc.against_sales_order
target_doc.against_sales_invoice = source_doc.against_sales_invoice
@ -296,6 +298,7 @@ def make_return_doc(doctype, source_name, target_doc=None):
target_doc.so_detail = source_doc.so_detail
target_doc.dn_detail = source_doc.dn_detail
target_doc.expense_account = source_doc.expense_account
target_doc.sales_invoice_item = source_doc.name
if default_warehouse_for_sales_return:
target_doc.warehouse = default_warehouse_for_sales_return

View File

@ -217,7 +217,9 @@ class SellingController(StockController):
'target_warehouse': p.target_warehouse,
'company': self.company,
'voucher_type': self.doctype,
'allow_zero_valuation': d.allow_zero_valuation_rate
'allow_zero_valuation': d.allow_zero_valuation_rate,
'sales_invoice_item': d.get("sales_invoice_item"),
'delivery_note_item': d.get("dn_detail")
}))
else:
il.append(frappe._dict({
@ -233,7 +235,9 @@ class SellingController(StockController):
'target_warehouse': d.target_warehouse,
'company': self.company,
'voucher_type': self.doctype,
'allow_zero_valuation': d.allow_zero_valuation_rate
'allow_zero_valuation': d.allow_zero_valuation_rate,
'sales_invoice_item': d.get("sales_invoice_item"),
'delivery_note_item': d.get("dn_detail")
}))
return il
@ -302,7 +306,11 @@ class SellingController(StockController):
d.conversion_factor = get_conversion_factor(d.item_code, d.uom).get("conversion_factor") or 1.0
return_rate = 0
if cint(self.is_return) and self.return_against and self.docstatus==1:
return_rate = self.get_incoming_rate_for_return(d.item_code, self.return_against)
against_document_no = (d.get("sales_invoice_item")
if self.doctype == "Sales Invoice" else d.get("delivery_note_item"))
return_rate = self.get_incoming_rate_for_return(d.item_code,
self.return_against, against_document_no)
# On cancellation or if return entry submission, make stock ledger entry for
# target warehouse first, to update serial no values properly

View File

@ -301,14 +301,19 @@ class StockController(AccountsController):
return serialized_items
def get_incoming_rate_for_return(self, item_code, against_document):
def get_incoming_rate_for_return(self, item_code, against_document, against_document_no=None):
incoming_rate = 0.0
cond = ''
if against_document and item_code:
if against_document_no:
cond = " and voucher_detail_no = %s" %(frappe.db.escape(against_document_no))
incoming_rate = frappe.db.sql("""select abs(stock_value_difference / actual_qty)
from `tabStock Ledger Entry`
where voucher_type = %s and voucher_no = %s
and item_code = %s limit 1""",
and item_code = %s {0} limit 1""".format(cond),
(self.doctype, against_document, item_code))
incoming_rate = incoming_rate[0][0] if incoming_rate else 0.0
return incoming_rate

View File

@ -325,7 +325,7 @@ def auto_close_opportunity():
doc.save()
@frappe.whitelist()
def make_opportunity_from_communication(communication, ignore_communication_links=False):
def make_opportunity_from_communication(communication, company, ignore_communication_links=False):
from erpnext.crm.doctype.lead.lead import make_lead_from_communication
doc = frappe.get_doc("Communication", communication)
@ -337,6 +337,7 @@ def make_opportunity_from_communication(communication, ignore_communication_link
opportunity = frappe.get_doc({
"doctype": "Opportunity",
"company": company,
"opportunity_from": opportunity_from,
"party_name": lead
}).insert(ignore_permissions=True)

View File

@ -3,6 +3,7 @@
from __future__ import unicode_literals
import frappe
from frappe.utils import cint
from frappe.model.document import Document
from frappe.model.mapper import get_mapped_doc
from frappe import _
@ -24,8 +25,7 @@ class JobOffer(Document):
check_vacancies = frappe.get_single("HR Settings").check_vacancies
if staffing_plan and check_vacancies:
job_offers = self.get_job_offer(staffing_plan.from_date, staffing_plan.to_date)
if not staffing_plan.get("vacancies") or staffing_plan.vacancies - len(job_offers) <= 0:
if not staffing_plan.get("vacancies") or cint(staffing_plan.vacancies) - len(job_offers) <= 0:
error_variable = 'for ' + frappe.bold(self.designation)
if staffing_plan.get("parent"):
error_variable = frappe.bold(get_link_to_form("Staffing Plan", staffing_plan.parent))
@ -65,7 +65,7 @@ def get_staffing_plan_detail(designation, company, offer_date):
AND %s between sp.from_date and sp.to_date
""", (designation, company, offer_date), as_dict=1)
return frappe._dict(detail[0]) if detail else None
return frappe._dict(detail[0]) if (detail and detail[0].parent) else None
@frappe.whitelist()
def make_employee(source_name, target_doc=None):

View File

@ -7,7 +7,7 @@ frappe.ui.form.on("Communication", {
},
setup_custom_buttons: (frm) => {
let confirm_msg = "Are you sure you want to create {0} from this email";
let confirm_msg = "Are you sure you want to create {0} from this email?";
if(frm.doc.reference_doctype !== "Issue") {
frm.add_custom_button(__("Issue"), () => {
frappe.confirm(__(confirm_msg, [__("Issue")]), () => {
@ -62,17 +62,36 @@ frappe.ui.form.on("Communication", {
},
make_opportunity_from_communication: (frm) => {
return frappe.call({
method: "erpnext.crm.doctype.opportunity.opportunity.make_opportunity_from_communication",
args: {
communication: frm.doc.name
},
freeze: true,
callback: (r) => {
if(r.message) {
frm.reload_doc()
const fields = [{
fieldtype: 'Link',
label: __('Select a Company'),
fieldname: 'company',
options: 'Company',
reqd: 1,
default: frappe.defaults.get_user_default("Company")
}];
frappe.prompt(fields, data => {
frappe.call({
method: "erpnext.crm.doctype.opportunity.opportunity.make_opportunity_from_communication",
args: {
communication: frm.doc.name,
company: data.company
},
freeze: true,
callback: (r) => {
if(r.message) {
frm.reload_doc();
frappe.show_alert({
message: __("Opportunity {0} created",
['<a href="#Form/Opportunity/'+r.message+'">' + r.message + '</a>']),
indicator: 'green'
});
}
}
}
})
});
},
'Create an Opportunity',
'Create');
}
});
});

View File

@ -22,6 +22,8 @@
}
.filter-options {
margin-left: -5px;
padding-left: 5px;
max-height: 300px;
overflow: auto;
}

View File

@ -726,9 +726,6 @@ def make_regional_gl_entries(gl_entries, doc):
if country != 'India':
return gl_entries
if not doc.total_taxes_and_charges:
return gl_entries
if doc.reverse_charge == 'Y':
gst_accounts = get_gst_accounts(doc.company)
gst_account_list = gst_accounts.get('cgst_account') + gst_accounts.get('sgst_account') \
@ -738,6 +735,7 @@ def make_regional_gl_entries(gl_entries, doc):
if tax.category not in ("Total", "Valuation and Total"):
continue
dr_or_cr = "credit" if tax.add_deduct_tax == "Add" else "debit"
if flt(tax.base_tax_amount_after_discount_amount) and tax.account_head in gst_account_list:
account_currency = get_account_currency(tax.account_head)
@ -747,8 +745,8 @@ def make_regional_gl_entries(gl_entries, doc):
"cost_center": tax.cost_center,
"posting_date": doc.posting_date,
"against": doc.supplier,
"credit": tax.base_tax_amount_after_discount_amount,
"credits_in_account_currency": tax.base_tax_amount_after_discount_amount \
dr_or_cr: tax.base_tax_amount_after_discount_amount,
dr_or_cr + "_in_account_currency": tax.base_tax_amount_after_discount_amount \
if account_currency==doc.company_currency \
else tax.tax_amount_after_discount_amount
}, account_currency, item=tax)

View File

@ -7,6 +7,7 @@ import frappe
from erpnext.accounts.doctype.cash_flow_mapper.default_cash_flow_mapper import DEFAULT_MAPPERS
from .default_success_action import get_default_success_action
from frappe import _
from frappe.utils import cint
from frappe.desk.page.setup_wizard.setup_wizard import add_all_roles_to
from frappe.custom.doctype.custom_field.custom_field import create_custom_field
from erpnext.setup.default_energy_point_rules import get_default_energy_point_rules
@ -30,7 +31,7 @@ def after_install():
def check_setup_wizard_not_completed():
if frappe.db.get_default('desktop:home_page') != 'setup-wizard':
if cint(frappe.db.get_single_value('System Settings', 'setup_complete') or 0):
message = """ERPNext can only be installed on a fresh site where the setup wizard is not completed.
You can reinstall this site (after saving your data) using: bench --site [sitename] reinstall"""
frappe.throw(message)