diff --git a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py index 56193216a22..f2b0a8c08a6 100644 --- a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py +++ b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py @@ -27,6 +27,9 @@ class ExchangeRateRevaluation(Document): if not (self.company and self.posting_date): frappe.throw(_("Please select Company and Posting Date to getting entries")) + def on_cancel(self): + self.ignore_linked_doctypes = ('GL Entry') + @frappe.whitelist() def check_journal_entry_condition(self): total_debit = frappe.db.get_value("Journal Entry Account", { @@ -99,10 +102,12 @@ class ExchangeRateRevaluation(Document): sum(debit) - sum(credit) as balance from `tabGL Entry` where account in (%s) - group by account, party_type, party + and posting_date <= %s + and is_cancelled = 0 + group by account, NULLIF(party_type,''), NULLIF(party,'') having sum(debit) != sum(credit) order by account - """ % ', '.join(['%s']*len(accounts)), tuple(accounts), as_dict=1) + """ % (', '.join(['%s']*len(accounts)), '%s'), tuple(accounts + [self.posting_date]), as_dict=1) return account_details @@ -143,9 +148,9 @@ class ExchangeRateRevaluation(Document): "party_type": d.get("party_type"), "party": d.get("party"), "account_currency": d.get("account_currency"), - "balance": d.get("balance_in_account_currency"), - dr_or_cr: abs(d.get("balance_in_account_currency")), - "exchange_rate":d.get("new_exchange_rate"), + "balance": flt(d.get("balance_in_account_currency"), d.precision("balance_in_account_currency")), + dr_or_cr: flt(abs(d.get("balance_in_account_currency")), d.precision("balance_in_account_currency")), + "exchange_rate": flt(d.get("new_exchange_rate"), d.precision("new_exchange_rate")), "reference_type": "Exchange Rate Revaluation", "reference_name": self.name, }) @@ -154,9 +159,9 @@ class ExchangeRateRevaluation(Document): "party_type": d.get("party_type"), "party": d.get("party"), "account_currency": d.get("account_currency"), - "balance": d.get("balance_in_account_currency"), - reverse_dr_or_cr: abs(d.get("balance_in_account_currency")), - "exchange_rate": d.get("current_exchange_rate"), + "balance": flt(d.get("balance_in_account_currency"), d.precision("balance_in_account_currency")), + reverse_dr_or_cr: flt(abs(d.get("balance_in_account_currency")), d.precision("balance_in_account_currency")), + "exchange_rate": flt(d.get("current_exchange_rate"), d.precision("current_exchange_rate")), "reference_type": "Exchange Rate Revaluation", "reference_name": self.name }) @@ -185,9 +190,9 @@ def get_account_details(account, company, posting_date, party_type=None, party=N account_details = {} company_currency = erpnext.get_company_currency(company) - balance = get_balance_on(account, party_type=party_type, party=party, in_account_currency=False) + balance = get_balance_on(account, date=posting_date, party_type=party_type, party=party, in_account_currency=False) if balance: - balance_in_account_currency = get_balance_on(account, party_type=party_type, party=party) + balance_in_account_currency = get_balance_on(account, date=posting_date, party_type=party_type, party=party) current_exchange_rate = balance / balance_in_account_currency if balance_in_account_currency else 0 new_exchange_rate = get_exchange_rate(account_currency, company_currency, posting_date) new_balance_in_base_currency = balance_in_account_currency * new_exchange_rate diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py index a11b77a6f64..b54646fd27a 100755 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py @@ -99,7 +99,6 @@ class ReceivablePayableReport(object): voucher_no = gle.voucher_no, party = gle.party, posting_date = gle.posting_date, - remarks = gle.remarks, account_currency = gle.account_currency, invoiced = 0.0, paid = 0.0, @@ -579,7 +578,7 @@ class ReceivablePayableReport(object): self.gl_entries = frappe.db.sql(""" select name, posting_date, account, party_type, party, voucher_type, voucher_no, cost_center, - against_voucher_type, against_voucher, account_currency, remarks, {0} + against_voucher_type, against_voucher, account_currency, {0} from `tabGL Entry` where @@ -792,8 +791,6 @@ class ReceivablePayableReport(object): self.add_column(label=_('Supplier Group'), fieldname='supplier_group', fieldtype='Link', options='Supplier Group') - self.add_column(label=_('Remarks'), fieldname='remarks', fieldtype='Text', width=200) - def add_column(self, label, fieldname=None, fieldtype='Currency', options=None, width=120): if not fieldname: fieldname = scrub(label) if fieldtype=='Currency': options='currency' diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 4c313c43a72..cdd865ac4ac 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -1112,8 +1112,11 @@ class AccountsController(TransactionBase): for d in self.get("payment_schedule"): if d.invoice_portion: d.payment_amount = flt(grand_total * flt(d.invoice_portion / 100), d.precision('payment_amount')) - d.base_payment_amount = flt(base_grand_total * flt(d.invoice_portion / 100), d.precision('payment_amount')) + d.base_payment_amount = flt(base_grand_total * flt(d.invoice_portion / 100), d.precision('base_payment_amount')) d.outstanding = d.payment_amount + elif not d.invoice_portion: + d.base_payment_amount = flt(base_grand_total * self.get("conversion_rate"), d.precision('base_payment_amount')) + def set_due_date(self): due_dates = [d.due_date for d in self.get("payment_schedule") if d.due_date] diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index 2526e6df0ef..17bd7354f93 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -53,12 +53,17 @@ class StockController(AccountsController): from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos for d in self.get("items"): if hasattr(d, 'serial_no') and hasattr(d, 'batch_no') and d.serial_no and d.batch_no: - serial_nos = get_serial_nos(d.serial_no) - for serial_no_data in frappe.get_all("Serial No", - filters={"name": ("in", serial_nos)}, fields=["batch_no", "name"]): - if serial_no_data.batch_no != d.batch_no: + serial_nos = frappe.get_all("Serial No", + fields=["batch_no", "name", "warehouse"], + filters={ + "name": ("in", get_serial_nos(d.serial_no)) + } + ) + + for row in serial_nos: + if row.warehouse and row.batch_no != d.batch_no: frappe.throw(_("Row #{0}: Serial No {1} does not belong to Batch {2}") - .format(d.idx, serial_no_data.name, d.batch_no)) + .format(d.idx, row.name, d.batch_no)) if flt(d.qty) > 0.0 and d.get("batch_no") and self.get("posting_date") and self.docstatus < 2: expiry_date = frappe.get_cached_value("Batch", d.get("batch_no"), "expiry_date") diff --git a/erpnext/crm/doctype/campaign/__init__.py b/erpnext/crm/doctype/campaign/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/crm/doctype/campaign/campaign.js b/erpnext/crm/doctype/campaign/campaign.js new file mode 100644 index 00000000000..11bfa74b29c --- /dev/null +++ b/erpnext/crm/doctype/campaign/campaign.js @@ -0,0 +1,17 @@ +// Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Campaign', { + refresh: function(frm) { + erpnext.toggle_naming_series(); + + if (frm.doc.__islocal) { + frm.toggle_display("naming_series", frappe.boot.sysdefaults.campaign_naming_by=="Naming Series"); + } else { + cur_frm.add_custom_button(__("View Leads"), function() { + frappe.route_options = {"source": "Campaign", "campaign_name": frm.doc.name}; + frappe.set_route("List", "Lead"); + }, "fa fa-list", true); + } + } +}); diff --git a/erpnext/selling/doctype/campaign/campaign.json b/erpnext/crm/doctype/campaign/campaign.json similarity index 95% rename from erpnext/selling/doctype/campaign/campaign.json rename to erpnext/crm/doctype/campaign/campaign.json index 986ac1306cd..f833f4c9d11 100644 --- a/erpnext/selling/doctype/campaign/campaign.json +++ b/erpnext/crm/doctype/campaign/campaign.json @@ -1,4 +1,5 @@ { + "actions": [], "allow_import": 1, "allow_rename": 1, "autoname": "naming_series:", @@ -39,17 +40,9 @@ "set_only_once": 1 }, { - "fieldname": "description", - "fieldtype": "Text", - "in_list_view": 1, - "label": "Description", - "oldfieldname": "description", - "oldfieldtype": "Text", - "width": "300px" - }, - { - "fieldname": "description_section", - "fieldtype": "Section Break" + "fieldname": "campaign_schedules_section", + "fieldtype": "Section Break", + "label": "Campaign Schedules" }, { "fieldname": "campaign_schedules", @@ -58,16 +51,25 @@ "options": "Campaign Email Schedule" }, { - "fieldname": "campaign_schedules_section", - "fieldtype": "Section Break", - "label": "Campaign Schedules" + "fieldname": "description_section", + "fieldtype": "Section Break" + }, + { + "fieldname": "description", + "fieldtype": "Text", + "in_list_view": 1, + "label": "Description", + "oldfieldname": "description", + "oldfieldtype": "Text", + "width": "300px" } ], "icon": "fa fa-bullhorn", "idx": 1, - "modified": "2019-07-22 12:03:39.832342", + "links": [], + "modified": "2021-06-30 18:05:06.412712", "modified_by": "Administrator", - "module": "Selling", + "module": "CRM", "name": "Campaign", "owner": "Administrator", "permissions": [ diff --git a/erpnext/selling/doctype/campaign/campaign.py b/erpnext/crm/doctype/campaign/campaign.py similarity index 66% rename from erpnext/selling/doctype/campaign/campaign.py rename to erpnext/crm/doctype/campaign/campaign.py index 10945428aee..e32799f34eb 100644 --- a/erpnext/selling/doctype/campaign/campaign.py +++ b/erpnext/crm/doctype/campaign/campaign.py @@ -1,9 +1,7 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -# License: GNU General Public License v3. See license.txt +# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt -from __future__ import unicode_literals import frappe - from frappe.model.document import Document from frappe.model.naming import set_name_by_naming_series diff --git a/erpnext/crm/doctype/campaign/test_campaign.py b/erpnext/crm/doctype/campaign/test_campaign.py new file mode 100644 index 00000000000..7124b8c7d60 --- /dev/null +++ b/erpnext/crm/doctype/campaign/test_campaign.py @@ -0,0 +1,8 @@ +# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt + +# import frappe +import unittest + +class TestCampaign(unittest.TestCase): + pass diff --git a/erpnext/manufacturing/doctype/job_card/job_card.py b/erpnext/manufacturing/doctype/job_card/job_card.py index 420bb008039..69c7f5c614b 100644 --- a/erpnext/manufacturing/doctype/job_card/job_card.py +++ b/erpnext/manufacturing/doctype/job_card/job_card.py @@ -192,11 +192,11 @@ class JobCard(Document): "completed_qty": args.get("completed_qty") or 0.0 }) elif args.get("start_time"): - new_args = { + new_args = frappe._dict({ "from_time": get_datetime(args.get("start_time")), "operation": args.get("sub_operation"), "completed_qty": 0.0 - } + }) if employees: for name in employees: diff --git a/erpnext/patches/v13_0/add_missing_fg_item_for_stock_entry.py b/erpnext/patches/v13_0/add_missing_fg_item_for_stock_entry.py index 48999e6f993..d7ad1fc6962 100644 --- a/erpnext/patches/v13_0/add_missing_fg_item_for_stock_entry.py +++ b/erpnext/patches/v13_0/add_missing_fg_item_for_stock_entry.py @@ -10,6 +10,7 @@ def execute(): if not frappe.db.has_column('Work Order', 'has_batch_no'): return + frappe.reload_doc('manufacturing', 'doctype', 'manufacturing_settings') if cint(frappe.db.get_single_value('Manufacturing Settings', 'make_serial_no_batch_from_work_order')): return @@ -107,4 +108,4 @@ def repost_future_sle_and_gle(doc): "company": doc.company }) - create_repost_item_valuation_entry(args) \ No newline at end of file + create_repost_item_valuation_entry(args) diff --git a/erpnext/patches/v13_0/rename_issue_doctype_fields.py b/erpnext/patches/v13_0/rename_issue_doctype_fields.py index fa1dfed6435..41c51c36dcb 100644 --- a/erpnext/patches/v13_0/rename_issue_doctype_fields.py +++ b/erpnext/patches/v13_0/rename_issue_doctype_fields.py @@ -37,7 +37,7 @@ def execute(): if frappe.db.exists('DocType', 'Opportunity'): opportunities = frappe.db.get_all('Opportunity', fields=['name', 'mins_to_first_response'], order_by='creation desc') - frappe.reload_doc('crm', 'doctype', 'opportunity') + frappe.reload_doctype('Opportunity', force=True) rename_field('Opportunity', 'mins_to_first_response', 'first_response_time') # change fieldtype to duration diff --git a/erpnext/payroll/doctype/salary_component/salary_component.js b/erpnext/payroll/doctype/salary_component/salary_component.js index dbf75140ac1..e9e6f81862c 100644 --- a/erpnext/payroll/doctype/salary_component/salary_component.js +++ b/erpnext/payroll/doctype/salary_component/salary_component.js @@ -4,11 +4,18 @@ frappe.ui.form.on('Salary Component', { setup: function(frm) { frm.set_query("account", "accounts", function(doc, cdt, cdn) { - var d = locals[cdt][cdn]; + let d = frappe.get_doc(cdt, cdn); + + let root_type = "Liability"; + if (frm.doc.type == "Deduction") { + root_type = "Expense"; + } + return { filters: { "is_group": 0, - "company": d.company + "company": d.company, + "root_type": root_type } }; }); diff --git a/erpnext/regional/doctype/e_invoice_settings/e_invoice_settings.js b/erpnext/regional/doctype/e_invoice_settings/e_invoice_settings.js index cc2d9f06d2d..54e488610df 100644 --- a/erpnext/regional/doctype/e_invoice_settings/e_invoice_settings.js +++ b/erpnext/regional/doctype/e_invoice_settings/e_invoice_settings.js @@ -3,7 +3,7 @@ frappe.ui.form.on('E Invoice Settings', { refresh(frm) { - const docs_link = 'https://docs.erpnext.com/docs/user/manual/en/regional/india/setup-e-invoicing'; + const docs_link = 'https://docs.erpnext.com/docs/v13/user/manual/en/regional/india/setup-e-invoicing'; frm.dashboard.set_headline( __("Read {0} for more information on E Invoicing features.", [`documentation`]) ); diff --git a/erpnext/selling/doctype/campaign/README.md b/erpnext/selling/doctype/campaign/README.md deleted file mode 100644 index a8373184027..00000000000 --- a/erpnext/selling/doctype/campaign/README.md +++ /dev/null @@ -1 +0,0 @@ -Sales campaign / promotion, like special discount, exhibition, newsletter etc. \ No newline at end of file diff --git a/erpnext/selling/doctype/campaign/__init__.py b/erpnext/selling/doctype/campaign/__init__.py deleted file mode 100644 index baffc488252..00000000000 --- a/erpnext/selling/doctype/campaign/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from __future__ import unicode_literals diff --git a/erpnext/selling/doctype/campaign/campaign.js b/erpnext/selling/doctype/campaign/campaign.js deleted file mode 100644 index 72a90d053f2..00000000000 --- a/erpnext/selling/doctype/campaign/campaign.js +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -// License: GNU General Public License v3. See license.txt - -frappe.ui.form.on("Campaign", "refresh", function(frm) { - erpnext.toggle_naming_series(); - if(frm.doc.__islocal) { - frm.toggle_display("naming_series", frappe.boot.sysdefaults.campaign_naming_by=="Naming Series"); - } - else{ - cur_frm.add_custom_button(__("View Leads"), function() { - frappe.route_options = {"source": "Campaign","campaign_name": frm.doc.name} - frappe.set_route("List", "Lead"); - }, "fa fa-list", true); - } -}) diff --git a/erpnext/selling/doctype/campaign/campaign_dashboard.py b/erpnext/selling/doctype/campaign/campaign_dashboard.py deleted file mode 100644 index 3cef560c32f..00000000000 --- a/erpnext/selling/doctype/campaign/campaign_dashboard.py +++ /dev/null @@ -1,17 +0,0 @@ -from __future__ import unicode_literals -from frappe import _ - -def get_data(): - return { - 'fieldname': 'campaign_name', - 'transactions': [ - { - 'label': _('Email Campaigns'), - 'items': ['Email Campaign'] - }, - { - 'label': _('Social Media Campaigns'), - 'items': ['Social Media Post'] - } - ] - } diff --git a/erpnext/selling/doctype/campaign/test_campaign.py b/erpnext/selling/doctype/campaign/test_campaign.py deleted file mode 100644 index 4d062ff84c6..00000000000 --- a/erpnext/selling/doctype/campaign/test_campaign.py +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -# License: GNU General Public License v3. See license.txt -from __future__ import unicode_literals - - -import frappe -test_records = frappe.get_test_records('Campaign') \ No newline at end of file diff --git a/erpnext/selling/doctype/campaign/test_records.json b/erpnext/selling/doctype/campaign/test_records.json deleted file mode 100644 index 625d3b377b2..00000000000 --- a/erpnext/selling/doctype/campaign/test_records.json +++ /dev/null @@ -1,10 +0,0 @@ -[ - { - "campaign_name": "_Test Campaign", - "doctype": "Campaign" - }, - { - "campaign_name": "_Test Campaign 1", - "doctype": "Campaign" - } -] \ No newline at end of file diff --git a/erpnext/selling/page/sales_funnel/sales_funnel.css b/erpnext/selling/page/sales_funnel/sales_funnel.css index 89e904fcfc9..455d37cb238 100644 --- a/erpnext/selling/page/sales_funnel/sales_funnel.css +++ b/erpnext/selling/page/sales_funnel/sales_funnel.css @@ -1,3 +1,4 @@ .funnel-wrapper { margin: 15px; + width: 100%; } \ No newline at end of file