Merge remote-tracking branch 'upstream/develop' into add-age-range-in-stock-ageing

Merge remote-tracking branch 'upstream/develop' into add-age-range-in-stock-ageing
This commit is contained in:
Afshan
2020-07-13 11:45:33 +05:30
25 changed files with 211 additions and 234 deletions

View File

@@ -2,6 +2,7 @@
{ {
"doctype": "Item Tax Template", "doctype": "Item Tax Template",
"title": "_Test Account Excise Duty @ 10", "title": "_Test Account Excise Duty @ 10",
"company": "_Test Company",
"taxes": [ "taxes": [
{ {
"doctype": "Item Tax Template Detail", "doctype": "Item Tax Template Detail",
@@ -14,6 +15,7 @@
{ {
"doctype": "Item Tax Template", "doctype": "Item Tax Template",
"title": "_Test Account Excise Duty @ 12", "title": "_Test Account Excise Duty @ 12",
"company": "_Test Company",
"taxes": [ "taxes": [
{ {
"doctype": "Item Tax Template Detail", "doctype": "Item Tax Template Detail",
@@ -26,6 +28,7 @@
{ {
"doctype": "Item Tax Template", "doctype": "Item Tax Template",
"title": "_Test Account Excise Duty @ 15", "title": "_Test Account Excise Duty @ 15",
"company": "_Test Company",
"taxes": [ "taxes": [
{ {
"doctype": "Item Tax Template Detail", "doctype": "Item Tax Template Detail",
@@ -38,6 +41,7 @@
{ {
"doctype": "Item Tax Template", "doctype": "Item Tax Template",
"title": "_Test Account Excise Duty @ 20", "title": "_Test Account Excise Duty @ 20",
"company": "_Test Company",
"taxes": [ "taxes": [
{ {
"doctype": "Item Tax Template Detail", "doctype": "Item Tax Template Detail",
@@ -50,6 +54,7 @@
{ {
"doctype": "Item Tax Template", "doctype": "Item Tax Template",
"title": "_Test Item Tax Template 1", "title": "_Test Item Tax Template 1",
"company": "_Test Company",
"taxes": [ "taxes": [
{ {
"doctype": "Item Tax Template Detail", "doctype": "Item Tax Template Detail",

View File

@@ -319,7 +319,9 @@ def apply_internal_priority(pricing_rules, field_set, args):
filtered_rules = [] filtered_rules = []
for field in field_set: for field in field_set:
if args.get(field): if args.get(field):
filtered_rules = filter(lambda x: x[field]==args[field], pricing_rules) # filter function always returns a filter object even if empty
# list conversion is necessary to check for an empty result
filtered_rules = list(filter(lambda x: x.get(field)==args.get(field), pricing_rules))
if filtered_rules: break if filtered_rules: break
return filtered_rules or pricing_rules return filtered_rules or pricing_rules

View File

@@ -17,41 +17,6 @@ frappe.query_reports["Accounts Payable"] = {
"fieldtype": "Date", "fieldtype": "Date",
"default": frappe.datetime.get_today() "default": frappe.datetime.get_today()
}, },
{
"fieldname":"ageing_based_on",
"label": __("Ageing Based On"),
"fieldtype": "Select",
"options": 'Posting Date\nDue Date\nSupplier Invoice Date',
"default": "Due Date"
},
{
"fieldname":"range1",
"label": __("Ageing Range 1"),
"fieldtype": "Int",
"default": "30",
"reqd": 1
},
{
"fieldname":"range2",
"label": __("Ageing Range 2"),
"fieldtype": "Int",
"default": "60",
"reqd": 1
},
{
"fieldname":"range3",
"label": __("Ageing Range 3"),
"fieldtype": "Int",
"default": "90",
"reqd": 1
},
{
"fieldname":"range4",
"label": __("Ageing Range 4"),
"fieldtype": "Int",
"default": "120",
"reqd": 1
},
{ {
"fieldname":"finance_book", "fieldname":"finance_book",
"label": __("Finance Book"), "label": __("Finance Book"),
@@ -88,6 +53,41 @@ frappe.query_reports["Accounts Payable"] = {
} }
} }
}, },
{
"fieldname":"ageing_based_on",
"label": __("Ageing Based On"),
"fieldtype": "Select",
"options": 'Posting Date\nDue Date\nSupplier Invoice Date',
"default": "Due Date"
},
{
"fieldname":"range1",
"label": __("Ageing Range 1"),
"fieldtype": "Int",
"default": "30",
"reqd": 1
},
{
"fieldname":"range2",
"label": __("Ageing Range 2"),
"fieldtype": "Int",
"default": "60",
"reqd": 1
},
{
"fieldname":"range3",
"label": __("Ageing Range 3"),
"fieldtype": "Int",
"default": "90",
"reqd": 1
},
{
"fieldname":"range4",
"label": __("Ageing Range 4"),
"fieldtype": "Int",
"default": "120",
"reqd": 1
},
{ {
"fieldname":"payment_terms_template", "fieldname":"payment_terms_template",
"label": __("Payment Terms Template"), "label": __("Payment Terms Template"),

View File

@@ -17,41 +17,6 @@ frappe.query_reports["Accounts Receivable"] = {
"fieldtype": "Date", "fieldtype": "Date",
"default": frappe.datetime.get_today() "default": frappe.datetime.get_today()
}, },
{
"fieldname":"ageing_based_on",
"label": __("Ageing Based On"),
"fieldtype": "Select",
"options": 'Posting Date\nDue Date',
"default": "Due Date"
},
{
"fieldname":"range1",
"label": __("Ageing Range 1"),
"fieldtype": "Int",
"default": "30",
"reqd": 1
},
{
"fieldname":"range2",
"label": __("Ageing Range 2"),
"fieldtype": "Int",
"default": "60",
"reqd": 1
},
{
"fieldname":"range3",
"label": __("Ageing Range 3"),
"fieldtype": "Int",
"default": "90",
"reqd": 1
},
{
"fieldname":"range4",
"label": __("Ageing Range 4"),
"fieldtype": "Int",
"default": "120",
"reqd": 1
},
{ {
"fieldname":"finance_book", "fieldname":"finance_book",
"label": __("Finance Book"), "label": __("Finance Book"),
@@ -101,6 +66,41 @@ frappe.query_reports["Accounts Receivable"] = {
} }
} }
}, },
{
"fieldname":"ageing_based_on",
"label": __("Ageing Based On"),
"fieldtype": "Select",
"options": 'Posting Date\nDue Date',
"default": "Due Date"
},
{
"fieldname":"range1",
"label": __("Ageing Range 1"),
"fieldtype": "Int",
"default": "30",
"reqd": 1
},
{
"fieldname":"range2",
"label": __("Ageing Range 2"),
"fieldtype": "Int",
"default": "60",
"reqd": 1
},
{
"fieldname":"range3",
"label": __("Ageing Range 3"),
"fieldtype": "Int",
"default": "90",
"reqd": 1
},
{
"fieldname":"range4",
"label": __("Ageing Range 4"),
"fieldtype": "Int",
"default": "120",
"reqd": 1
},
{ {
"fieldname":"customer_group", "fieldname":"customer_group",
"label": __("Customer Group"), "label": __("Customer Group"),
@@ -113,12 +113,6 @@ frappe.query_reports["Accounts Receivable"] = {
"fieldtype": "Link", "fieldtype": "Link",
"options": "Payment Terms Template" "options": "Payment Terms Template"
}, },
{
"fieldname":"territory",
"label": __("Territory"),
"fieldtype": "Link",
"options": "Territory"
},
{ {
"fieldname":"sales_partner", "fieldname":"sales_partner",
"label": __("Sales Partner"), "label": __("Sales Partner"),
@@ -131,6 +125,12 @@ frappe.query_reports["Accounts Receivable"] = {
"fieldtype": "Link", "fieldtype": "Link",
"options": "Sales Person" "options": "Sales Person"
}, },
{
"fieldname":"territory",
"label": __("Territory"),
"fieldtype": "Link",
"options": "Territory"
},
{ {
"fieldname": "group_by_party", "fieldname": "group_by_party",
"label": __("Group By Customer"), "label": __("Group By Customer"),

View File

@@ -405,12 +405,12 @@ def set_gl_entries_by_account(
FROM `tabDistributed Cost Center` FROM `tabDistributed Cost Center`
WHERE cost_center IN %(cost_center)s WHERE cost_center IN %(cost_center)s
AND parent NOT IN %(cost_center)s AND parent NOT IN %(cost_center)s
AND is_cancelled = 0
GROUP BY parent GROUP BY parent
) as DCC_allocation ) as DCC_allocation
WHERE company=%(company)s WHERE company=%(company)s
{additional_conditions} {additional_conditions}
AND posting_date <= %(to_date)s AND posting_date <= %(to_date)s
AND is_cancelled = 0
AND cost_center = DCC_allocation.parent AND cost_center = DCC_allocation.parent
""".format(additional_conditions=additional_conditions.replace("and cost_center in %(cost_center)s ", '')) """.format(additional_conditions=additional_conditions.replace("and cost_center in %(cost_center)s ", ''))

View File

@@ -123,14 +123,14 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
} }
if(doc.status != "Closed") { if(doc.status != "Closed") {
if (doc.status != "On Hold") { if (doc.status != "On Hold") {
if(flt(doc.per_received, 2) < 100 && allow_receipt) { if(flt(doc.per_received) < 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" && me.has_unsupplied_items()) { 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"));
} }
} }
if(flt(doc.per_billed, 2) < 100) if(flt(doc.per_billed) < 100)
cur_frm.add_custom_button(__('Invoice'), cur_frm.add_custom_button(__('Invoice'),
this.make_purchase_invoice, __('Create')); this.make_purchase_invoice, __('Create'));

View File

@@ -1,4 +1,5 @@
{ {
"actions": "",
"allow_import": 1, "allow_import": 1,
"autoname": "naming_series:", "autoname": "naming_series:",
"creation": "2016-02-25 01:24:07.224790", "creation": "2016-02-25 01:24:07.224790",
@@ -28,7 +29,6 @@
"letter_head", "letter_head",
"more_info", "more_info",
"status", "status",
"fiscal_year",
"column_break3", "column_break3",
"amended_from" "amended_from"
], ],
@@ -218,17 +218,6 @@
"reqd": 1, "reqd": 1,
"search_index": 1 "search_index": 1
}, },
{
"fieldname": "fiscal_year",
"fieldtype": "Link",
"label": "Fiscal Year",
"oldfieldname": "fiscal_year",
"oldfieldtype": "Select",
"options": "Fiscal Year",
"print_hide": 1,
"reqd": 1,
"search_index": 1
},
{ {
"fieldname": "column_break3", "fieldname": "column_break3",
"fieldtype": "Column Break" "fieldtype": "Column Break"
@@ -245,7 +234,8 @@
], ],
"icon": "fa fa-shopping-cart", "icon": "fa fa-shopping-cart",
"is_submittable": 1, "is_submittable": 1,
"modified": "2019-09-24 15:08:32.750661", "links": [],
"modified": "2020-06-25 14:37:21.140194",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Buying", "module": "Buying",
"name": "Request for Quotation", "name": "Request for Quotation",

View File

@@ -13,14 +13,12 @@ class TestMapper(unittest.TestCase):
'''Test mapping of multiple source docs on a single target doc''' '''Test mapping of multiple source docs on a single target doc'''
make_test_records("Item") make_test_records("Item")
items = frappe.get_all("Item", fields = ["name", "item_code"], filters = {'is_sales_item': 1, 'has_variants': 0, 'disabled': 0}) items = ['_Test Item', '_Test Item 2', '_Test FG Item']
customers = frappe.get_all("Customer")
if items and customers: # Make source docs (quotations) and a target doc (sales order)
# Make source docs (quotations) and a target doc (sales order) qtn1, item_list_1 = self.make_quotation(items, '_Test Customer')
customer = random.choice(customers).name qtn2, item_list_2 = self.make_quotation(items, '_Test Customer')
qtn1, item_list_1 = self.make_quotation(items, customer) so, item_list_3 = self.make_sales_order()
qtn2, item_list_2 = self.make_quotation(items, customer)
so, item_list_3 = self.make_sales_order()
# Map source docs to target with corresponding mapper method # Map source docs to target with corresponding mapper method
method = "erpnext.selling.doctype.quotation.quotation.make_sales_order" method = "erpnext.selling.doctype.quotation.quotation.make_sales_order"
@@ -28,18 +26,12 @@ class TestMapper(unittest.TestCase):
# Assert that all inserted items are present in updated sales order # Assert that all inserted items are present in updated sales order
src_items = item_list_1 + item_list_2 + item_list_3 src_items = item_list_1 + item_list_2 + item_list_3
self.assertEqual(set([d.item_code for d in src_items]), self.assertEqual(set([d for d in src_items]),
set([d.item_code for d in updated_so.items])) set([d.item_code for d in updated_so.items]))
def get_random_items(self, items, limit):
'''Get a number of random items from a list of given items'''
random_items = []
for i in range(0, limit):
random_items.append(random.choice(items))
return random_items
def make_quotation(self, items, customer): def make_quotation(self, item_list, customer):
item_list = self.get_random_items(items, 3)
qtn = frappe.get_doc({ qtn = frappe.get_doc({
"doctype": "Quotation", "doctype": "Quotation",
"quotation_to": "Customer", "quotation_to": "Customer",
@@ -49,7 +41,7 @@ class TestMapper(unittest.TestCase):
"valid_till" : add_months(nowdate(), 1) "valid_till" : add_months(nowdate(), 1)
}) })
for item in item_list: for item in item_list:
qtn.append("items", {"qty": "2", "item_code": item.item_code}) qtn.append("items", {"qty": "2", "item_code": item})
qtn.submit() qtn.submit()
return qtn, item_list return qtn, item_list
@@ -60,7 +52,7 @@ class TestMapper(unittest.TestCase):
"base_rate": 100.0, "base_rate": 100.0,
"description": "CPU", "description": "CPU",
"doctype": "Sales Order Item", "doctype": "Sales Order Item",
"item_code": "_Test Item Home Desktop 100", "item_code": "_Test Item",
"item_name": "CPU", "item_name": "CPU",
"parentfield": "items", "parentfield": "items",
"qty": 10.0, "qty": 10.0,
@@ -72,4 +64,4 @@ class TestMapper(unittest.TestCase):
}) })
so = frappe.get_doc(frappe.get_test_records('Sales Order')[0]) so = frappe.get_doc(frappe.get_test_records('Sales Order')[0])
so.insert(ignore_permissions=True) so.insert(ignore_permissions=True)
return so, [item] return so, [item.item_code]

View File

@@ -30,6 +30,7 @@ class TestTaxes(unittest.TestCase):
self.item_tax_template = frappe.get_doc({ self.item_tax_template = frappe.get_doc({
'doctype': 'Item Tax Template', 'doctype': 'Item Tax Template',
'title': uuid4(), 'title': uuid4(),
'company': self.company.name,
'taxes': [ 'taxes': [
{ {
'tax_type': self.account.name, 'tax_type': self.account.name,

View File

@@ -73,7 +73,7 @@ def update_encounter_medical_record(encounter):
insert_encounter_to_medical_record(encounter) insert_encounter_to_medical_record(encounter)
def delete_medical_record(encounter): def delete_medical_record(encounter):
frappe.db.delete_doc_if_exists('Patient Medical Record', 'reference_name', encounter.name) frappe.delete_doc_if_exists('Patient Medical Record', 'reference_name', encounter.name)
def set_subject_field(encounter): def set_subject_field(encounter):
subject = frappe.bold(_('Healthcare Practitioner: ')) + encounter.practitioner + '<br>' subject = frappe.bold(_('Healthcare Practitioner: ')) + encounter.practitioner + '<br>'

View File

@@ -13,6 +13,7 @@ class EmployeeIncentive(Document):
additional_salary = frappe.new_doc('Additional Salary') additional_salary = frappe.new_doc('Additional Salary')
additional_salary.employee = self.employee additional_salary.employee = self.employee
additional_salary.salary_component = self.salary_component additional_salary.salary_component = self.salary_component
additional_salary.overwrite_salary_structure_amount = 0
additional_salary.amount = self.incentive_amount additional_salary.amount = self.incentive_amount
additional_salary.payroll_date = self.payroll_date additional_salary.payroll_date = self.payroll_date
additional_salary.company = company additional_salary.company = company

View File

@@ -26,6 +26,7 @@ class RetentionBonus(Document):
additional_salary.amount = self.bonus_amount additional_salary.amount = self.bonus_amount
additional_salary.payroll_date = self.bonus_payment_date additional_salary.payroll_date = self.bonus_payment_date
additional_salary.company = company additional_salary.company = company
additional_salary.overwrite_salary_structure_amount = 0
additional_salary.ref_doctype = self.doctype additional_salary.ref_doctype = self.doctype
additional_salary.ref_docname = self.name additional_salary.ref_docname = self.name
additional_salary.submit() additional_salary.submit()
@@ -53,7 +54,7 @@ class RetentionBonus(Document):
'employee': self.employee, 'employee': self.employee,
'salary_component': self.salary_component, 'salary_component': self.salary_component,
'payroll_date': self.bonus_payment_date, 'payroll_date': self.bonus_payment_date,
'company': company, 'company': self.company,
'docstatus': 1, 'docstatus': 1,
'ref_doctype': self.doctype, 'ref_doctype': self.doctype,
'ref_docname': self.name 'ref_docname': self.name

View File

@@ -3,55 +3,42 @@
frappe.provide("erpnext.projects"); frappe.provide("erpnext.projects");
cur_frm.add_fetch("project", "company", "company");
frappe.ui.form.on("Task", { frappe.ui.form.on("Task", {
onload: function(frm) { setup: function (frm) {
frm.set_query("task", "depends_on", function() { frm.set_query("project", function () {
var filters = { return {
query: "erpnext.projects.doctype.task.task.get_project"
}
});
frm.make_methods = {
'Timesheet': () => frappe.model.open_mapped_doc({
method: 'erpnext.projects.doctype.task.task.make_timesheet',
frm: frm
})
}
},
onload: function (frm) {
frm.set_query("task", "depends_on", function () {
let filters = {
name: ["!=", frm.doc.name] name: ["!=", frm.doc.name]
}; };
if(frm.doc.project) filters["project"] = frm.doc.project; if (frm.doc.project) filters["project"] = frm.doc.project;
return { return {
filters: filters filters: filters
}; };
}) })
},
refresh: function(frm) { frm.set_query("parent_task", function () {
frm.fields_dict['parent_task'].get_query = function () { let filters = {
"is_group": 1
};
if (frm.doc.project) filters["project"] = frm.doc.project;
return { return {
filters: { filters: filters
"is_group": 1,
}
} }
} });
if (!frm.doc.is_group) {
if (!frm.is_new()) {
if (frappe.model.can_read("Timesheet")) {
frm.add_custom_button(__("Timesheet"), () => {
frappe.route_options = { "project": frm.doc.project, "task": frm.doc.name }
frappe.set_route("List", "Timesheet");
}, __("View"), true);
}
if (frappe.model.can_read("Expense Claim")) {
frm.add_custom_button(__("Expense Claims"), () => {
frappe.route_options = { "project": frm.doc.project, "task": frm.doc.name };
frappe.set_route("List", "Expense Claim");
}, __("View"), true);
}
}
}
},
setup: function(frm) {
frm.fields_dict.project.get_query = function() {
return {
query: "erpnext.projects.doctype.task.task.get_project"
}
};
}, },
is_group: function (frm) { is_group: function (frm) {
@@ -69,12 +56,8 @@ frappe.ui.form.on("Task", {
}) })
}, },
validate: function(frm) { validate: function (frm) {
frm.doc.project && frappe.model.remove_from_locals("Project", frm.doc.project && frappe.model.remove_from_locals("Project",
frm.doc.project); frm.doc.project);
}, }
}); });
cur_frm.add_fetch('task', 'subject', 'subject');
cur_frm.add_fetch('task', 'project', 'project');

View File

@@ -325,6 +325,7 @@
"options": "Department" "options": "Department"
}, },
{ {
"fetch_from": "project.company",
"fieldname": "company", "fieldname": "company",
"fieldtype": "Link", "fieldtype": "Link",
"label": "Company", "label": "Company",

View File

@@ -7,10 +7,11 @@ import json
import frappe import frappe
from frappe import _, throw from frappe import _, throw
from frappe.desk.form.assign_to import clear, close_all_assignments
from frappe.model.mapper import get_mapped_doc
from frappe.utils import add_days, cstr, date_diff, get_link_to_form, getdate, today from frappe.utils import add_days, cstr, date_diff, get_link_to_form, getdate, today
from frappe.utils.nestedset import NestedSet from frappe.utils.nestedset import NestedSet
from frappe.desk.form.assign_to import close_all_assignments, clear
from frappe.utils import date_diff
class CircularReferenceError(frappe.ValidationError): pass class CircularReferenceError(frappe.ValidationError): pass
class EndDateCannotBeGreaterThanProjectEndDateError(frappe.ValidationError): pass class EndDateCannotBeGreaterThanProjectEndDateError(frappe.ValidationError): pass
@@ -220,6 +221,26 @@ def set_tasks_as_overdue():
continue continue
frappe.get_doc("Task", task.name).update_status() frappe.get_doc("Task", task.name).update_status()
@frappe.whitelist()
def make_timesheet(source_name, target_doc=None, ignore_permissions=False):
def set_missing_values(source, target):
target.append("time_logs", {
"hours": source.actual_time,
"completed": source.status == "Completed",
"project": source.project,
"task": source.name
})
doclist = get_mapped_doc("Task", source_name, {
"Task": {
"doctype": "Timesheet"
}
}, target_doc, postprocess=set_missing_values, ignore_permissions=ignore_permissions)
return doclist
@frappe.whitelist() @frappe.whitelist()
def get_children(doctype, parent, task=None, project=None, is_root=False): def get_children(doctype, parent, task=None, project=None, is_root=False):

View File

@@ -458,19 +458,23 @@ def generate_ewb_json(dt, dn):
@frappe.whitelist() @frappe.whitelist()
def download_ewb_json(): def download_ewb_json():
data = frappe._dict(frappe.local.form_dict) data = json.loads(frappe.local.form_dict.data)
frappe.local.response.filecontent = json.dumps(data, indent=4, sort_keys=True)
frappe.local.response.filecontent = json.dumps(data['data'], indent=4, sort_keys=True)
frappe.local.response.type = 'download' frappe.local.response.type = 'download'
billList = json.loads(data['data'])['billLists'] filename_prefix = 'Bulk'
docname = frappe.local.form_dict.docname
if docname:
if docname.startswith('['):
docname = json.loads(docname)
if len(docname) == 1:
docname = docname[0]
if len(billList) > 1: if not isinstance(docname, list):
doc_name = 'Bulk' # removes characters not allowed in a filename (https://stackoverflow.com/a/38766141/4767738)
else: filename_prefix = re.sub('[^\w_.)( -]', '', docname)
doc_name = data['docname']
frappe.local.response.filename = '{0}_e-WayBill_Data_{1}.json'.format(doc_name, frappe.utils.random_string(5)) frappe.local.response.filename = '{0}_e-WayBill_Data_{1}.json'.format(filename_prefix, frappe.utils.random_string(5))
@frappe.whitelist() @frappe.whitelist()
def get_gstins_for_company(company): def get_gstins_for_company(company):

View File

@@ -30,7 +30,7 @@ frappe.query_reports["DATEV"] = {
} }
], ],
onload: function(query_report) { onload: function(query_report) {
query_report.page.add_inner_button("Download DATEV Export", () => { query_report.page.add_menu_item(__("Download DATEV File"), () => {
const filters = JSON.stringify(query_report.get_values()); const filters = JSON.stringify(query_report.get_values());
window.open(`/api/method/erpnext.regional.report.datev.datev.download_datev_csv?filters=${filters}`); window.open(`/api/method/erpnext.regional.report.datev.datev.download_datev_csv?filters=${filters}`);
}); });

View File

@@ -1,39 +1,39 @@
[ [
{ {
"advance_paid": 0.0, "advance_paid": 0.0,
"company": "_Test Company", "company": "_Test Company",
"conversion_rate": 1.0, "conversion_rate": 1.0,
"currency": "INR", "currency": "INR",
"customer": "_Test Customer", "customer": "_Test Customer",
"customer_group": "_Test Customer Group", "customer_group": "_Test Customer Group",
"customer_name": "_Test Customer", "customer_name": "_Test Customer",
"doctype": "Sales Order", "doctype": "Sales Order",
"base_grand_total": 1000.0, "base_grand_total": 1000.0,
"grand_total": 1000.0, "grand_total": 1000.0,
"naming_series": "_T-Sales Order-", "naming_series": "_T-Sales Order-",
"order_type": "Sales", "order_type": "Sales",
"plc_conversion_rate": 1.0, "plc_conversion_rate": 1.0,
"price_list_currency": "INR", "price_list_currency": "INR",
"items": [ "items": [
{ {
"base_amount": 1000.0, "base_amount": 1000.0,
"base_rate": 100.0, "base_rate": 100.0,
"description": "CPU", "description": "CPU",
"doctype": "Sales Order Item", "doctype": "Sales Order Item",
"item_code": "_Test Item Home Desktop 100", "item_code": "_Test Item",
"item_name": "CPU", "item_name": "_Test Item 1",
"delivery_date": "2013-02-23", "delivery_date": "2013-02-23",
"parentfield": "items", "parentfield": "items",
"qty": 10.0, "qty": 10.0,
"rate": 100.0, "rate": 100.0,
"warehouse": "_Test Warehouse - _TC", "warehouse": "_Test Warehouse - _TC",
"stock_uom": "_Test UOM", "stock_uom": "_Test UOM",
"conversion_factor": 1.0, "conversion_factor": 1.0,
"uom": "_Test UOM" "uom": "_Test UOM"
} }
], ],
"selling_price_list": "_Test Price List", "selling_price_list": "_Test Price List",
"territory": "_Test Territory", "territory": "_Test Territory",
"transaction_date": "2013-02-21" "transaction_date": "2013-02-21"
} }
] ]

View File

@@ -29,12 +29,10 @@ def after_install():
def check_setup_wizard_not_completed(): def check_setup_wizard_not_completed():
if frappe.db.get_default('desktop:home_page') == 'desktop': if frappe.db.get_default('desktop:home_page') != 'setup-wizard':
print() message = """ERPNext can only be installed on a fresh site where the setup wizard is not completed.
print("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"""
print("You can reinstall this site (after saving your data) using: bench --site [sitename] reinstall") frappe.throw(message)
print()
return False
def set_single_defaults(): def set_single_defaults():
@@ -105,4 +103,3 @@ def add_company_to_session_defaults():
"ref_doctype": "Company" "ref_doctype": "Company"
}) })
settings.save() settings.save()

View File

@@ -92,8 +92,7 @@
{ {
"doctype": "Item Tax", "doctype": "Item Tax",
"parentfield": "taxes", "parentfield": "taxes",
"item_tax_template": "_Test Account Excise Duty @ 10", "item_tax_template": "_Test Account Excise Duty @ 10"
"tax_category": ""
} }
], ],
"stock_uom": "_Test UOM 1" "stock_uom": "_Test UOM 1"
@@ -371,8 +370,7 @@
{ {
"doctype": "Item Tax", "doctype": "Item Tax",
"parentfield": "taxes", "parentfield": "taxes",
"item_tax_template": "_Test Account Excise Duty @ 10", "item_tax_template": "_Test Account Excise Duty @ 10"
"tax_category": ""
}, },
{ {
"doctype": "Item Tax", "doctype": "Item Tax",
@@ -451,14 +449,13 @@
{ {
"doctype": "Item Tax", "doctype": "Item Tax",
"parentfield": "taxes", "parentfield": "taxes",
"item_tax_template": "_Test Account Excise Duty @ 20", "item_tax_template": "_Test Account Excise Duty @ 20"
"tax_category": ""
}, },
{ {
"doctype": "Item Tax", "doctype": "Item Tax",
"parentfield": "taxes", "parentfield": "taxes",
"item_tax_template": "_Test Item Tax Template 1", "tax_category": "_Test Tax Category 1",
"tax_category": "_Test Tax Category 1" "item_tax_template": "_Test Item Tax Template 1"
} }
] ]
} }

View File

@@ -190,23 +190,6 @@ class SerialNo(StockController):
if sle_exists: if sle_exists:
frappe.throw(_("Cannot delete Serial No {0}, as it is used in stock transactions").format(self.name)) frappe.throw(_("Cannot delete Serial No {0}, as it is used in stock transactions").format(self.name))
def before_rename(self, old, new, merge=False):
if merge:
frappe.throw(_("Sorry, Serial Nos cannot be merged"))
def after_rename(self, old, new, merge=False):
"""rename serial_no text fields"""
for dt in frappe.db.sql("""select parent from tabDocField
where fieldname='serial_no' and fieldtype in ('Text', 'Small Text')"""):
for item in frappe.db.sql("""select name, serial_no from `tab%s`
where serial_no like %s""" % (dt[0], frappe.db.escape('%' + old + '%'))):
serial_nos = map(lambda i: new if i.upper()==old.upper() else i, item[1].split('\n'))
frappe.db.sql("""update `tab%s` set serial_no = %s
where name=%s""" % (dt[0], '%s', '%s'),
('\n'.join(list(serial_nos)), item[0]))
def update_serial_no_reference(self, serial_no=None): def update_serial_no_reference(self, serial_no=None):
last_sle = self.get_last_sle(serial_no) last_sle = self.get_last_sle(serial_no)
self.set_purchase_details(last_sle.get("purchase_sle")) self.set_purchase_details(last_sle.get("purchase_sle"))

View File

@@ -638,7 +638,7 @@ def get_item_price(args, item_code, ignore_party=False):
if args.get('transaction_date'): if args.get('transaction_date'):
conditions += """ and %(transaction_date)s between conditions += """ and %(transaction_date)s between
ifnull(valid_from, '2000-01-01') and ifnull(valid_upto, '2500-12-31')""" ifnull(valid_from, '2000-01-01') and ifnull(valid_upto, '2500-12-31')"""
if args.get('posting_date'): if args.get('posting_date'):
conditions += """ and %(posting_date)s between conditions += """ and %(posting_date)s between
ifnull(valid_from, '2000-01-01') and ifnull(valid_upto, '2500-12-31')""" ifnull(valid_from, '2000-01-01') and ifnull(valid_upto, '2500-12-31')"""

View File

@@ -21,7 +21,7 @@ def execute(filters=None):
for cd in consumed_details.get(item_code): for cd in consumed_details.get(item_code):
if (cd.voucher_no not in material_transfer_vouchers): if (cd.voucher_no not in material_transfer_vouchers):
if cd.voucher_type=="Delivery Note": if cd.voucher_type in ["Delivery Note", "Sales Invoice"]:
delivered_qty += abs(flt(cd.actual_qty)) delivered_qty += abs(flt(cd.actual_qty))
delivered_amount += abs(flt(cd.stock_value_difference)) delivered_amount += abs(flt(cd.stock_value_difference))
elif cd.voucher_type!="Delivery Note": elif cd.voucher_type!="Delivery Note":

View File

@@ -121,7 +121,6 @@ class TransactionBase(StatusUpdater):
def validate_rate_with_reference_doc(self, ref_details): def validate_rate_with_reference_doc(self, ref_details):
buying_doctypes = ["Purchase Order", "Purchase Invoice", "Purchase Receipt"] buying_doctypes = ["Purchase Order", "Purchase Invoice", "Purchase Receipt"]
selling_doctypes = ["Sales Invoice", "Delivery Note"]
if self.doctype in buying_doctypes: if self.doctype in buying_doctypes:
to_disable = "Maintain same rate throughout Purchase cycle" to_disable = "Maintain same rate throughout Purchase cycle"

View File

@@ -2,7 +2,7 @@ braintree==3.57.1
frappe frappe
gocardless-pro==1.11.0 gocardless-pro==1.11.0
googlemaps==3.1.1 googlemaps==3.1.1
pandas==0.24.2 pandas==1.0.5
plaid-python==3.4.0 plaid-python==3.4.0
pycountry==19.8.18 pycountry==19.8.18
PyGithub==1.44.1 PyGithub==1.44.1