Merge branch 'version-12-hotfix' into validation-for-disabled-warehouse-v12

This commit is contained in:
Marica
2021-02-11 13:04:49 +05:30
committed by GitHub
10 changed files with 84 additions and 33 deletions

View File

@@ -41,6 +41,8 @@ frappe.ui.form.on('Accounting Dimension', {
});
});
}
frm.toggle_enable('document_type', frm.doc.__islocal);
},
document_type: function(frm) {

View File

@@ -29,6 +29,16 @@ class AccountingDimension(Document):
if exists and self.is_new():
frappe.throw("Document Type already used as a dimension")
if not self.is_new():
self.validate_document_type_change()
def validate_document_type_change(self):
doctype_before_save = frappe.db.get_value("Accounting Dimension", self.name, "document_type")
if doctype_before_save != self.document_type:
message = _("Cannot change Reference Document Type.")
message += _("Please create a new Accounting Dimension if required.")
frappe.throw(message)
def after_insert(self):
if frappe.flags.in_test:
make_dimension_in_accounting_doctypes(doc=self)

View File

@@ -88,18 +88,18 @@ class PaymentReconciliation(Document):
voucher_type = ('Sales Invoice'
if self.party_type == 'Customer' else "Purchase Invoice")
return frappe.db.sql(""" SELECT `tab{doc}`.name as reference_name, %(voucher_type)s as reference_type,
(sum(`tabGL Entry`.{dr_or_cr}) - sum(`tabGL Entry`.{reconciled_dr_or_cr})) as amount,
return frappe.db.sql(""" SELECT doc.name as reference_name, %(voucher_type)s as reference_type,
(sum(gl.{dr_or_cr}) - sum(gl.{reconciled_dr_or_cr})) as amount,
account_currency as currency
FROM `tab{doc}`, `tabGL Entry`
FROM `tab{doc}` doc, `tabGL Entry` gl
WHERE
(`tab{doc}`.name = `tabGL Entry`.against_voucher or `tab{doc}`.name = `tabGL Entry`.voucher_no)
and `tab{doc}`.{party_type_field} = %(party)s
and `tab{doc}`.is_return = 1 and `tab{doc}`.return_against IS NULL
and `tabGL Entry`.against_voucher_type = %(voucher_type)s
and `tab{doc}`.docstatus = 1 and `tabGL Entry`.party = %(party)s
and `tabGL Entry`.party_type = %(party_type)s and `tabGL Entry`.account = %(account)s
GROUP BY `tab{doc}`.name
(doc.name = gl.against_voucher or doc.name = gl.voucher_no)
and doc.{party_type_field} = %(party)s
and doc.is_return = 1 and ifnull(doc.return_against, "") = ""
and gl.against_voucher_type = %(voucher_type)s
and doc.docstatus = 1 and gl.party = %(party)s
and gl.party_type = %(party_type)s and gl.account = %(account)s
GROUP BY doc.name
Having
amount > 0
""".format(
@@ -112,7 +112,7 @@ class PaymentReconciliation(Document):
'party_type': self.party_type,
'voucher_type': voucher_type,
'account': self.receivable_payable_account
}, as_dict=1)
}, as_dict=1, debug=1)
def add_payment_entries(self, entries):
self.set('payments', [])

View File

@@ -206,7 +206,7 @@ def get_data(companies, root_type, balance_must_be, fiscal_year, filters=None, i
set_gl_entries_by_account(fiscal_year.year_start_date,
fiscal_year.year_end_date, root.lft, root.rgt, filters,
gl_entries_by_account, accounts_by_name, ignore_closing_entries=False)
gl_entries_by_account, accounts_by_name, accounts, ignore_closing_entries=False)
calculate_values(accounts_by_name, gl_entries_by_account, companies, fiscal_year, filters)
accumulate_values_into_parents(accounts, accounts_by_name, companies)
@@ -325,7 +325,7 @@ def prepare_data(accounts, fiscal_year, balance_must_be, companies, company_curr
return data
def set_gl_entries_by_account(from_date, to_date, root_lft, root_rgt, filters, gl_entries_by_account,
accounts_by_name, ignore_closing_entries=False):
accounts_by_name, accounts, ignore_closing_entries=False):
"""Returns a dict like { "account": [gl entries], ... }"""
company_lft, company_rgt = frappe.get_cached_value('Company',
@@ -368,15 +368,31 @@ def set_gl_entries_by_account(from_date, to_date, root_lft, root_rgt, filters, g
for entry in gl_entries:
key = entry.account_number or entry.account_name
validate_entries(key, entry, accounts_by_name)
validate_entries(key, entry, accounts_by_name, accounts)
gl_entries_by_account.setdefault(key, []).append(entry)
return gl_entries_by_account
def validate_entries(key, entry, accounts_by_name):
def get_account_details(account):
return frappe.get_cached_value('Account', account, ['name', 'report_type', 'root_type', 'company',
'is_group', 'account_name', 'account_number', 'parent_account', 'lft', 'rgt'], as_dict=1)
def validate_entries(key, entry, accounts_by_name, accounts):
if key not in accounts_by_name:
field = "Account number" if entry.account_number else "Account name"
frappe.throw(_("{0} {1} is not present in the parent company").format(field, key))
args = get_account_details(entry.account)
if args.parent_account:
parent_args = get_account_details(args.parent_account)
args.update({
'lft': parent_args.lft + 1,
'rgt': parent_args.rgt - 1,
'root_type': parent_args.root_type,
'report_type': parent_args.report_type
})
accounts_by_name.setdefault(key, args)
accounts.append(args)
def get_additional_conditions(from_date, ignore_closing_entries, filters):
additional_conditions = []

View File

@@ -54,8 +54,8 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
row = {
'item_code': d.item_code,
'item_name': item_record.item_name,
'item_group': item_record.item_group,
'item_name': item_record.item_name if item_record else d.item_name,
'item_group': item_record.item_group if item_record else d.item_group,
'description': d.description,
'invoice': d.parent,
'posting_date': d.posting_date,
@@ -324,6 +324,7 @@ def get_items(filters, additional_query_columns):
`tabPurchase Invoice`.posting_date, `tabPurchase Invoice`.credit_to, `tabPurchase Invoice`.company,
`tabPurchase Invoice`.supplier, `tabPurchase Invoice`.remarks, `tabPurchase Invoice`.base_net_total,
`tabPurchase Invoice Item`.`item_code`, `tabPurchase Invoice Item`.description,
`tabPurchase Invoice Item`.`item_name`, `tabPurchase Invoice Item`.`item_group`,
`tabPurchase Invoice Item`.`project`, `tabPurchase Invoice Item`.`purchase_order`,
`tabPurchase Invoice Item`.`purchase_receipt`, `tabPurchase Invoice Item`.`po_detail`,
`tabPurchase Invoice Item`.`expense_account`, `tabPurchase Invoice Item`.`stock_qty`,

View File

@@ -53,8 +53,8 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
row = {
'item_code': d.item_code,
'item_name': item_record.item_name,
'item_group': item_record.item_group,
'item_name': item_record.item_name if item_record else d.item_name,
'item_group': item_record.item_group if item_record else d.item_group,
'description': d.description,
'invoice': d.parent,
'posting_date': d.posting_date,
@@ -390,6 +390,7 @@ def get_items(filters, additional_query_columns):
`tabSales Invoice`.project, `tabSales Invoice`.customer, `tabSales Invoice`.remarks,
`tabSales Invoice`.territory, `tabSales Invoice`.company, `tabSales Invoice`.base_net_total,
`tabSales Invoice Item`.item_code, `tabSales Invoice Item`.description,
`tabSales Invoice Item`.`item_name`, `tabSales Invoice Item`.`item_group`,
`tabSales Invoice Item`.sales_order, `tabSales Invoice Item`.delivery_note,
`tabSales Invoice Item`.income_account, `tabSales Invoice Item`.cost_center,
`tabSales Invoice Item`.stock_qty, `tabSales Invoice Item`.stock_uom,

View File

@@ -1397,6 +1397,7 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
parent.flags.ignore_validate_update_after_submit = True
parent.set_qty_as_per_stock_uom()
parent.calculate_taxes_and_totals()
parent.set_total_in_words()
if parent_doctype == "Sales Order":
make_packing_list(parent)
parent.set_gross_profit()

View File

@@ -20,11 +20,13 @@ from frappe.utils.data import cstr, cint, formatdate as format_date, flt, time_d
def validate_einvoice_fields(doc):
einvoicing_enabled = cint(frappe.db.get_value('E Invoice Settings', 'E Invoice Settings', 'enable'))
invalid_doctype = doc.doctype not in ['Sales Invoice']
invalid_doctype = doc.doctype != 'Sales Invoice'
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 = len(doc.get('taxes', [])) == 0
if not einvoicing_enabled or invalid_doctype or invalid_supply_type or company_transaction: return
if not einvoicing_enabled or invalid_doctype or invalid_supply_type or company_transaction or no_taxes_applied:
return
if doc.docstatus == 0 and doc._action == 'save':
if doc.irn:
@@ -303,7 +305,7 @@ def validate_mandatory_fields(invoice):
_('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'):
if invoice.gst_category != 'Overseas' and 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')
@@ -330,7 +332,10 @@ def make_einvoice(invoice):
shipping_details = payment_details = prev_doc_details = eway_bill_details = frappe._dict({})
if invoice.shipping_address_name and invoice.customer_address != invoice.shipping_address_name:
shipping_details = get_party_details(invoice.shipping_address_name)
if invoice.gst_category == 'Overseas':
shipping_details = get_overseas_address_details(invoice.shipping_address_name)
else:
shipping_details = get_party_details(invoice.shipping_address_name)
if invoice.is_pos and invoice.base_paid_amount:
payment_details = get_payment_details(invoice)

View File

@@ -32,6 +32,10 @@ def execute(filters=None):
data = []
columns = get_columns()
conditions = ""
if filters.supplier_group:
conditions += "AND s.supplier_group = %s" %frappe.db.escape(filters.get("supplier_group"))
data = frappe.db.sql("""
SELECT
s.supplier_group as "supplier_group",
@@ -46,15 +50,17 @@ def execute(filters=None):
AND s.irs_1099 = 1
AND gl.fiscal_year = %(fiscal_year)s
AND gl.party_type = "Supplier"
AND gl.company = %(company)s
{conditions}
GROUP BY
gl.party
ORDER BY
gl.party DESC
""", {
"fiscal_year": filters.fiscal_year,
"supplier_group": filters.supplier_group,
"company": filters.company
}, as_dict=True)
gl.party DESC""".format(conditions=conditions), {
"fiscal_year": filters.fiscal_year,
"company": filters.company
}, as_dict=True)
return columns, data
@@ -79,13 +85,13 @@ def get_columns():
"fieldname": "tax_id",
"label": _("Tax ID"),
"fieldtype": "Data",
"width": 120
"width": 200
},
{
"fieldname": "payments",
"label": _("Total Payments"),
"fieldtype": "Currency",
"width": 120
"width": 200
}
]

View File

@@ -324,6 +324,9 @@ class TestSalesOrder(unittest.TestCase):
create_dn_against_so(so.name, 4)
make_sales_invoice(so.name)
prev_total = so.get("base_total")
prev_total_in_words = so.get("base_in_words")
first_item_of_so = so.get("items")[0]
trans_item = json.dumps([
{'item_code' : first_item_of_so.item_code, 'rate' : first_item_of_so.rate, \
@@ -339,6 +342,12 @@ class TestSalesOrder(unittest.TestCase):
self.assertEqual(so.get("items")[-1].amount, 1400)
self.assertEqual(so.status, 'To Deliver and Bill')
updated_total = so.get("base_total")
updated_total_in_words = so.get("base_in_words")
self.assertEqual(updated_total, prev_total+1400)
self.assertNotEqual(updated_total_in_words, prev_total_in_words)
def test_update_child_removing_item(self):
so = make_sales_order(**{
"item_list": [{