mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-25 07:54:46 +00:00
Merge branch 'develop' into qi-ux
This commit is contained in:
@@ -75,62 +75,70 @@ frappe.query_reports["Purchase Analytics"] = {
|
|||||||
return Object.assign(options, {
|
return Object.assign(options, {
|
||||||
checkboxColumn: true,
|
checkboxColumn: true,
|
||||||
events: {
|
events: {
|
||||||
onCheckRow: function(data) {
|
onCheckRow: function (data) {
|
||||||
|
if (!data) return;
|
||||||
|
|
||||||
|
const data_doctype = $(
|
||||||
|
data[2].html
|
||||||
|
)[0].attributes.getNamedItem("data-doctype").value;
|
||||||
|
const tree_type = frappe.query_report.filters[0].value;
|
||||||
|
if (data_doctype != tree_type) return;
|
||||||
|
|
||||||
row_name = data[2].content;
|
row_name = data[2].content;
|
||||||
length = data.length;
|
length = data.length;
|
||||||
|
|
||||||
var tree_type = frappe.query_report.filters[0].value;
|
if (tree_type == "Supplier") {
|
||||||
|
row_values = data
|
||||||
if(tree_type == "Supplier" || tree_type == "Item") {
|
.slice(4, length - 1)
|
||||||
row_values = data.slice(4,length-1).map(function (column) {
|
.map(function (column) {
|
||||||
return column.content;
|
return column.content;
|
||||||
})
|
});
|
||||||
}
|
} else if (tree_type == "Item") {
|
||||||
else {
|
row_values = data
|
||||||
row_values = data.slice(3,length-1).map(function (column) {
|
.slice(5, length - 1)
|
||||||
return column.content;
|
.map(function (column) {
|
||||||
})
|
return column.content;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
row_values = data
|
||||||
|
.slice(3, length - 1)
|
||||||
|
.map(function (column) {
|
||||||
|
return column.content;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
entry = {
|
entry = {
|
||||||
'name':row_name,
|
name: row_name,
|
||||||
'values':row_values
|
values: row_values,
|
||||||
}
|
};
|
||||||
|
|
||||||
let raw_data = frappe.query_report.chart.data;
|
let raw_data = frappe.query_report.chart.data;
|
||||||
let new_datasets = raw_data.datasets;
|
let new_datasets = raw_data.datasets;
|
||||||
|
|
||||||
var found = false;
|
let element_found = new_datasets.some((element, index, array)=>{
|
||||||
|
if(element.name == row_name){
|
||||||
for(var i=0; i < new_datasets.length;i++){
|
array.splice(index, 1)
|
||||||
if(new_datasets[i].name == row_name){
|
return true
|
||||||
found = true;
|
|
||||||
new_datasets.splice(i,1);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
return false
|
||||||
|
})
|
||||||
|
|
||||||
if(!found){
|
if (!element_found) {
|
||||||
new_datasets.push(entry);
|
new_datasets.push(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
let new_data = {
|
let new_data = {
|
||||||
labels: raw_data.labels,
|
labels: raw_data.labels,
|
||||||
datasets: new_datasets
|
datasets: new_datasets,
|
||||||
}
|
};
|
||||||
|
chart_options = {
|
||||||
setTimeout(() => {
|
data: new_data,
|
||||||
frappe.query_report.chart.update(new_data)
|
type: "line",
|
||||||
},500)
|
};
|
||||||
|
frappe.query_report.render_chart(chart_options);
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
frappe.query_report.chart.draw(true);
|
|
||||||
}, 1000)
|
|
||||||
|
|
||||||
frappe.query_report.raw_chart_data = new_data;
|
frappe.query_report.raw_chart_data = new_data;
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -328,6 +328,7 @@ def make_return_doc(doctype, source_name, target_doc=None):
|
|||||||
target_doc.po_detail = source_doc.po_detail
|
target_doc.po_detail = source_doc.po_detail
|
||||||
target_doc.pr_detail = source_doc.pr_detail
|
target_doc.pr_detail = source_doc.pr_detail
|
||||||
target_doc.purchase_invoice_item = source_doc.name
|
target_doc.purchase_invoice_item = source_doc.name
|
||||||
|
target_doc.price_list_rate = 0
|
||||||
|
|
||||||
elif doctype == "Delivery Note":
|
elif doctype == "Delivery Note":
|
||||||
returned_qty_map = get_returned_qty_map_for_row(source_doc.name, doctype)
|
returned_qty_map = get_returned_qty_map_for_row(source_doc.name, doctype)
|
||||||
@@ -353,6 +354,7 @@ def make_return_doc(doctype, source_name, target_doc=None):
|
|||||||
target_doc.dn_detail = source_doc.dn_detail
|
target_doc.dn_detail = source_doc.dn_detail
|
||||||
target_doc.expense_account = source_doc.expense_account
|
target_doc.expense_account = source_doc.expense_account
|
||||||
target_doc.sales_invoice_item = source_doc.name
|
target_doc.sales_invoice_item = source_doc.name
|
||||||
|
target_doc.price_list_rate = 0
|
||||||
if default_warehouse_for_sales_return:
|
if default_warehouse_for_sales_return:
|
||||||
target_doc.warehouse = default_warehouse_for_sales_return
|
target_doc.warehouse = default_warehouse_for_sales_return
|
||||||
|
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ class SellingController(StockController):
|
|||||||
'allow_zero_valuation': d.allow_zero_valuation_rate,
|
'allow_zero_valuation': d.allow_zero_valuation_rate,
|
||||||
'sales_invoice_item': d.get("sales_invoice_item"),
|
'sales_invoice_item': d.get("sales_invoice_item"),
|
||||||
'dn_detail': d.get("dn_detail"),
|
'dn_detail': d.get("dn_detail"),
|
||||||
'incoming_rate': p.incoming_rate
|
'incoming_rate': p.get("incoming_rate")
|
||||||
}))
|
}))
|
||||||
else:
|
else:
|
||||||
il.append(frappe._dict({
|
il.append(frappe._dict({
|
||||||
@@ -252,7 +252,7 @@ class SellingController(StockController):
|
|||||||
'allow_zero_valuation': d.allow_zero_valuation_rate,
|
'allow_zero_valuation': d.allow_zero_valuation_rate,
|
||||||
'sales_invoice_item': d.get("sales_invoice_item"),
|
'sales_invoice_item': d.get("sales_invoice_item"),
|
||||||
'dn_detail': d.get("dn_detail"),
|
'dn_detail': d.get("dn_detail"),
|
||||||
'incoming_rate': d.incoming_rate
|
'incoming_rate': d.get("incoming_rate")
|
||||||
}))
|
}))
|
||||||
return il
|
return il
|
||||||
|
|
||||||
|
|||||||
@@ -543,6 +543,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
company: me.frm.doc.company,
|
company: me.frm.doc.company,
|
||||||
order_type: me.frm.doc.order_type,
|
order_type: me.frm.doc.order_type,
|
||||||
is_pos: cint(me.frm.doc.is_pos),
|
is_pos: cint(me.frm.doc.is_pos),
|
||||||
|
is_return: cint(me.frm.doc.is_return),
|
||||||
is_subcontracted: me.frm.doc.is_subcontracted,
|
is_subcontracted: me.frm.doc.is_subcontracted,
|
||||||
transaction_date: me.frm.doc.transaction_date || me.frm.doc.posting_date,
|
transaction_date: me.frm.doc.transaction_date || me.frm.doc.posting_date,
|
||||||
ignore_pricing_rule: me.frm.doc.ignore_pricing_rule,
|
ignore_pricing_rule: me.frm.doc.ignore_pricing_rule,
|
||||||
|
|||||||
@@ -92,21 +92,18 @@ def get_party_details(address_name):
|
|||||||
location = gstin_details.get('AddrLoc') or address.get('city')
|
location = gstin_details.get('AddrLoc') or address.get('city')
|
||||||
state_code = gstin_details.get('StateCode')
|
state_code = gstin_details.get('StateCode')
|
||||||
pincode = gstin_details.get('AddrPncd')
|
pincode = gstin_details.get('AddrPncd')
|
||||||
address_line1 = '{} {}'.format(gstin_details.get('AddrBno'), gstin_details.get('AddrFlno'))
|
address_line1 = '{} {}'.format(gstin_details.get('AddrBno') or "", gstin_details.get('AddrFlno') or "")
|
||||||
address_line2 = '{} {}'.format(gstin_details.get('AddrBnm'), gstin_details.get('AddrSt'))
|
address_line2 = '{} {}'.format(gstin_details.get('AddrBnm') or "", gstin_details.get('AddrSt') or "")
|
||||||
email_id = address.get('email_id')
|
|
||||||
phone = address.get('phone')
|
|
||||||
# get last 10 digit
|
|
||||||
phone = phone.replace(" ", "")[-10:] if phone else ''
|
|
||||||
|
|
||||||
if state_code == 97:
|
if state_code == 97:
|
||||||
# according to einvoice standard
|
# according to einvoice standard
|
||||||
pincode = 999999
|
pincode = 999999
|
||||||
|
|
||||||
return frappe._dict(dict(
|
return frappe._dict(dict(
|
||||||
gstin=gstin, legal_name=legal_name, location=location,
|
gstin=gstin, legal_name=legal_name,
|
||||||
pincode=pincode, state_code=state_code, address_line1=address_line1,
|
location=location, pincode=pincode,
|
||||||
address_line2=address_line2, email=email_id, phone=phone
|
state_code=state_code, address_line1=address_line1,
|
||||||
|
address_line2=address_line2
|
||||||
))
|
))
|
||||||
|
|
||||||
def get_gstin_details(gstin):
|
def get_gstin_details(gstin):
|
||||||
@@ -146,9 +143,10 @@ def get_item_list(invoice):
|
|||||||
item.update(d.as_dict())
|
item.update(d.as_dict())
|
||||||
|
|
||||||
item.sr_no = d.idx
|
item.sr_no = d.idx
|
||||||
item.discount_amount = abs(item.discount_amount * item.qty)
|
item.description = d.item_name.replace('"', '\\"')
|
||||||
item.description = d.item_name
|
|
||||||
item.qty = abs(item.qty)
|
item.qty = abs(item.qty)
|
||||||
|
item.discount_amount = abs(item.discount_amount * item.qty)
|
||||||
item.unit_rate = abs(item.base_amount / item.qty)
|
item.unit_rate = abs(item.base_amount / item.qty)
|
||||||
item.gross_amount = abs(item.base_amount)
|
item.gross_amount = abs(item.base_amount)
|
||||||
item.taxable_value = abs(item.base_amount)
|
item.taxable_value = abs(item.base_amount)
|
||||||
@@ -156,6 +154,7 @@ def get_item_list(invoice):
|
|||||||
item.batch_expiry_date = frappe.db.get_value('Batch', d.batch_no, 'expiry_date') if d.batch_no else None
|
item.batch_expiry_date = frappe.db.get_value('Batch', d.batch_no, 'expiry_date') if d.batch_no else None
|
||||||
item.batch_expiry_date = format_date(item.batch_expiry_date, 'dd/mm/yyyy') if item.batch_expiry_date else None
|
item.batch_expiry_date = format_date(item.batch_expiry_date, 'dd/mm/yyyy') if item.batch_expiry_date else None
|
||||||
item.is_service_item = 'N' if frappe.db.get_value('Item', d.item_code, 'is_stock_item') else 'Y'
|
item.is_service_item = 'N' if frappe.db.get_value('Item', d.item_code, 'is_stock_item') else 'Y'
|
||||||
|
item.serial_no = ""
|
||||||
|
|
||||||
item = update_item_taxes(invoice, item)
|
item = update_item_taxes(invoice, item)
|
||||||
|
|
||||||
@@ -272,7 +271,25 @@ def get_eway_bill_details(invoice):
|
|||||||
vehicle_type=vehicle_type[invoice.gst_vehicle_type]
|
vehicle_type=vehicle_type[invoice.gst_vehicle_type]
|
||||||
))
|
))
|
||||||
|
|
||||||
|
def validate_mandatory_fields(invoice):
|
||||||
|
if not invoice.company_address:
|
||||||
|
frappe.throw(_('Company Address is mandatory to fetch company GSTIN details.'), title=_('Missing Fields'))
|
||||||
|
if not invoice.customer_address:
|
||||||
|
frappe.throw(_('Customer Address is mandatory to fetch customer GSTIN details.'), title=_('Missing Fields'))
|
||||||
|
if not frappe.db.get_value('Address', invoice.company_address, 'gstin'):
|
||||||
|
frappe.throw(
|
||||||
|
_('GSTIN is mandatory to fetch company GSTIN details. Please enter GSTIN in selected company address.'),
|
||||||
|
title=_('Missing Fields')
|
||||||
|
)
|
||||||
|
if not frappe.db.get_value('Address', invoice.customer_address, 'gstin'):
|
||||||
|
frappe.throw(
|
||||||
|
_('GSTIN is mandatory to fetch customer GSTIN details. Please enter GSTIN in selected customer address.'),
|
||||||
|
title=_('Missing Fields')
|
||||||
|
)
|
||||||
|
|
||||||
def make_einvoice(invoice):
|
def make_einvoice(invoice):
|
||||||
|
validate_mandatory_fields(invoice)
|
||||||
|
|
||||||
schema = read_json('einv_template')
|
schema = read_json('einv_template')
|
||||||
|
|
||||||
transaction_details = get_transaction_details(invoice)
|
transaction_details = get_transaction_details(invoice)
|
||||||
@@ -351,7 +368,7 @@ def validate_einvoice(validations, einvoice, errors=[]):
|
|||||||
# remove empty dicts
|
# remove empty dicts
|
||||||
einvoice.pop(fieldname, None)
|
einvoice.pop(fieldname, None)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# convert to int or str
|
# convert to int or str
|
||||||
if value_type == 'string':
|
if value_type == 'string':
|
||||||
einvoice[fieldname] = str(value)
|
einvoice[fieldname] = str(value)
|
||||||
|
|||||||
@@ -74,67 +74,71 @@ frappe.query_reports["Sales Analytics"] = {
|
|||||||
return Object.assign(options, {
|
return Object.assign(options, {
|
||||||
checkboxColumn: true,
|
checkboxColumn: true,
|
||||||
events: {
|
events: {
|
||||||
onCheckRow: function(data) {
|
onCheckRow: function (data) {
|
||||||
|
if (!data) return;
|
||||||
|
const data_doctype = $(
|
||||||
|
data[2].html
|
||||||
|
)[0].attributes.getNamedItem("data-doctype").value;
|
||||||
|
const tree_type = frappe.query_report.filters[0].value;
|
||||||
|
if (data_doctype != tree_type) return;
|
||||||
|
|
||||||
row_name = data[2].content;
|
row_name = data[2].content;
|
||||||
length = data.length;
|
length = data.length;
|
||||||
|
|
||||||
var tree_type = frappe.query_report.filters[0].value;
|
if (tree_type == "Customer") {
|
||||||
|
row_values = data
|
||||||
if(tree_type == "Customer") {
|
.slice(4, length - 1)
|
||||||
row_values = data.slice(4,length-1).map(function (column) {
|
.map(function (column) {
|
||||||
return column.content;
|
return column.content;
|
||||||
})
|
});
|
||||||
} else if (tree_type == "Item") {
|
} else if (tree_type == "Item") {
|
||||||
row_values = data.slice(5,length-1).map(function (column) {
|
row_values = data
|
||||||
return column.content;
|
.slice(5, length - 1)
|
||||||
})
|
.map(function (column) {
|
||||||
}
|
return column.content;
|
||||||
else {
|
});
|
||||||
row_values = data.slice(3,length-1).map(function (column) {
|
} else {
|
||||||
return column.content;
|
row_values = data
|
||||||
})
|
.slice(3, length - 1)
|
||||||
|
.map(function (column) {
|
||||||
|
return column.content;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
entry = {
|
entry = {
|
||||||
'name':row_name,
|
name: row_name,
|
||||||
'values':row_values
|
values: row_values,
|
||||||
}
|
};
|
||||||
|
|
||||||
let raw_data = frappe.query_report.chart.data;
|
let raw_data = frappe.query_report.chart.data;
|
||||||
let new_datasets = raw_data.datasets;
|
let new_datasets = raw_data.datasets;
|
||||||
|
|
||||||
var found = false;
|
let element_found = new_datasets.some((element, index, array)=>{
|
||||||
|
if(element.name == row_name){
|
||||||
for(var i=0; i < new_datasets.length;i++){
|
array.splice(index, 1)
|
||||||
if(new_datasets[i].name == row_name){
|
return true
|
||||||
found = true;
|
|
||||||
new_datasets.splice(i,1);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
return false
|
||||||
|
})
|
||||||
|
|
||||||
if(!found){
|
if (!element_found) {
|
||||||
new_datasets.push(entry);
|
new_datasets.push(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
let new_data = {
|
let new_data = {
|
||||||
labels: raw_data.labels,
|
labels: raw_data.labels,
|
||||||
datasets: new_datasets
|
datasets: new_datasets,
|
||||||
}
|
};
|
||||||
|
chart_options = {
|
||||||
setTimeout(() => {
|
data: new_data,
|
||||||
frappe.query_report.chart.update(new_data)
|
type: "line",
|
||||||
}, 500)
|
};
|
||||||
|
frappe.query_report.render_chart(chart_options);
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
frappe.query_report.chart.draw(true);
|
|
||||||
}, 1000)
|
|
||||||
|
|
||||||
frappe.query_report.raw_chart_data = new_data;
|
frappe.query_report.raw_chart_data = new_data;
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,9 @@ def get_item_details(args, doc=None, for_validate=False, overwrite_warehouse=Tru
|
|||||||
|
|
||||||
update_party_blanket_order(args, out)
|
update_party_blanket_order(args, out)
|
||||||
|
|
||||||
get_price_list_rate(args, item, out)
|
if not doc or cint(doc.get('is_return')) == 0:
|
||||||
|
# get price list rate only if the invoice is not a credit or debit note
|
||||||
|
get_price_list_rate(args, item, out)
|
||||||
|
|
||||||
if args.customer and cint(args.is_pos):
|
if args.customer and cint(args.is_pos):
|
||||||
out.update(get_pos_profile_item_details(args.company, args))
|
out.update(get_pos_profile_item_details(args.company, args))
|
||||||
|
|||||||
Reference in New Issue
Block a user