Merge pull request #25701 from anupamvs/timesheet-refactor
refactor: timesheet
diff --git a/erpnext/accounts/deferred_revenue.py b/erpnext/accounts/deferred_revenue.py
index d5ab1c1..dd346bc 100644
--- a/erpnext/accounts/deferred_revenue.py
+++ b/erpnext/accounts/deferred_revenue.py
@@ -41,7 +41,7 @@
if account:
conditions += "AND %s='%s'"%(deferred_account, account)
elif company:
- conditions += "AND p.company='%s'"%(company)
+ conditions += f"AND p.company = {frappe.db.escape(company)}"
return conditions
@@ -360,12 +360,10 @@
frappe.flags.deferred_accounting_error = True
def send_mail(deferred_process):
- title = _("Error while processing deferred accounting for {0}".format(deferred_process))
- content = _("""
- Deferred accounting failed for some invoices:
- Please check Process Deferred Accounting {0}
- and submit manually after resolving errors
- """).format(get_link_to_form('Process Deferred Accounting', deferred_process))
+ title = _("Error while processing deferred accounting for {0}").format(deferred_process)
+ link = get_link_to_form('Process Deferred Accounting', deferred_process)
+ content = _("Deferred accounting failed for some invoices:") + "\n"
+ content += _("Please check Process Deferred Accounting {0} and submit manually after resolving errors.").format(link)
sendmail_to_system_managers(title, content)
def book_revenue_via_journal_entry(doc, credit_account, debit_account, against,
diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py
index 78febf9..948c513 100644
--- a/erpnext/accounts/doctype/gl_entry/gl_entry.py
+++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py
@@ -75,8 +75,13 @@
def pl_must_have_cost_center(self):
if frappe.get_cached_value("Account", self.account, "report_type") == "Profit and Loss":
if not self.cost_center and self.voucher_type != 'Period Closing Voucher':
- frappe.throw(_("{0} {1}: Cost Center is required for 'Profit and Loss' account {2}. Please set up a default Cost Center for the Company.")
- .format(self.voucher_type, self.voucher_no, self.account))
+ msg = _("{0} {1}: Cost Center is required for 'Profit and Loss' account {2}.").format(
+ self.voucher_type, self.voucher_no, self.account)
+ msg += " "
+ msg += _("Please set the cost center field in {0} or setup a default Cost Center for the Company.").format(
+ self.voucher_type)
+
+ frappe.throw(msg, title=_("Missing Cost Center"))
def validate_dimensions_for_pl_and_bs(self):
account_type = frappe.db.get_value("Account", self.account, "report_type")
diff --git a/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.js b/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.js
index aa0c53e..8c5a34a 100644
--- a/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.js
+++ b/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.js
@@ -101,15 +101,24 @@
},
before_save: function(frm) {
+ frm.set_value("grand_total", 0);
+ frm.set_value("net_total", 0);
+ frm.set_value("total_quantity", 0);
+ frm.set_value("taxes", []);
+
+ for (let row of frm.doc.payment_reconciliation) {
+ row.expected_amount = 0;
+ }
+
for (let row of frm.doc.pos_transactions) {
frappe.db.get_doc("POS Invoice", row.pos_invoice).then(doc => {
- cur_frm.doc.grand_total -= flt(doc.grand_total);
- cur_frm.doc.net_total -= flt(doc.net_total);
- cur_frm.doc.total_quantity -= flt(doc.total_qty);
- refresh_payments(doc, cur_frm, 1);
- refresh_taxes(doc, cur_frm, 1);
- refresh_fields(cur_frm);
- set_html_data(cur_frm);
+ frm.doc.grand_total += flt(doc.grand_total);
+ frm.doc.net_total += flt(doc.net_total);
+ frm.doc.total_quantity += flt(doc.total_qty);
+ refresh_payments(doc, frm);
+ refresh_taxes(doc, frm);
+ refresh_fields(frm);
+ set_html_data(frm);
});
}
}
@@ -118,7 +127,7 @@
frappe.ui.form.on('POS Closing Entry Detail', {
closing_amount: (frm, cdt, cdn) => {
const row = locals[cdt][cdn];
- frappe.model.set_value(cdt, cdn, "difference", flt(row.expected_amount - row.closing_amount))
+ frappe.model.set_value(cdt, cdn, "difference", flt(row.expected_amount - row.closing_amount));
}
})
@@ -142,28 +151,28 @@
})
}
-function refresh_payments(d, frm, remove) {
+function refresh_payments(d, frm) {
d.payments.forEach(p => {
const payment = frm.doc.payment_reconciliation.find(pay => pay.mode_of_payment === p.mode_of_payment);
if (payment) {
- if (!remove) payment.expected_amount += flt(p.amount);
- else payment.expected_amount -= flt(p.amount);
+ payment.expected_amount += flt(p.amount);
+ payment.difference = payment.closing_amount - payment.expected_amount;
} else {
frm.add_child("payment_reconciliation", {
mode_of_payment: p.mode_of_payment,
opening_amount: 0,
- expected_amount: p.amount
+ expected_amount: p.amount,
+ closing_amount: 0
})
}
})
}
-function refresh_taxes(d, frm, remove) {
+function refresh_taxes(d, frm) {
d.taxes.forEach(t => {
const tax = frm.doc.taxes.find(tx => tx.account_head === t.account_head && tx.rate === t.rate);
if (tax) {
- if (!remove) tax.amount += flt(t.tax_amount);
- else tax.amount -= flt(t.tax_amount);
+ tax.amount += flt(t.tax_amount);
} else {
frm.add_child("taxes", {
account_head: t.account_head,
diff --git a/erpnext/accounts/report/dimension_wise_accounts_balance_report/__init__.py b/erpnext/accounts/report/dimension_wise_accounts_balance_report/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/accounts/report/dimension_wise_accounts_balance_report/__init__.py
diff --git a/erpnext/accounts/report/dimension_wise_accounts_balance_report/dimension_wise_accounts_balance_report.js b/erpnext/accounts/report/dimension_wise_accounts_balance_report/dimension_wise_accounts_balance_report.js
new file mode 100644
index 0000000..6a03948
--- /dev/null
+++ b/erpnext/accounts/report/dimension_wise_accounts_balance_report/dimension_wise_accounts_balance_report.js
@@ -0,0 +1,81 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.require("assets/erpnext/js/financial_statements.js", function() {
+ frappe.query_reports["Dimension-wise Accounts Balance Report"] = {
+ "filters": [
+ {
+ "fieldname": "company",
+ "label": __("Company"),
+ "fieldtype": "Link",
+ "options": "Company",
+ "default": frappe.defaults.get_user_default("Company"),
+ "reqd": 1
+ },
+ {
+ "fieldname": "fiscal_year",
+ "label": __("Fiscal Year"),
+ "fieldtype": "Link",
+ "options": "Fiscal Year",
+ "default": frappe.defaults.get_user_default("fiscal_year"),
+ "reqd": 1,
+ "on_change": function(query_report) {
+ var fiscal_year = query_report.get_values().fiscal_year;
+ if (!fiscal_year) {
+ return;
+ }
+ frappe.model.with_doc("Fiscal Year", fiscal_year, function(r) {
+ var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
+ frappe.query_report.set_filter_value({
+ from_date: fy.year_start_date,
+ to_date: fy.year_end_date
+ });
+ });
+ }
+ },
+ {
+ "fieldname": "from_date",
+ "label": __("From Date"),
+ "fieldtype": "Date",
+ "default": frappe.defaults.get_user_default("year_start_date"),
+ },
+ {
+ "fieldname": "to_date",
+ "label": __("To Date"),
+ "fieldtype": "Date",
+ "default": frappe.defaults.get_user_default("year_end_date"),
+ },
+ {
+ "fieldname": "finance_book",
+ "label": __("Finance Book"),
+ "fieldtype": "Link",
+ "options": "Finance Book",
+ },
+ {
+ "fieldname": "dimension",
+ "label": __("Select Dimension"),
+ "fieldtype": "Select",
+ "options": get_accounting_dimension_options(),
+ "reqd": 1,
+ },
+ ],
+ "formatter": erpnext.financial_statements.formatter,
+ "tree": true,
+ "name_field": "account",
+ "parent_field": "parent_account",
+ "initial_depth": 3
+ }
+
+});
+
+function get_accounting_dimension_options() {
+ let options =["", "Cost Center", "Project"];
+ frappe.db.get_list('Accounting Dimension',
+ {fields:['document_type']}).then((res) => {
+ res.forEach((dimension) => {
+ options.push(dimension.document_type);
+ });
+ });
+ return options
+}
diff --git a/erpnext/accounts/report/dimension_wise_accounts_balance_report/dimension_wise_accounts_balance_report.json b/erpnext/accounts/report/dimension_wise_accounts_balance_report/dimension_wise_accounts_balance_report.json
new file mode 100644
index 0000000..6141944
--- /dev/null
+++ b/erpnext/accounts/report/dimension_wise_accounts_balance_report/dimension_wise_accounts_balance_report.json
@@ -0,0 +1,22 @@
+{
+ "add_total_row": 0,
+ "columns": [],
+ "creation": "2021-04-09 16:48:59.548018",
+ "disable_prepared_report": 0,
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "filters": [],
+ "idx": 0,
+ "is_standard": "Yes",
+ "modified": "2021-04-09 16:48:59.548018",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "Dimension-wise Accounts Balance Report",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "ref_doctype": "GL Entry",
+ "report_name": "Dimension-wise Accounts Balance Report",
+ "report_type": "Script Report",
+ "roles": []
+}
\ No newline at end of file
diff --git a/erpnext/accounts/report/dimension_wise_accounts_balance_report/dimension_wise_accounts_balance_report.py b/erpnext/accounts/report/dimension_wise_accounts_balance_report/dimension_wise_accounts_balance_report.py
new file mode 100644
index 0000000..de7ed49
--- /dev/null
+++ b/erpnext/accounts/report/dimension_wise_accounts_balance_report/dimension_wise_accounts_balance_report.py
@@ -0,0 +1,213 @@
+# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe, erpnext
+from frappe import _
+from frappe.utils import (flt, cstr)
+
+from erpnext.accounts.report.financial_statements import filter_accounts, filter_out_zero_value_rows
+from erpnext.accounts.report.trial_balance.trial_balance import validate_filters
+
+from six import itervalues
+
+def execute(filters=None):
+ validate_filters(filters)
+ dimension_items_list = get_dimension_items_list(filters.dimension, filters.company)
+
+ if not dimension_items_list:
+ return [], []
+
+ dimension_items_list = [''.join(d) for d in dimension_items_list]
+ columns = get_columns(dimension_items_list)
+ data = get_data(filters, dimension_items_list)
+
+ return columns, data
+
+def get_data(filters, dimension_items_list):
+ company_currency = erpnext.get_company_currency(filters.company)
+ acc = frappe.db.sql("""
+ select
+ name, account_number, parent_account, lft, rgt, root_type,
+ report_type, account_name, include_in_gross, account_type, is_group
+ from
+ `tabAccount`
+ where
+ company=%s
+ order by lft""", (filters.company), as_dict=True)
+
+ if not acc:
+ return None
+
+ accounts, accounts_by_name, parent_children_map = filter_accounts(acc)
+
+ min_lft, max_rgt = frappe.db.sql("""select min(lft), max(rgt) from `tabAccount`
+ where company=%s""", (filters.company))[0]
+
+ account = frappe.db.sql_list("""select name from `tabAccount`
+ where lft >= %s and rgt <= %s and company = %s""", (min_lft, max_rgt, filters.company))
+
+ gl_entries_by_account = {}
+ set_gl_entries_by_account(dimension_items_list, filters, account, gl_entries_by_account)
+ format_gl_entries(gl_entries_by_account, accounts_by_name, dimension_items_list)
+ accumulate_values_into_parents(accounts, accounts_by_name, dimension_items_list)
+ out = prepare_data(accounts, filters, parent_children_map, company_currency, dimension_items_list)
+ out = filter_out_zero_value_rows(out, parent_children_map)
+
+ return out
+
+def set_gl_entries_by_account(dimension_items_list, filters, account, gl_entries_by_account):
+ for item in dimension_items_list:
+ condition = get_condition(filters.from_date, item, filters.dimension)
+ if account:
+ condition += " and account in ({})"\
+ .format(", ".join([frappe.db.escape(d) for d in account]))
+
+ gl_filters = {
+ "company": filters.get("company"),
+ "from_date": filters.get("from_date"),
+ "to_date": filters.get("to_date"),
+ "finance_book": cstr(filters.get("finance_book"))
+ }
+
+ gl_filters['item'] = ''.join(item)
+
+ if filters.get("include_default_book_entries"):
+ gl_filters["company_fb"] = frappe.db.get_value("Company",
+ filters.company, 'default_finance_book')
+
+ for key, value in filters.items():
+ if value:
+ gl_filters.update({
+ key: value
+ })
+
+ gl_entries = frappe.db.sql("""
+ select
+ posting_date, account, debit, credit, is_opening, fiscal_year,
+ debit_in_account_currency, credit_in_account_currency, account_currency
+ from
+ `tabGL Entry`
+ where
+ company=%(company)s
+ {condition}
+ and posting_date <= %(to_date)s
+ and is_cancelled = 0
+ order by account, posting_date""".format(
+ condition=condition),
+ gl_filters, as_dict=True) #nosec
+
+ for entry in gl_entries:
+ entry['dimension_item'] = ''.join(item)
+ gl_entries_by_account.setdefault(entry.account, []).append(entry)
+
+def format_gl_entries(gl_entries_by_account, accounts_by_name, dimension_items_list):
+
+ for entries in itervalues(gl_entries_by_account):
+ for entry in entries:
+ d = accounts_by_name.get(entry.account)
+ if not d:
+ frappe.msgprint(
+ _("Could not retrieve information for {0}.").format(entry.account), title="Error",
+ raise_exception=1
+ )
+ for item in dimension_items_list:
+ if item == entry.dimension_item:
+ d[frappe.scrub(item)] = d.get(frappe.scrub(item), 0.0) + flt(entry.debit) - flt(entry.credit)
+
+def prepare_data(accounts, filters, parent_children_map, company_currency, dimension_items_list):
+ data = []
+
+ for d in accounts:
+ has_value = False
+ total = 0
+ row = {
+ "account": d.name,
+ "parent_account": d.parent_account,
+ "indent": d.indent,
+ "from_date": filters.from_date,
+ "to_date": filters.to_date,
+ "currency": company_currency,
+ "account_name": ('{} - {}'.format(d.account_number, d.account_name)
+ if d.account_number else d.account_name)
+ }
+
+ for item in dimension_items_list:
+ row[frappe.scrub(item)] = flt(d.get(frappe.scrub(item), 0.0), 3)
+
+ if abs(row[frappe.scrub(item)]) >= 0.005:
+ # ignore zero values
+ has_value = True
+ total += flt(d.get(frappe.scrub(item), 0.0), 3)
+
+ row["has_value"] = has_value
+ row["total"] = total
+ data.append(row)
+
+ return data
+
+def accumulate_values_into_parents(accounts, accounts_by_name, dimension_items_list):
+ """accumulate children's values in parent accounts"""
+ for d in reversed(accounts):
+ if d.parent_account:
+ for item in dimension_items_list:
+ accounts_by_name[d.parent_account][frappe.scrub(item)] = \
+ accounts_by_name[d.parent_account].get(frappe.scrub(item), 0.0) + d.get(frappe.scrub(item), 0.0)
+
+def get_condition(from_date, item, dimension):
+ conditions = []
+
+ if from_date:
+ conditions.append("posting_date >= %(from_date)s")
+ if dimension:
+ if dimension not in ['Cost Center', 'Project']:
+ if dimension in ['Customer', 'Supplier']:
+ dimension = 'Party'
+ else:
+ dimension = 'Voucher No'
+ txt = "{0} = %(item)s".format(frappe.scrub(dimension))
+ conditions.append(txt)
+
+ return " and {}".format(" and ".join(conditions)) if conditions else ""
+
+def get_dimension_items_list(dimension, company):
+ meta = frappe.get_meta(dimension, cached=False)
+ fieldnames = [d.fieldname for d in meta.get("fields")]
+ filters = {}
+ if 'company' in fieldnames:
+ filters['company'] = company
+ return frappe.get_all(dimension, filters, as_list=True)
+
+def get_columns(dimension_items_list, accumulated_values=1, company=None):
+ columns = [{
+ "fieldname": "account",
+ "label": _("Account"),
+ "fieldtype": "Link",
+ "options": "Account",
+ "width": 300
+ }]
+ if company:
+ columns.append({
+ "fieldname": "currency",
+ "label": _("Currency"),
+ "fieldtype": "Link",
+ "options": "Currency",
+ "hidden": 1
+ })
+ for item in dimension_items_list:
+ columns.append({
+ "fieldname": frappe.scrub(item),
+ "label": item,
+ "fieldtype": "Currency",
+ "options": "currency",
+ "width": 150
+ })
+ columns.append({
+ "fieldname": "total",
+ "label": "Total",
+ "fieldtype": "Currency",
+ "options": "currency",
+ "width": 150
+ })
+
+ return columns
diff --git a/erpnext/assets/doctype/asset_category/asset_category.js b/erpnext/assets/doctype/asset_category/asset_category.js
index 74963c2..51ce157 100644
--- a/erpnext/assets/doctype/asset_category/asset_category.js
+++ b/erpnext/assets/doctype/asset_category/asset_category.js
@@ -4,7 +4,7 @@
frappe.ui.form.on('Asset Category', {
onload: function(frm) {
frm.add_fetch('company_name', 'accumulated_depreciation_account', 'accumulated_depreciation_account');
- frm.add_fetch('company_name', 'depreciation_expense_account', 'accumulated_depreciation_account');
+ frm.add_fetch('company_name', 'depreciation_expense_account', 'depreciation_expense_account');
frm.set_query('fixed_asset_account', 'accounts', function(doc, cdt, cdn) {
var d = locals[cdt][cdn];
diff --git a/erpnext/projects/doctype/project/project.js b/erpnext/projects/doctype/project/project.js
index c5265e2..31460f6 100644
--- a/erpnext/projects/doctype/project/project.js
+++ b/erpnext/projects/doctype/project/project.js
@@ -87,7 +87,7 @@
frm.add_custom_button(__("Kanban Board"), () => {
frappe.call('erpnext.projects.doctype.project.project.create_kanban_board_if_not_exists', {
- project: frm.doc.project_name
+ project: frm.doc.name
}).then(() => {
frappe.set_route('List', 'Task', 'Kanban', frm.doc.project_name);
});
diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py
index 55c5149..c8fbe0b 100644
--- a/erpnext/projects/doctype/project/project.py
+++ b/erpnext/projects/doctype/project/project.py
@@ -523,8 +523,9 @@
def create_kanban_board_if_not_exists(project):
from frappe.desk.doctype.kanban_board.kanban_board import quick_kanban_board
- if not frappe.db.exists('Kanban Board', project):
- quick_kanban_board('Task', project, 'status', project)
+ project = frappe.get_doc('Project', project)
+ if not frappe.db.exists('Kanban Board', project.project_name):
+ quick_kanban_board('Task', project.project_name, 'status', project.name)
return True
diff --git a/erpnext/projects/doctype/task/task.js b/erpnext/projects/doctype/task/task.js
index 6a9d2d1..3cd92ee 100644
--- a/erpnext/projects/doctype/task/task.js
+++ b/erpnext/projects/doctype/task/task.js
@@ -5,12 +5,6 @@
frappe.ui.form.on("Task", {
setup: function (frm) {
- frm.set_query("project", function () {
- 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',
diff --git a/erpnext/regional/address_template/templates/united_states.html b/erpnext/regional/address_template/templates/united_states.html
index 089315e..77fce46 100644
--- a/erpnext/regional/address_template/templates/united_states.html
+++ b/erpnext/regional/address_template/templates/united_states.html
@@ -1,4 +1,4 @@
{{ address_line1 }}<br>
{% if address_line2 %}{{ address_line2 }}<br>{% endif -%}
{{ city }}, {% if state %}{{ state }}{% endif -%}{% if pincode %} {{ pincode }}<br>{% endif -%}
-{% if country != "United States" %}{{ country|upper }}{% endif -%}
+{% if country != "United States" %}{{ country }}{% endif -%}
diff --git a/erpnext/regional/india/e_invoice/utils.py b/erpnext/regional/india/e_invoice/utils.py
index b4e7a88..70e6d07 100644
--- a/erpnext/regional/india/e_invoice/utils.py
+++ b/erpnext/regional/india/e_invoice/utils.py
@@ -43,8 +43,9 @@
invalid_supply_type = doc.get('gst_category') not in ['Registered Regular', 'SEZ', 'Overseas', 'Deemed Export']
company_transaction = doc.get('billing_address_gstin') == doc.get('company_gstin')
no_taxes_applied = not doc.get('taxes')
+ has_non_gst_item = any(d for d in doc.get('items') if d.get('is_non_gst'))
- if invalid_company or invalid_supply_type or company_transaction or no_taxes_applied:
+ if invalid_company or invalid_supply_type or company_transaction or no_taxes_applied or has_non_gst_item:
return False
return True
diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py
index ca679e4..fc227de 100644
--- a/erpnext/regional/india/utils.py
+++ b/erpnext/regional/india/utils.py
@@ -695,7 +695,7 @@
filters=filters,
fields=["cgst_account", "sgst_account", "igst_account", "cess_account"])
- if not gst_settings_accounts and not frappe.flags.in_test:
+ if not gst_settings_accounts and not frappe.flags.in_test and not frappe.flags.in_migrate:
frappe.throw(_("Please set GST Accounts in GST Settings"))
for d in gst_settings_accounts:
diff --git a/erpnext/stock/dashboard/item_dashboard.js b/erpnext/stock/dashboard/item_dashboard.js
index 933ca8a..db05739 100644
--- a/erpnext/stock/dashboard/item_dashboard.js
+++ b/erpnext/stock/dashboard/item_dashboard.js
@@ -230,6 +230,7 @@
},
],
});
+ var submitted = false;
dialog.show();
dialog.get_field('item_code').set_input(item);
@@ -253,6 +254,7 @@
}
dialog.set_primary_action(__('Submit'), function () {
+ if(submitted) return;
var values = dialog.get_values();
if (!values) {
return;
@@ -265,6 +267,7 @@
frappe.msgprint(__('Source and target warehouse must be different'));
}
+ submitted = true;
frappe.call({
method: 'erpnext.stock.doctype.stock_entry.stock_entry_utils.make_stock_entry',
args: values,
diff --git a/erpnext/stock/doctype/landed_cost_taxes_and_charges/landed_cost_taxes_and_charges.json b/erpnext/stock/doctype/landed_cost_taxes_and_charges/landed_cost_taxes_and_charges.json
index 4fcdb4c..9c59c13 100644
--- a/erpnext/stock/doctype/landed_cost_taxes_and_charges/landed_cost_taxes_and_charges.json
+++ b/erpnext/stock/doctype/landed_cost_taxes_and_charges/landed_cost_taxes_and_charges.json
@@ -10,8 +10,8 @@
"exchange_rate",
"description",
"col_break3",
- "base_amount",
- "amount"
+ "amount",
+ "base_amount"
],
"fields": [
{
@@ -59,7 +59,7 @@
{
"fieldname": "base_amount",
"fieldtype": "Currency",
- "label": "Base Amount",
+ "label": "Amount (Company Currency)",
"options": "Company:company:default_currency",
"read_only": 1
}
@@ -67,7 +67,7 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
- "modified": "2020-12-26 01:07:23.233604",
+ "modified": "2021-05-17 13:57:10.807980",
"modified_by": "Administrator",
"module": "Stock",
"name": "Landed Cost Taxes and Charges",