Merge branch 'hotfix' into fix_by_voucher_order
This commit is contained in:
@@ -5,7 +5,7 @@ import frappe
|
||||
from erpnext.hooks import regional_overrides
|
||||
from frappe.utils import getdate
|
||||
|
||||
__version__ = '11.1.39'
|
||||
__version__ = '11.1.42'
|
||||
|
||||
def get_default_company(user=None):
|
||||
'''Get default company for user'''
|
||||
|
||||
@@ -487,7 +487,7 @@ class SalesInvoice(SellingController):
|
||||
"""Set against account for debit to account"""
|
||||
against_acc = []
|
||||
for d in self.get('items'):
|
||||
if d.income_account not in against_acc:
|
||||
if d.income_account and d.income_account not in against_acc:
|
||||
against_acc.append(d.income_account)
|
||||
self.against_income_account = ','.join(against_acc)
|
||||
|
||||
|
||||
@@ -12,20 +12,21 @@ def get_ordered_to_be_billed_data(args):
|
||||
child_tab = doctype + " Item"
|
||||
precision = get_field_precision(frappe.get_meta(child_tab).get_field("billed_amt"),
|
||||
currency=get_default_currency()) or 2
|
||||
|
||||
|
||||
project_field = get_project_field(doctype, party)
|
||||
|
||||
return frappe.db.sql("""
|
||||
Select
|
||||
`{parent_tab}`.name, `{parent_tab}`.{date_field}, `{parent_tab}`.{party}, `{parent_tab}`.{party}_name,
|
||||
{project_field}, `{child_tab}`.item_code, `{child_tab}`.base_amount,
|
||||
(`{child_tab}`.billed_amt * ifnull(`{parent_tab}`.conversion_rate, 1)),
|
||||
(`{child_tab}`.billed_amt * ifnull(`{parent_tab}`.conversion_rate, 1)),
|
||||
(`{child_tab}`.base_amount - (`{child_tab}`.billed_amt * ifnull(`{parent_tab}`.conversion_rate, 1))),
|
||||
`{child_tab}`.item_name, `{child_tab}`.description, `{parent_tab}`.company
|
||||
from
|
||||
`{parent_tab}`, `{child_tab}`
|
||||
where
|
||||
`{parent_tab}`.name = `{child_tab}`.parent and `{parent_tab}`.docstatus = 1 and `{parent_tab}`.status != 'Closed'
|
||||
`{parent_tab}`.name = `{child_tab}`.parent and `{parent_tab}`.docstatus = 1
|
||||
and `{parent_tab}`.status not in ('Closed', 'Completed')
|
||||
and `{child_tab}`.amount > 0 and round(`{child_tab}`.billed_amt *
|
||||
ifnull(`{parent_tab}`.conversion_rate, 1), {precision}) < `{child_tab}`.base_amount
|
||||
order by
|
||||
|
||||
@@ -104,7 +104,7 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
|
||||
|
||||
if(doc.docstatus == 1 && !in_list(["Closed", "Delivered"], doc.status)) {
|
||||
if (this.frm.has_perm("submit")) {
|
||||
if(flt(doc.per_billed, 2) < 100 || doc.per_received < 100) {
|
||||
if(flt(doc.per_billed, 6) < 100 || flt(doc.per_received, 6) < 100) {
|
||||
cur_frm.add_custom_button(__('Close'), this.close_purchase_order, __("Status"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -428,8 +428,9 @@ class BuyingController(StockController):
|
||||
elif not flt(d.rejected_qty):
|
||||
d.rejected_qty = flt(d.received_qty) - flt(d.qty)
|
||||
|
||||
val = flt(d.qty) + flt(d.rejected_qty)
|
||||
# Check Received Qty = Accepted Qty + Rejected Qty
|
||||
if ((flt(d.qty) + flt(d.rejected_qty)) != flt(d.received_qty)):
|
||||
if (flt(val, d.precision("received_qty")) != flt(d.received_qty, d.precision("received_qty"))):
|
||||
frappe.throw(_("Accepted + Rejected Qty must be equal to Received quantity for Item {0}").format(d.item_code))
|
||||
|
||||
def validate_negative_quantity(self, item_row, field_list):
|
||||
|
||||
@@ -27,7 +27,7 @@ status_map = {
|
||||
],
|
||||
"Quotation": [
|
||||
["Draft", None],
|
||||
["Submitted", "eval:self.docstatus==1"],
|
||||
["Open", "eval:self.docstatus==1"],
|
||||
["Lost", "eval:self.status=='Lost'"],
|
||||
["Ordered", "has_sales_order"],
|
||||
["Cancelled", "eval:self.docstatus==2"],
|
||||
|
||||
@@ -42,7 +42,7 @@ update_and_get_user_progress = "erpnext.utilities.user_progress_utils.update_def
|
||||
on_session_creation = "erpnext.shopping_cart.utils.set_cart_count"
|
||||
on_logout = "erpnext.shopping_cart.utils.clear_cart_count"
|
||||
|
||||
treeviews = ['Account', 'Cost Center', 'Warehouse', 'Item Group', 'Customer Group', 'Sales Person', 'Territory', 'Assessment Group']
|
||||
treeviews = ['Account', 'Cost Center', 'Warehouse', 'Item Group', 'Customer Group', 'Sales Person', 'Territory', 'Assessment Group', 'Department']
|
||||
|
||||
# website
|
||||
update_website_context = "erpnext.shopping_cart.utils.update_website_context"
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// For license information, please see license.txt
|
||||
frappe.views.calendar["Attendance"] = {
|
||||
field_map: {
|
||||
"start": "date",
|
||||
"end": "date",
|
||||
"start": "attendance_date",
|
||||
"end": "attendance_date",
|
||||
"id": "name",
|
||||
"docstatus": 1
|
||||
},
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
frappe.ui.form.on('Department', {
|
||||
refresh: function(frm) {
|
||||
// read-only for root department
|
||||
if(!frm.doc.parent_department) {
|
||||
if(!frm.doc.parent_department && !frm.is_new()) {
|
||||
frm.set_read_only();
|
||||
frm.set_intro(__("This is a root department and cannot be edited."));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_events_in_timeline": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 1,
|
||||
@@ -19,6 +20,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "department_name",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
@@ -52,6 +54,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "parent_department",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@@ -85,6 +88,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@@ -118,6 +122,7 @@
|
||||
"bold": 1,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "is_group",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
@@ -150,6 +155,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "disabled",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
@@ -182,6 +188,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "section_break_4",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
@@ -214,6 +221,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "Days for which Holidays are blocked for this department.",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "leave_block_list",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@@ -246,6 +254,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "leave_section",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
@@ -279,6 +288,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "The first Leave Approver in the list will be set as the default Leave Approver.",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "leave_approvers",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
@@ -312,6 +322,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "expense_section",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
@@ -345,6 +356,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "The first Expense Approver in the list will be set as the default Expense Approver.",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "expense_approvers",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
@@ -378,6 +390,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "lft",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 1,
|
||||
@@ -410,6 +423,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "rgt",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 1,
|
||||
@@ -442,6 +456,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "old_parent",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
@@ -479,7 +494,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-08-29 06:26:12.995703",
|
||||
"modified": "2019-06-25 18:43:05.550387",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Department",
|
||||
@@ -543,7 +558,7 @@
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 1,
|
||||
|
||||
@@ -400,19 +400,6 @@ def get_leave_balance_on(employee, leave_type, date, allocation_records=None, do
|
||||
|
||||
return flt(allocation.total_leaves_allocated) - (flt(leaves_taken) + flt(leaves_encashed))
|
||||
|
||||
def get_total_allocated_leaves(employee, leave_type, date):
|
||||
filters= {
|
||||
'from_date': ['<=', date],
|
||||
'to_date': ['>=', date],
|
||||
'docstatus': 1,
|
||||
'leave_type': leave_type,
|
||||
'employee': employee
|
||||
}
|
||||
|
||||
leave_allocation_records = frappe.db.get_all('Leave Allocation', filters=filters, fields=['total_leaves_allocated'])
|
||||
|
||||
return flt(leave_allocation_records[0]['total_leaves_allocated']) if leave_allocation_records else flt(0)
|
||||
|
||||
def get_leaves_for_period(employee, leave_type, from_date, to_date, status, docname=None):
|
||||
leave_applications = frappe.db.sql("""
|
||||
select name, employee, leave_type, from_date, to_date, total_leave_days
|
||||
|
||||
@@ -5,7 +5,7 @@ from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from erpnext.hr.doctype.leave_application.leave_application \
|
||||
import get_leave_allocation_records, get_leave_balance_on, get_approved_leaves_for_period, get_total_allocated_leaves
|
||||
import get_leave_allocation_records, get_leave_balance_on, get_approved_leaves_for_period
|
||||
|
||||
|
||||
def execute(filters=None):
|
||||
@@ -35,6 +35,9 @@ def get_data(filters, leave_types):
|
||||
allocation_records_based_on_to_date = get_leave_allocation_records(filters.to_date)
|
||||
allocation_records_based_on_from_date = get_leave_allocation_records(filters.from_date)
|
||||
|
||||
if filters.to_date <= filters.from_date:
|
||||
frappe.throw(_("From date can not be greater than than To date"))
|
||||
|
||||
active_employees = frappe.get_all("Employee",
|
||||
filters = { "status": "Active", "company": filters.company},
|
||||
fields = ["name", "employee_name", "department", "user_id"])
|
||||
@@ -51,7 +54,8 @@ def get_data(filters, leave_types):
|
||||
filters.from_date, filters.to_date)
|
||||
|
||||
# opening balance
|
||||
opening = get_total_allocated_leaves(employee.name, leave_type, filters.to_date)
|
||||
opening = get_leave_balance_on(employee.name, leave_type, filters.from_date,
|
||||
allocation_records_based_on_to_date.get(employee.name, frappe._dict()))
|
||||
|
||||
# closing balance
|
||||
closing = get_leave_balance_on(employee.name, leave_type, filters.to_date,
|
||||
|
||||
@@ -586,7 +586,7 @@ erpnext.patches.v11_0.add_permissions_in_gst_settings
|
||||
erpnext.patches.v11_1.setup_guardian_role
|
||||
execute:frappe.delete_doc('DocType', 'Notification Control')
|
||||
erpnext.patches.v11_0.remove_barcodes_field_from_copy_fields_to_variants
|
||||
erpnext.patches.v10_0.item_barcode_childtable_migrate # 16-02-2019
|
||||
erpnext.patches.v10_0.item_barcode_childtable_migrate # 16-02-2019 #25-06-2019
|
||||
erpnext.patches.v11_0.make_italian_localization_fields # 26-03-2019
|
||||
erpnext.patches.v11_1.make_job_card_time_logs
|
||||
erpnext.patches.v11_1.set_variant_based_on
|
||||
@@ -601,4 +601,5 @@ execute:frappe.delete_doc("Report", "Inactive Items")
|
||||
erpnext.patches.v11_1.delete_scheduling_tool
|
||||
erpnext.patches.v11_1.update_bank_transaction_status
|
||||
erpnext.patches.v11_1.renamed_delayed_item_report
|
||||
erpnext.patches.v11_1.set_missing_opportunity_from
|
||||
erpnext.patches.v11_1.set_missing_opportunity_from
|
||||
erpnext.patches.v11_1.set_quotation_status
|
||||
@@ -8,8 +8,10 @@ import frappe
|
||||
|
||||
def execute():
|
||||
frappe.reload_doc("stock", "doctype", "item_barcode")
|
||||
if frappe.get_all("Item Barcode", limit=1): return
|
||||
if "barcode" not in frappe.db.get_table_columns("Item"): return
|
||||
|
||||
items_barcode = frappe.get_all('Item', ['name', 'barcode'], { 'barcode': ('!=', '') })
|
||||
items_barcode = frappe.db.sql("select name, barcode from tabItem where barcode is not null", as_dict=True)
|
||||
frappe.reload_doc("stock", "doctype", "item")
|
||||
|
||||
|
||||
|
||||
7
erpnext/patches/v11_1/set_quotation_status.py
Normal file
7
erpnext/patches/v11_1/set_quotation_status.py
Normal file
@@ -0,0 +1,7 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
def execute():
|
||||
|
||||
frappe.db.sql(""" UPDATE `tabQuotation` set status = 'Open'
|
||||
where docstatus = 1 and status = 'Submitted' """)
|
||||
@@ -41,7 +41,8 @@ $.extend(frappe.create_routes, {
|
||||
"Item Group": "Tree/Item Group",
|
||||
"Sales Person": "Tree/Sales Person",
|
||||
"Account": "Tree/Account",
|
||||
"Cost Center": "Tree/Cost Center"
|
||||
"Cost Center": "Tree/Cost Center",
|
||||
"Department": "Tree/Department",
|
||||
});
|
||||
|
||||
// preferred modules for breadcrumbs
|
||||
|
||||
@@ -1290,10 +1290,13 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
},
|
||||
callback: function(r) {
|
||||
if(!r.exc) {
|
||||
for (let tax of r.message) {
|
||||
me.frm.add_child("taxes", tax);
|
||||
me.frm.set_value("taxes", r.message);
|
||||
|
||||
if(me.frm.doc.shipping_rule) {
|
||||
me.frm.script_manager.trigger("shipping_rule");
|
||||
} else {
|
||||
me.calculate_taxes_and_totals();
|
||||
}
|
||||
me.calculate_taxes_and_totals();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -3096,7 +3096,7 @@
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "status",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "Draft\nSubmitted\nOrdered\nLost\nCancelled\nOpen\nReplied",
|
||||
"options": "Draft\nOpen\nReplied\nOrdered\nLost\nCancelled",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
@@ -3224,7 +3224,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 1,
|
||||
"menu_index": 0,
|
||||
"modified": "2019-05-11 19:26:50.735628",
|
||||
"modified": "2019-06-25 15:31:04.724730",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Quotation",
|
||||
|
||||
@@ -13,11 +13,11 @@ frappe.listview_settings['Quotation'] = {
|
||||
},
|
||||
|
||||
get_indicator: function(doc) {
|
||||
if(doc.status==="Submitted") {
|
||||
if(doc.status==="Open") {
|
||||
if (doc.valid_till && doc.valid_till < frappe.datetime.nowdate()) {
|
||||
return [__("Expired"), "darkgrey", "valid_till,<," + frappe.datetime.nowdate()];
|
||||
} else {
|
||||
return [__("Submitted"), "blue", "status,=,Submitted"];
|
||||
return [__("Open"), "orange", "status,=,Open"];
|
||||
}
|
||||
} else if(doc.status==="Ordered") {
|
||||
return [__("Ordered"), "green", "status,=,Ordered"];
|
||||
|
||||
@@ -133,7 +133,7 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
|
||||
|
||||
if (this.frm.has_perm("submit")) {
|
||||
// close
|
||||
if(flt(doc.per_delivered, 6) < 100 || flt(doc.per_billed) < 100) {
|
||||
if(flt(doc.per_delivered, 6) < 100 || flt(doc.per_billed, 6) < 100) {
|
||||
this.frm.add_custom_button(__('Close'),
|
||||
function() { me.close_sales_order() }, __("Status"))
|
||||
}
|
||||
|
||||
@@ -414,6 +414,8 @@ def get_returned_qty_map(delivery_note):
|
||||
@frappe.whitelist()
|
||||
def make_sales_invoice(source_name, target_doc=None):
|
||||
doc = frappe.get_doc('Delivery Note', source_name)
|
||||
|
||||
to_make_invoice_qty_map = {}
|
||||
returned_qty_map = get_returned_qty_map(source_name)
|
||||
invoiced_qty_map = get_invoiced_qty_map(source_name)
|
||||
|
||||
@@ -434,8 +436,7 @@ def make_sales_invoice(source_name, target_doc=None):
|
||||
target.update(get_fetch_values("Sales Invoice", 'company_address', target.company_address))
|
||||
|
||||
def update_item(source_doc, target_doc, source_parent):
|
||||
target_doc.qty, returned_qty = get_pending_qty(source_doc)
|
||||
returned_qty_map[source_doc.item_code] = returned_qty
|
||||
target_doc.qty = to_make_invoice_qty_map[source_doc.name]
|
||||
|
||||
if source_doc.serial_no and source_parent.per_billed > 0:
|
||||
target_doc.serial_no = get_delivery_note_serial_no(source_doc.item_code,
|
||||
@@ -443,7 +444,12 @@ def make_sales_invoice(source_name, target_doc=None):
|
||||
|
||||
def get_pending_qty(item_row):
|
||||
pending_qty = item_row.qty - invoiced_qty_map.get(item_row.name, 0)
|
||||
returned_qty = flt(returned_qty_map.get(item_row.item_code, 0))
|
||||
|
||||
returned_qty = 0
|
||||
if returned_qty_map.get(item_row.item_code, 0) > 0:
|
||||
returned_qty = flt(returned_qty_map.get(item_row.item_code, 0))
|
||||
returned_qty_map[item_row.item_code] -= pending_qty
|
||||
|
||||
if returned_qty:
|
||||
if returned_qty >= pending_qty:
|
||||
pending_qty = 0
|
||||
@@ -451,7 +457,10 @@ def make_sales_invoice(source_name, target_doc=None):
|
||||
else:
|
||||
pending_qty -= returned_qty
|
||||
returned_qty = 0
|
||||
return pending_qty, returned_qty
|
||||
|
||||
to_make_invoice_qty_map[item_row.name] = pending_qty
|
||||
|
||||
return pending_qty
|
||||
|
||||
doc = get_mapped_doc("Delivery Note", source_name, {
|
||||
"Delivery Note": {
|
||||
@@ -471,7 +480,7 @@ def make_sales_invoice(source_name, target_doc=None):
|
||||
"cost_center": "cost_center"
|
||||
},
|
||||
"postprocess": update_item,
|
||||
"filter": lambda d: get_pending_qty(d)[0] <= 0 if not doc.get("is_return") else get_pending_qty(d)[0] > 0
|
||||
"filter": lambda d: get_pending_qty(d) <= 0 if not doc.get("is_return") else get_pending_qty(d) > 0
|
||||
},
|
||||
"Sales Taxes and Charges": {
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
|
||||
Reference in New Issue
Block a user