Merge branch 'version-12-hotfix' into mr-se-warehouse-validation-hotfix

This commit is contained in:
Marica
2021-01-12 20:17:41 +05:30
committed by GitHub
7 changed files with 134 additions and 80 deletions

View File

@@ -187,7 +187,7 @@ frappe.ui.form.on('Payment Entry', {
frm.toggle_display("base_received_amount", (
frm.doc.paid_to_account_currency != company_currency &&
frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency
frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency
&& frm.doc.base_paid_amount != frm.doc.base_received_amount
));
@@ -386,6 +386,8 @@ frappe.ui.form.on('Payment Entry', {
set_account_currency_and_balance: function(frm, account, currency_field,
balance_field, callback_function) {
var company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency;
if (frm.doc.posting_date && account) {
frappe.call({
method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_account_details",
@@ -412,6 +414,14 @@ frappe.ui.form.on('Payment Entry', {
if(!frm.doc.paid_amount && frm.doc.received_amount)
frm.events.received_amount(frm);
if (frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency
&& frm.doc.paid_amount != frm.doc.received_amount) {
if (company_currency != frm.doc.paid_from_account_currency &&
frm.doc.payment_type == "Pay") {
frm.doc.paid_amount = frm.doc.received_amount;
}
}
}
},
() => {

View File

@@ -8,6 +8,7 @@ from frappe.utils import flt
from erpnext.accounts.report.item_wise_sales_register.item_wise_sales_register import (get_tax_accounts,
get_grand_total, add_total_row, get_display_value, get_group_by_and_display_fields, add_sub_total_row,
get_group_by_conditions)
from erpnext.selling.report.item_wise_sales_history.item_wise_sales_history import get_item_details
def execute(filters=None):
return _execute(filters)
@@ -23,7 +24,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
aii_account_map = get_aii_accounts()
if item_list:
itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency,
doctype="Purchase Invoice", tax_doctype="Purchase Taxes and Charges")
doctype='Purchase Invoice', tax_doctype='Purchase Taxes and Charges')
po_pr_map = get_purchase_receipts_against_purchase_order(item_list)
@@ -35,10 +36,14 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
if filters.get('group_by'):
grand_total = get_grand_total(filters, 'Purchase Invoice')
item_details = get_item_details()
for d in item_list:
if not d.stock_qty:
continue
item_record = item_details.get(d.item_code)
purchase_receipt = None
if d.purchase_receipt:
purchase_receipt = d.purchase_receipt
@@ -49,8 +54,8 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
row = {
'item_code': d.item_code,
'item_name': d.item_name,
'item_group': d.item_group,
'item_name': item_record.item_name,
'item_group': item_record.item_group,
'description': d.description,
'invoice': d.parent,
'posting_date': d.posting_date,
@@ -82,10 +87,10 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
for tax in tax_columns:
item_tax = itemised_tax.get(d.name, {}).get(tax, {})
row.update({
frappe.scrub(tax + ' Rate'): item_tax.get("tax_rate", 0),
frappe.scrub(tax + ' Amount'): item_tax.get("tax_amount", 0),
frappe.scrub(tax + ' Rate'): item_tax.get('tax_rate', 0),
frappe.scrub(tax + ' Amount'): item_tax.get('tax_amount', 0),
})
total_tax += flt(item_tax.get("tax_amount"))
total_tax += flt(item_tax.get('tax_amount'))
row.update({
'total_tax': total_tax,
@@ -317,8 +322,8 @@ def get_items(filters, additional_query_columns):
select
`tabPurchase Invoice Item`.`name`, `tabPurchase Invoice Item`.`parent`,
`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`.`item_name`, `tabPurchase Invoice Item`.`item_group`, `tabPurchase Invoice Item`.description,
`tabPurchase Invoice`.supplier, `tabPurchase Invoice`.remarks, `tabPurchase Invoice`.base_net_total,
`tabPurchase Invoice Item`.`item_code`, `tabPurchase Invoice Item`.description,
`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

@@ -8,6 +8,7 @@ from frappe.utils import flt, cstr
from frappe.model.meta import get_field_precision
from frappe.utils.xlsxutils import handle_html
from erpnext.accounts.report.sales_register.sales_register import get_mode_of_payments
from erpnext.selling.report.item_wise_sales_history.item_wise_sales_history import get_item_details, get_customer_details
def execute(filters=None):
return _execute(filters)
@@ -17,7 +18,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
filters.update({"from_date": filters.get("date_range") and filters.get("date_range")[0], "to_date": filters.get("date_range") and filters.get("date_range")[1]})
columns = get_columns(additional_table_columns, filters)
company_currency = frappe.get_cached_value('Company', filters.get("company"), "default_currency")
company_currency = frappe.get_cached_value('Company', filters.get('company'), 'default_currency')
item_list = get_items(filters, additional_query_columns)
if item_list:
@@ -34,7 +35,13 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
if filters.get('group_by'):
grand_total = get_grand_total(filters, 'Sales Invoice')
customer_details = get_customer_details()
item_details = get_item_details()
for d in item_list:
customer_record = customer_details.get(d.customer)
item_record = item_details.get(d.item_code)
delivery_note = None
if d.delivery_note:
delivery_note = d.delivery_note
@@ -46,14 +53,14 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
row = {
'item_code': d.item_code,
'item_name': d.item_name,
'item_group': d.item_group,
'item_name': item_record.item_name,
'item_group': item_record.item_group,
'description': d.description,
'invoice': d.parent,
'posting_date': d.posting_date,
'customer': d.customer,
'customer_name': d.customer_name,
'customer_group': d.customer_group,
'customer_name': customer_record.customer_name,
'customer_group': customer_record.customer_group,
}
if additional_query_columns:
@@ -91,10 +98,10 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
for tax in tax_columns:
item_tax = itemised_tax.get(d.name, {}).get(tax, {})
row.update({
frappe.scrub(tax + ' Rate'): item_tax.get("tax_rate", 0),
frappe.scrub(tax + ' Amount'): item_tax.get("tax_amount", 0),
frappe.scrub(tax + ' Rate'): item_tax.get('tax_rate', 0),
frappe.scrub(tax + ' Amount'): item_tax.get('tax_amount', 0),
})
total_tax += flt(item_tax.get("tax_amount"))
total_tax += flt(item_tax.get('tax_amount'))
row.update({
'total_tax': total_tax,
@@ -227,7 +234,7 @@ def get_columns(additional_table_columns, filters):
if filters.get('group_by') != 'Terriotory':
columns.extend([
{
'label': _("Territory"),
'label': _('Territory'),
'fieldname': 'territory',
'fieldtype': 'Link',
'options': 'Territory',
@@ -382,13 +389,12 @@ def get_items(filters, additional_query_columns):
`tabSales Invoice`.posting_date, `tabSales Invoice`.debit_to,
`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`.item_name,
`tabSales Invoice Item`.item_group, `tabSales Invoice Item`.description, `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, `tabSales Invoice Item`.base_net_rate,
`tabSales Invoice Item`.base_net_amount, `tabSales Invoice`.customer_name,
`tabSales Invoice`.customer_group, `tabSales Invoice Item`.so_detail,
`tabSales Invoice Item`.item_code, `tabSales Invoice Item`.description,
`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,
`tabSales Invoice Item`.base_net_rate, `tabSales Invoice Item`.base_net_amount,
`tabSales Invoice`.customer_name, `tabSales Invoice`.customer_group, `tabSales Invoice Item`.so_detail,
`tabSales Invoice`.update_stock, `tabSales Invoice Item`.uom, `tabSales Invoice Item`.qty {0}
from `tabSales Invoice`, `tabSales Invoice Item`
where `tabSales Invoice`.name = `tabSales Invoice Item`.parent
@@ -425,14 +431,14 @@ def get_deducted_taxes():
return frappe.db.sql_list("select name from `tabPurchase Taxes and Charges` where add_deduct_tax = 'Deduct'")
def get_tax_accounts(item_list, columns, company_currency,
doctype="Sales Invoice", tax_doctype="Sales Taxes and Charges"):
doctype='Sales Invoice', tax_doctype='Sales Taxes and Charges'):
import json
item_row_map = {}
tax_columns = []
invoice_item_row = {}
itemised_tax = {}
tax_amount_precision = get_field_precision(frappe.get_meta(tax_doctype).get_field("tax_amount"),
tax_amount_precision = get_field_precision(frappe.get_meta(tax_doctype).get_field('tax_amount'),
currency=company_currency) or 2
for d in item_list:
@@ -477,8 +483,8 @@ def get_tax_accounts(item_list, columns, company_currency,
tax_rate = tax_data
tax_amount = 0
if charge_type == "Actual" and not tax_rate:
tax_rate = "NA"
if charge_type == 'Actual' and not tax_rate:
tax_rate = 'NA'
item_net_amount = sum([flt(d.base_net_amount)
for d in item_row_map.get(parent, {}).get(item_code, [])])
@@ -492,17 +498,17 @@ def get_tax_accounts(item_list, columns, company_currency,
if (doctype == 'Purchase Invoice' and name in deducted_tax) else tax_value)
itemised_tax.setdefault(d.name, {})[description] = frappe._dict({
"tax_rate": tax_rate,
"tax_amount": tax_value
'tax_rate': tax_rate,
'tax_amount': tax_value
})
except ValueError:
continue
elif charge_type == "Actual" and tax_amount:
elif charge_type == 'Actual' and tax_amount:
for d in invoice_item_row.get(parent, []):
itemised_tax.setdefault(d.name, {})[description] = frappe._dict({
"tax_rate": "NA",
"tax_amount": flt((tax_amount * d.base_net_amount) / d.base_net_total,
'tax_rate': 'NA',
'tax_amount': flt((tax_amount * d.base_net_amount) / d.base_net_total,
tax_amount_precision)
})
@@ -564,7 +570,7 @@ def add_total_row(data, filters, prev_group_by_value, item, total_row_map,
})
total_row_map.setdefault('total_row', {
subtotal_display_field: "Total",
subtotal_display_field: 'Total',
'stock_qty': 0.0,
'amount': 0.0,
'bold': 1,

View File

@@ -782,7 +782,7 @@
"icon": "fa fa-user",
"idx": 24,
"image_field": "image",
"modified": "2020-01-09 04:23:55.611366",
"modified": "2020-01-09 05:23:55.611366",
"modified_by": "Administrator",
"module": "HR",
"name": "Employee",
@@ -824,7 +824,6 @@
"write": 1
}
],
"quick_entry": 1,
"search_fields": "employee_name",
"show_name_in_global_search": 1,
"sort_field": "modified",

View File

@@ -299,14 +299,17 @@ class SalarySlip(TransactionBase):
def calculate_net_pay(self):
if self.salary_structure:
self.calculate_component_amounts("earnings")
self.gross_pay = self.get_component_totals("earnings")
self.gross_pay = self.get_component_totals("earnings", depends_on_payment_days=1)
if self.salary_structure:
self.calculate_component_amounts("deductions")
self.total_deduction = self.get_component_totals("deductions")
self.set_loan_repayment()
self.set_component_amounts_based_on_payment_days()
self.set_net_pay()
def set_net_pay(self):
self.total_deduction = self.get_component_totals("deductions")
self.net_pay = flt(self.gross_pay) - (flt(self.total_deduction) + flt(self.total_loan_repayment))
self.rounded_total = rounded(self.net_pay)
@@ -323,8 +326,6 @@ class SalarySlip(TransactionBase):
else:
self.add_tax_components(payroll_period)
self.set_component_amounts_based_on_payment_days(component_type)
def add_structure_components(self, component_type):
data = self.get_data_for_eval()
for struct_row in self._salary_structure_doc.get(component_type):
@@ -679,7 +680,7 @@ class SalarySlip(TransactionBase):
cint(row.depends_on_payment_days) and cint(self.total_working_days) and
(not self.salary_slip_based_on_timesheet or
getdate(self.start_date) < joining_date or
getdate(self.end_date) > relieving_date
(relieving_date and getdate(self.end_date) > relieving_date)
)):
additional_amount = flt((flt(row.additional_amount) * flt(self.payment_days)
/ cint(self.total_working_days)), row.precision("additional_amount"))
@@ -812,15 +813,21 @@ class SalarySlip(TransactionBase):
struct_row['variable_based_on_taxable_salary'] = component.variable_based_on_taxable_salary
return struct_row
def get_component_totals(self, component_type):
def get_component_totals(self, component_type, depends_on_payment_days=0):
joining_date, relieving_date = frappe.get_cached_value("Employee", self.employee,
["date_of_joining", "relieving_date"])
total = 0.0
for d in self.get(component_type):
if not d.do_not_include_in_total:
d.amount = flt(d.amount, d.precision("amount"))
total += d.amount
if depends_on_payment_days:
amount = self.get_amount_based_on_payment_days(d, joining_date, relieving_date)[0]
else:
amount = flt(d.amount, d.precision("amount"))
total += amount
return total
def set_component_amounts_based_on_payment_days(self, component_type):
def set_component_amounts_based_on_payment_days(self):
joining_date, relieving_date = frappe.get_cached_value("Employee", self.employee,
["date_of_joining", "relieving_date"])
@@ -830,8 +837,9 @@ class SalarySlip(TransactionBase):
if not joining_date:
frappe.throw(_("Please set the Date Of Joining for employee {0}").format(frappe.bold(self.employee_name)))
for d in self.get(component_type):
d.amount = self.get_amount_based_on_payment_days(d, joining_date, relieving_date)[0]
for component_type in ("earnings", "deductions"):
for d in self.get(component_type):
d.amount = flt(self.get_amount_based_on_payment_days(d, joining_date, relieving_date)[0], d.precision("amount"))
def set_loan_repayment(self):
self.set('loans', [])

View File

@@ -15,7 +15,7 @@ from frappe import _, bold
from pyqrcode import create as qrcreate
from frappe.integrations.utils import make_post_request, make_get_request
from erpnext.regional.india.utils import get_gst_accounts, get_place_of_supply
from frappe.utils.data import cstr, cint, formatdate as format_date, flt, time_diff_in_seconds, now_datetime, add_to_date
from frappe.utils.data import cstr, cint, formatdate as format_date, flt, time_diff_in_seconds, now_datetime, add_to_date, get_link_to_form
def validate_einvoice_fields(doc):
einvoicing_enabled = cint(frappe.db.get_value('E Invoice Settings', 'E Invoice Settings', 'enable'))
@@ -84,26 +84,32 @@ def get_doc_details(invoice):
))
def get_party_details(address_name):
address = frappe.get_all('Address', filters={'name': address_name}, fields=['*'])[0]
gstin = address.get('gstin')
d = frappe.get_all('Address', filters={'name': address_name}, fields=['*'])[0]
gstin_details = get_gstin_details(gstin)
legal_name = gstin_details.get('LegalName') or gstin_details.get('TradeName')
location = gstin_details.get('AddrLoc') or address.get('city')
state_code = gstin_details.get('StateCode')
pincode = gstin_details.get('AddrPncd')
address_line1 = '{} {}'.format(gstin_details.get('AddrBno') or "", gstin_details.get('AddrFlno') or "")
address_line2 = '{} {}'.format(gstin_details.get('AddrBnm') or "", gstin_details.get('AddrSt') or "")
if (not d.gstin
or not d.city
or not d.pincode
or not d.address_title
or not d.address_line1
or not d.gst_state_number):
if state_code == 97:
frappe.throw(
msg=_('Address lines, city, pincode, gstin is mandatory for address {}. Please set them and try again.').format(
get_link_to_form('Address', address_name)
),
title=_('Missing Address Fields')
)
if d.gst_state_number == 97:
# according to einvoice standard
pincode = 999999
return frappe._dict(dict(
gstin=gstin, legal_name=legal_name,
location=location, pincode=pincode,
state_code=state_code, address_line1=address_line1,
address_line2=address_line2
gstin=d.gstin, legal_name=d.address_title,
location=d.city, pincode=d.pincode,
state_code=d.gst_state_number,
address_line1=d.address_line1,
address_line2=d.address_line2
))
def get_gstin_details(gstin):
@@ -124,14 +130,22 @@ def get_gstin_details(gstin):
return GSPConnector.get_gstin_details(gstin)
def get_overseas_address_details(address_name):
address_title, address_line1, address_line2, city, phone, email_id = frappe.db.get_value(
'Address', address_name, ['address_title', 'address_line1', 'address_line2', 'city', 'phone', 'email_id']
address_title, address_line1, address_line2, city = frappe.db.get_value(
'Address', address_name, ['address_title', 'address_line1', 'address_line2', 'city']
)
if not address_title or not address_line1 or not city:
frappe.throw(
msg=_('Address lines and city is mandatory for address {}. Please set them and try again.').format(
get_link_to_form('Address', address_name)
),
title=_('Missing Address Fields')
)
return frappe._dict(dict(
gstin='URP', legal_name=address_title, address_line1=address_line1,
address_line2=address_line2, email=email_id, phone=phone,
pincode=999999, state_code=96, place_of_supply=96, location=city
gstin='URP', legal_name=address_title, location=city,
address_line1=address_line1, address_line2=address_line2,
pincode=999999, state_code=96, place_of_supply=96
))
def get_item_list(invoice):

View File

@@ -10,8 +10,8 @@ from frappe.utils.nestedset import get_descendants_of
def execute(filters=None):
filters = frappe._dict(filters or {})
if filters.from_date > filters.to_date:
frappe.throw(_('From Date cannot be greater than To Date'))
frappe.throw(_("From Date cannot be greater than To Date"))
columns = get_columns(filters)
data = get_data(filters)
return columns, data
@@ -145,14 +145,16 @@ def get_data(filters):
company_list.append(filters.get("company"))
customer_details = get_customer_details()
item_details = get_item_details()
sales_order_records = get_sales_order_details(company_list, filters)
for record in sales_order_records:
customer_record = customer_details.get(record.customer)
item_record = item_details.get(record.item_code)
row = {
"item_code": record.item_code,
"item_name": record.item_name,
"item_group": record.item_group,
"item_name": item_record.item_name,
"item_group": item_record.item_group,
"description": record.description,
"quantity": record.qty,
"uom": record.uom,
@@ -187,8 +189,8 @@ def get_conditions(filters):
return conditions
def get_customer_details():
details = frappe.get_all('Customer',
fields=['name', 'customer_name', "customer_group"])
details = frappe.get_all("Customer",
fields=["name", "customer_name", "customer_group"])
customer_details = {}
for d in details:
customer_details.setdefault(d.name, frappe._dict({
@@ -197,15 +199,25 @@ def get_customer_details():
}))
return customer_details
def get_item_details():
details = frappe.db.get_all("Item",
fields=["item_code", "item_name", "item_group"])
item_details = {}
for d in details:
item_details.setdefault(d.item_code, frappe._dict({
"item_name": d.item_name,
"item_group": d.item_group
}))
return item_details
def get_sales_order_details(company_list, filters):
conditions = get_conditions(filters)
return frappe.db.sql("""
SELECT
so_item.item_code, so_item.item_name, so_item.item_group,
so_item.description, so_item.qty, so_item.uom,
so_item.base_rate, so_item.base_amount, so.name,
so.transaction_date, so.customer, so.territory,
so_item.item_code, so_item.description, so_item.qty,
so_item.uom, so_item.base_rate, so_item.base_amount,
so.name, so.transaction_date, so.customer,so.territory,
so.project, so_item.delivered_qty,
so_item.billed_amt, so.company
FROM