Merge branch 'version-12-hotfix' into incorrect-qty-after-transaction-stock-reco

This commit is contained in:
Marica
2020-07-20 11:34:29 +05:30
committed by GitHub
19 changed files with 374 additions and 278 deletions

View File

@@ -322,7 +322,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

@@ -413,6 +413,8 @@ class PurchaseInvoice(BuyingController):
self.make_tax_gl_entries(gl_entries) self.make_tax_gl_entries(gl_entries)
gl_entries = make_regional_gl_entries(gl_entries, self)
gl_entries = merge_similar_entries(gl_entries) gl_entries = merge_similar_entries(gl_entries)
self.make_payment_gl_entries(gl_entries) self.make_payment_gl_entries(gl_entries)
@@ -1026,6 +1028,10 @@ def get_list_context(context=None):
}) })
return list_context return list_context
@erpnext.allow_regional
def make_regional_gl_entries(gl_entries, doc):
return gl_entries
@frappe.whitelist() @frappe.whitelist()
def make_debit_note(source_name, target_doc=None): def make_debit_note(source_name, target_doc=None):
from erpnext.controllers.sales_and_purchase_return import make_return_doc from erpnext.controllers.sales_and_purchase_return import make_return_doc

View File

@@ -1105,7 +1105,10 @@ class SalesInvoice(SellingController):
expiry_date=self.posting_date, include_expired_entry=True) expiry_date=self.posting_date, include_expired_entry=True)
if lp_details and getdate(lp_details.from_date) <= getdate(self.posting_date) and \ if lp_details and getdate(lp_details.from_date) <= getdate(self.posting_date) and \
(not lp_details.to_date or getdate(lp_details.to_date) >= getdate(self.posting_date)): (not lp_details.to_date or getdate(lp_details.to_date) >= getdate(self.posting_date)):
points_earned = cint(eligible_amount/lp_details.collection_factor)
collection_factor = lp_details.collection_factor if lp_details.collection_factor else 1.0
points_earned = cint(eligible_amount/collection_factor)
doc = frappe.get_doc({ doc = frappe.get_doc({
"doctype": "Loyalty Point Entry", "doctype": "Loyalty Point Entry",
"company": self.company, "company": self.company,

View File

@@ -8,6 +8,7 @@ from __future__ import unicode_literals
import re import re
from past.builtins import cmp from past.builtins import cmp
import functools import functools
import math
import frappe, erpnext import frappe, erpnext
from erpnext.accounts.report.utils import get_currency, convert_to_presentation_currency from erpnext.accounts.report.utils import get_currency, convert_to_presentation_currency
@@ -42,7 +43,7 @@ def get_period_list(from_fiscal_year, to_fiscal_year, periodicity, accumulated_v
start_date = year_start_date start_date = year_start_date
months = get_months(year_start_date, year_end_date) months = get_months(year_start_date, year_end_date)
for i in range(months // months_to_add): for i in range(math.ceil(months / months_to_add)):
period = frappe._dict({ period = frappe._dict({
"from_date": start_date "from_date": start_date
}) })

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

@@ -195,10 +195,21 @@ def create_sensitivity():
def add_healthcare_service_unit_tree_root(): def add_healthcare_service_unit_tree_root():
record = [ record = [
{ {
"doctype": "Healthcare Service Unit", "doctype": "Healthcare Service Unit",
"healthcare_service_unit_name": "All Healthcare Service Units", "healthcare_service_unit_name": "All Healthcare Service Units",
"is_group": 1 "is_group": 1,
} "company": get_company()
}
] ]
insert_record(record) insert_record(record)
def get_company():
company = frappe.defaults.get_defaults().company
if company:
return company
else:
company = frappe.get_list("Company", limit=1)
if company:
return company[0].name
return None

View File

@@ -245,7 +245,7 @@ doc_events = {
"on_trash": "erpnext.regional.check_deletion_permission" "on_trash": "erpnext.regional.check_deletion_permission"
}, },
"Purchase Invoice": { "Purchase Invoice": {
"on_submit": "erpnext.regional.india.utils.make_reverse_charge_entries" "validate": "erpnext.regional.india.utils.update_grand_total_for_rcm"
}, },
"Payment Entry": { "Payment Entry": {
"on_submit": ["erpnext.regional.create_transaction_log", "erpnext.accounts.doctype.payment_request.payment_request.update_payment_req_status"], "on_submit": ["erpnext.regional.create_transaction_log", "erpnext.accounts.doctype.payment_request.payment_request.update_payment_req_status"],
@@ -356,7 +356,8 @@ regional_overrides = {
'erpnext.controllers.taxes_and_totals.get_itemised_tax_breakup_data': 'erpnext.regional.india.utils.get_itemised_tax_breakup_data', 'erpnext.controllers.taxes_and_totals.get_itemised_tax_breakup_data': 'erpnext.regional.india.utils.get_itemised_tax_breakup_data',
'erpnext.accounts.party.get_regional_address_details': 'erpnext.regional.india.utils.get_regional_address_details', 'erpnext.accounts.party.get_regional_address_details': 'erpnext.regional.india.utils.get_regional_address_details',
'erpnext.hr.utils.calculate_annual_eligible_hra_exemption': 'erpnext.regional.india.utils.calculate_annual_eligible_hra_exemption', 'erpnext.hr.utils.calculate_annual_eligible_hra_exemption': 'erpnext.regional.india.utils.calculate_annual_eligible_hra_exemption',
'erpnext.hr.utils.calculate_hra_exemption_for_period': 'erpnext.regional.india.utils.calculate_hra_exemption_for_period' 'erpnext.hr.utils.calculate_hra_exemption_for_period': 'erpnext.regional.india.utils.calculate_hra_exemption_for_period',
'erpnext.accounts.doctype.purchase_invoice.purchase_invoice.make_regional_gl_entries': 'erpnext.regional.india.utils.make_regional_gl_entries'
}, },
'United Arab Emirates': { 'United Arab Emirates': {
'erpnext.controllers.taxes_and_totals.update_itemised_tax_data': 'erpnext.regional.united_arab_emirates.utils.update_itemised_tax_data' 'erpnext.controllers.taxes_and_totals.update_itemised_tax_data': 'erpnext.regional.united_arab_emirates.utils.update_itemised_tax_data'

View File

@@ -1,232 +1,234 @@
{ {
"allow_copy": 0, "allow_copy": 0,
"allow_guest_to_view": 0, "allow_guest_to_view": 0,
"allow_import": 0, "allow_import": 0,
"allow_rename": 0, "allow_rename": 0,
"beta": 0, "beta": 0,
"creation": "2018-04-13 17:42:13.516032", "creation": "2018-04-13 17:42:13.516032",
"custom": 0, "custom": 0,
"docstatus": 0, "docstatus": 0,
"doctype": "DocType", "doctype": "DocType",
"document_type": "", "document_type": "",
"editable_grid": 1, "editable_grid": 1,
"engine": "InnoDB", "engine": "InnoDB",
"fields": [ "fields": [
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0, "allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fieldname": "from_amount", "default": "0",
"fieldtype": "Currency", "fieldname": "from_amount",
"hidden": 0, "fieldtype": "Currency",
"ignore_user_permissions": 0, "hidden": 0,
"ignore_xss_filter": 0, "ignore_user_permissions": 0,
"in_filter": 0, "ignore_xss_filter": 0,
"in_global_search": 0, "in_filter": 0,
"in_list_view": 1, "in_global_search": 0,
"in_standard_filter": 0, "in_list_view": 1,
"label": "From Amount", "in_standard_filter": 0,
"length": 0, "label": "From Amount",
"no_copy": 0, "length": 0,
"permlevel": 0, "no_copy": 0,
"precision": "", "permlevel": 0,
"print_hide": 0, "precision": "",
"print_hide_if_no_value": 0, "print_hide": 0,
"read_only": 0, "print_hide_if_no_value": 0,
"remember_last_selected_value": 0, "read_only": 0,
"report_hide": 0, "remember_last_selected_value": 0,
"reqd": 1, "report_hide": 0,
"search_index": 0, "reqd": 1,
"set_only_once": 0, "search_index": 0,
"translatable": 0, "set_only_once": 0,
"translatable": 0,
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0, "allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fieldname": "to_amount", "fieldname": "to_amount",
"fieldtype": "Currency", "fieldtype": "Currency",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0, "ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "To Amount", "label": "To Amount",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"permlevel": 0, "permlevel": 0,
"precision": "", "precision": "",
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0, "print_hide_if_no_value": 0,
"read_only": 0, "read_only": 0,
"remember_last_selected_value": 0, "remember_last_selected_value": 0,
"report_hide": 0, "report_hide": 0,
"reqd": 0, "reqd": 0,
"search_index": 0, "search_index": 0,
"set_only_once": 0, "set_only_once": 0,
"translatable": 0, "translatable": 0,
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0, "allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fieldname": "percent_deduction", "default": "0",
"fieldtype": "Percent", "fieldname": "percent_deduction",
"hidden": 0, "fieldtype": "Percent",
"ignore_user_permissions": 0, "hidden": 0,
"ignore_xss_filter": 0, "ignore_user_permissions": 0,
"in_filter": 0, "ignore_xss_filter": 0,
"in_global_search": 0, "in_filter": 0,
"in_list_view": 1, "in_global_search": 0,
"in_standard_filter": 0, "in_list_view": 1,
"label": "Percent Deduction", "in_standard_filter": 0,
"length": 0, "label": "Percent Deduction",
"no_copy": 0, "length": 0,
"permlevel": 0, "no_copy": 0,
"precision": "", "permlevel": 0,
"print_hide": 0, "precision": "",
"print_hide_if_no_value": 0, "print_hide": 0,
"read_only": 0, "print_hide_if_no_value": 0,
"remember_last_selected_value": 0, "read_only": 0,
"report_hide": 0, "remember_last_selected_value": 0,
"reqd": 1, "report_hide": 0,
"search_index": 0, "reqd": 1,
"set_only_once": 0, "search_index": 0,
"translatable": 0, "set_only_once": 0,
"translatable": 0,
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0, "allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fieldname": "condition", "fieldname": "condition",
"fieldtype": "Code", "fieldtype": "Code",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0, "ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "Condition", "label": "Condition",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"permlevel": 0, "permlevel": 0,
"precision": "", "precision": "",
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0, "print_hide_if_no_value": 0,
"read_only": 0, "read_only": 0,
"remember_last_selected_value": 0, "remember_last_selected_value": 0,
"report_hide": 0, "report_hide": 0,
"reqd": 0, "reqd": 0,
"search_index": 0, "search_index": 0,
"set_only_once": 0, "set_only_once": 0,
"translatable": 0, "translatable": 0,
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0, "allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fieldname": "column_break_5", "fieldname": "column_break_5",
"fieldtype": "Column Break", "fieldtype": "Column Break",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0, "ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 0, "in_list_view": 0,
"in_standard_filter": 0, "in_standard_filter": 0,
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"permlevel": 0, "permlevel": 0,
"precision": "", "precision": "",
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0, "print_hide_if_no_value": 0,
"read_only": 0, "read_only": 0,
"remember_last_selected_value": 0, "remember_last_selected_value": 0,
"report_hide": 0, "report_hide": 0,
"reqd": 0, "reqd": 0,
"search_index": 0, "search_index": 0,
"set_only_once": 0, "set_only_once": 0,
"translatable": 0, "translatable": 0,
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0, "allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fieldname": "html_6", "fieldname": "html_6",
"fieldtype": "HTML", "fieldtype": "HTML",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0, "ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 0, "in_list_view": 0,
"in_standard_filter": 0, "in_standard_filter": 0,
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"options": "<h4>Condition Examples</h4>\n<ol>\n<li>Applying tax if employee born between 31-12-1937 and 01-01-1958 (Employees aged 60 to 80)<br>\n<code>Condition: date_of_birth&gt;date(1937, 12, 31) and date_of_birth&lt;date(1958, 01, 01)</code></li><br><li>Applying tax by employee gender<br>\n<code>Condition: gender==\"Male\"</code></li><br>\n<li>Applying tax by Salary Component<br>\n<code>Condition: base &gt; 10000</code></li></ol>", "options": "<h4>Condition Examples</h4>\n<ol>\n<li>Applying tax if employee born between 31-12-1937 and 01-01-1958 (Employees aged 60 to 80)<br>\n<code>Condition: date_of_birth&gt;date(1937, 12, 31) and date_of_birth&lt;date(1958, 01, 01)</code></li><br><li>Applying tax by employee gender<br>\n<code>Condition: gender==\"Male\"</code></li><br>\n<li>Applying tax by Salary Component<br>\n<code>Condition: base &gt; 10000</code></li></ol>",
"permlevel": 0, "permlevel": 0,
"precision": "", "precision": "",
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0, "print_hide_if_no_value": 0,
"read_only": 0, "read_only": 0,
"remember_last_selected_value": 0, "remember_last_selected_value": 0,
"report_hide": 0, "report_hide": 0,
"reqd": 0, "reqd": 0,
"search_index": 0, "search_index": 0,
"set_only_once": 0, "set_only_once": 0,
"translatable": 0, "translatable": 0,
"unique": 0 "unique": 0
} }
], ],
"has_web_view": 0, "has_web_view": 0,
"hide_heading": 0, "hide_heading": 0,
"hide_toolbar": 0, "hide_toolbar": 0,
"idx": 0, "idx": 0,
"image_view": 0, "image_view": 0,
"in_create": 0, "in_create": 0,
"is_submittable": 0, "is_submittable": 0,
"issingle": 0, "issingle": 0,
"istable": 1, "istable": 1,
"max_attachments": 0, "max_attachments": 0,
"modified": "2018-06-19 10:10:23.732132", "modified": "2020-06-22 18:16:07.596493",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "HR", "module": "HR",
"name": "Taxable Salary Slab", "name": "Taxable Salary Slab",
"name_case": "", "name_case": "",
"owner": "Administrator", "owner": "Administrator",
"permissions": [], "permissions": [],
"quick_entry": 1, "quick_entry": 1,
"read_only": 0, "read_only": 0,
"read_only_onload": 0, "read_only_onload": 0,
"show_name_in_global_search": 0, "show_name_in_global_search": 0,
"sort_field": "modified", "sort_field": "modified",
"sort_order": "DESC", "sort_order": "DESC",
"track_changes": 1, "track_changes": 1,
"track_seen": 0 "track_seen": 0
} }

View File

@@ -1,7 +1,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import frappe, re, json import frappe, re, json
from frappe import _ from frappe import _
from frappe.utils import cstr, flt, date_diff, nowdate from frappe.utils import cstr, flt, date_diff, nowdate, round_based_on_smallest_currency_fraction, money_in_words
from erpnext.regional.india import states, state_numbers from erpnext.regional.india import states, state_numbers
from erpnext.controllers.taxes_and_totals import get_itemised_tax, get_itemised_taxable_amount from erpnext.controllers.taxes_and_totals import get_itemised_tax, get_itemised_taxable_amount
from erpnext.controllers.accounts_controller import get_taxes_and_charges from erpnext.controllers.accounts_controller import get_taxes_and_charges
@@ -443,19 +443,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):
@@ -629,6 +633,7 @@ def validate_state_code(state_code, address):
else: else:
return int(state_code) return int(state_code)
@frappe.whitelist()
def get_gst_accounts(company, account_wise=False): def get_gst_accounts(company, account_wise=False):
gst_accounts = frappe._dict() gst_accounts = frappe._dict()
gst_settings_accounts = frappe.get_all("GST Account", gst_settings_accounts = frappe.get_all("GST Account",
@@ -647,14 +652,54 @@ def get_gst_accounts(company, account_wise=False):
return gst_accounts return gst_accounts
def make_reverse_charge_entries(doc, method): def update_grand_total_for_rcm(doc, method):
country = frappe.get_cached_value('Company', doc.company, 'country')
if country != 'India':
return
if doc.reverse_charge == 'Y':
gst_accounts = get_gst_accounts(doc.company)
gst_account_list = gst_accounts.get('cgst_account') + gst_accounts.get('sgst_account') \
+ gst_accounts.get('igst_account')
gst_tax = 0
for tax in doc.get('taxes'):
if tax.category not in ("Total", "Valuation and Total"):
continue
if flt(tax.base_tax_amount_after_discount_amount) and tax.account_head in gst_account_list:
gst_tax += tax.base_tax_amount_after_discount_amount
doc.taxes_and_charges_added -= gst_tax
doc.total_taxes_and_charges -= gst_tax
update_totals(gst_tax, doc)
def update_totals(gst_tax, doc):
doc.grand_total -= gst_tax
if doc.meta.get_field("rounded_total"):
if doc.is_rounded_total_disabled():
doc.outstanding_amount = doc.grand_total
else:
doc.rounded_total = round_based_on_smallest_currency_fraction(doc.grand_total,
doc.currency, doc.precision("rounded_total"))
doc.rounding_adjustment += flt(doc.rounded_total - doc.grand_total,
doc.precision("rounding_adjustment"))
doc.outstanding_amount = doc.base_rounded_total
doc.in_words = money_in_words(doc.grand_total, doc.currency)
def make_regional_gl_entries(gl_entries, doc):
country = frappe.get_cached_value('Company', doc.company, 'country') country = frappe.get_cached_value('Company', doc.company, 'country')
if country != 'India': if country != 'India':
return return
if doc.reverse_charge == 'Y': if doc.reverse_charge == 'Y':
gl_entries = []
gst_accounts = get_gst_accounts(doc.company) gst_accounts = get_gst_accounts(doc.company)
gst_account_list = gst_accounts.get('cgst_account') + gst_accounts.get('sgst_account') \ gst_account_list = gst_accounts.get('cgst_account') + gst_accounts.get('sgst_account') \
+ gst_accounts.get('igst_account') + gst_accounts.get('igst_account')
@@ -679,19 +724,4 @@ def make_reverse_charge_entries(doc, method):
}, account_currency, item=tax) }, account_currency, item=tax)
) )
gl_entries.append(doc.get_gl_dict( return gl_entries
{
"account": doc.credit_to if doc.doctype == 'Purchase Invoice' else doc.debit_to,
"cost_center": doc.cost_center,
"posting_date": doc.posting_date,
"party_type": 'Supplier',
"party": doc.supplier,
"against": tax.account_head,
"debit": tax.base_tax_amount_after_discount_amount,
"debit_in_account_currency": tax.base_tax_amount_after_discount_amount \
if account_currency==doc.company_currency \
else tax.tax_amount_after_discount_amount
}, account_currency, item=doc)
)
make_gl_entries(gl_entries)

View File

@@ -3,13 +3,15 @@ frappe.listview_settings['Quotation'] = {
"company", "currency", 'valid_till'], "company", "currency", 'valid_till'],
onload: function(listview) { onload: function(listview) {
listview.page.fields_dict.quotation_to.get_query = function() { if (listview.page.fields_dict.quotation_to) {
return { listview.page.fields_dict.quotation_to.get_query = function() {
"filters": { return {
"name": ["in", ["Customer", "Lead"]], "filters": {
} "name": ["in", ["Customer", "Lead"]],
}
};
}; };
}; }
}, },
get_indicator: function(doc) { get_indicator: function(doc) {

View File

@@ -202,8 +202,6 @@ cur_frm.cscript.change_abbr = function() {
if(r.exc) { if(r.exc) {
frappe.msgprint(__("There were errors.")); frappe.msgprint(__("There were errors."));
return; return;
} else {
cur_frm.set_value("abbr", args.new_abbr);
} }
dialog.hide(); dialog.hide();
cur_frm.refresh(); cur_frm.refresh();

View File

@@ -400,8 +400,6 @@ def replace_abbr(company, old, new):
for dt in ["Warehouse", "Account", "Cost Center", "Department", for dt in ["Warehouse", "Account", "Cost Center", "Department",
"Sales Taxes and Charges Template", "Purchase Taxes and Charges Template"]: "Sales Taxes and Charges Template", "Purchase Taxes and Charges Template"]:
_rename_records(dt) _rename_records(dt)
frappe.db.commit()
def get_name_with_abbr(name, company): def get_name_with_abbr(name, company):
company_abbr = frappe.get_cached_value('Company', company, "abbr") company_abbr = frappe.get_cached_value('Company', company, "abbr")

View File

@@ -143,7 +143,7 @@ class Batch(Document):
@frappe.whitelist() @frappe.whitelist()
def get_batch_qty(batch_no=None, warehouse=None, item_code=None): def get_batch_qty(batch_no=None, warehouse=None, item_code=None, posting_date=None, posting_time=None):
"""Returns batch actual qty if warehouse is passed, """Returns batch actual qty if warehouse is passed,
or returns dict of qty by warehouse if warehouse is None or returns dict of qty by warehouse if warehouse is None
@@ -155,9 +155,14 @@ def get_batch_qty(batch_no=None, warehouse=None, item_code=None):
out = 0 out = 0
if batch_no and warehouse: if batch_no and warehouse:
cond = ""
if posting_date and posting_time:
cond = " and timestamp(posting_date, posting_time) <= timestamp('{0}', '{1}')".format(posting_date,
posting_time)
out = float(frappe.db.sql("""select sum(actual_qty) out = float(frappe.db.sql("""select sum(actual_qty)
from `tabStock Ledger Entry` from `tabStock Ledger Entry`
where warehouse=%s and batch_no=%s""", where warehouse=%s and batch_no=%s {0}""".format(cond),
(warehouse, batch_no))[0][0] or 0) (warehouse, batch_no))[0][0] or 0)
if batch_no and not warehouse: if batch_no and not warehouse:

View File

@@ -102,6 +102,7 @@
"bill_no", "bill_no",
"bill_date", "bill_date",
"more_info", "more_info",
"project",
"status", "status",
"amended_from", "amended_from",
"range", "range",
@@ -1059,13 +1060,20 @@
"fieldname": "scan_barcode", "fieldname": "scan_barcode",
"fieldtype": "Data", "fieldtype": "Data",
"label": "Scan Barcode" "label": "Scan Barcode"
},
{
"description": "Track this Purchase Receipt against any Project",
"fieldname": "project",
"fieldtype": "Link",
"label": "Project",
"options": "Project"
} }
], ],
"icon": "fa fa-truck", "icon": "fa fa-truck",
"idx": 261, "idx": 261,
"is_submittable": 1, "is_submittable": 1,
"links": [], "links": [],
"modified": "2020-04-17 13:06:26.970288", "modified": "2020-07-15 12:49:42.095297",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Stock", "module": "Stock",
"name": "Purchase Receipt", "name": "Purchase Receipt",

View File

@@ -74,6 +74,20 @@ frappe.ui.form.on("Stock Reconciliation", {
, __("Get Items"), __("Update")); , __("Get Items"), __("Update"));
}, },
posting_date: function(frm) {
frm.trigger("set_valuation_rate_and_qty_for_all_items");
},
posting_time: function(frm) {
frm.trigger("set_valuation_rate_and_qty_for_all_items");
},
set_valuation_rate_and_qty_for_all_items: function(frm) {
frm.doc.items.forEach(row => {
frm.events.set_valuation_rate_and_qty(frm, row.doctype, row.name);
});
},
set_valuation_rate_and_qty: function(frm, cdt, cdn) { set_valuation_rate_and_qty: function(frm, cdt, cdn) {
var d = frappe.model.get_doc(cdt, cdn); var d = frappe.model.get_doc(cdt, cdn);

View File

@@ -184,8 +184,12 @@ class StockReconciliation(StockController):
sl_entries = [] sl_entries = []
has_serial_no = False has_serial_no = False
has_batch_no = False
for row in self.items: for row in self.items:
item = frappe.get_doc("Item", row.item_code) item = frappe.get_doc("Item", row.item_code)
if item.has_batch_no:
has_batch_no = True
if item.has_serial_no or item.has_batch_no: if item.has_serial_no or item.has_batch_no:
has_serial_no = True has_serial_no = True
self.get_sle_for_serialized_items(row, sl_entries) self.get_sle_for_serialized_items(row, sl_entries)
@@ -221,7 +225,11 @@ class StockReconciliation(StockController):
if has_serial_no: if has_serial_no:
sl_entries = self.merge_similar_item_serial_nos(sl_entries) sl_entries = self.merge_similar_item_serial_nos(sl_entries)
self.make_sl_entries(sl_entries) allow_negative_stock = False
if has_batch_no:
allow_negative_stock = True
self.make_sl_entries(sl_entries, allow_negative_stock=allow_negative_stock)
if has_serial_no and sl_entries: if has_serial_no and sl_entries:
self.update_valuation_rate_for_serial_no() self.update_valuation_rate_for_serial_no()
@@ -507,7 +515,7 @@ def get_stock_balance_for(item_code, warehouse,
qty, rate = data qty, rate = data
if item_dict.get("has_batch_no"): if item_dict.get("has_batch_no"):
qty = get_batch_qty(batch_no, warehouse) or 0 qty = get_batch_qty(batch_no, warehouse, posting_date=posting_date, posting_time=posting_time) or 0
return { return {
'qty': qty, 'qty': qty,

View File

@@ -2,7 +2,7 @@
# License: GNU General Public License v3. See license.txt # License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals from __future__ import unicode_literals
import frappe import frappe, erpnext
from frappe import _ from frappe import _
from frappe.utils import flt, cint, getdate, now, date_diff from frappe.utils import flt, cint, getdate, now, date_diff
from erpnext.stock.utils import add_additional_uom_columns from erpnext.stock.utils import add_additional_uom_columns
@@ -20,6 +20,11 @@ def execute(filters=None):
from_date = filters.get('from_date') from_date = filters.get('from_date')
to_date = filters.get('to_date') to_date = filters.get('to_date')
if filters.get("company"):
company_currency = erpnext.get_company_currency(filters.get("company"))
else:
company_currency = frappe.db.get_single_value("Global Defaults", "default_currency")
include_uom = filters.get("include_uom") include_uom = filters.get("include_uom")
columns = get_columns(filters) columns = get_columns(filters)
items = get_items(filters) items = get_items(filters)
@@ -52,6 +57,7 @@ def execute(filters=None):
item_reorder_qty = item_reorder_detail_map[item + warehouse]["warehouse_reorder_qty"] item_reorder_qty = item_reorder_detail_map[item + warehouse]["warehouse_reorder_qty"]
report_data = { report_data = {
'currency': company_currency,
'item_code': item, 'item_code': item,
'warehouse': warehouse, 'warehouse': warehouse,
'company': company, 'company': company,
@@ -89,7 +95,6 @@ def execute(filters=None):
def get_columns(filters): def get_columns(filters):
"""return columns""" """return columns"""
columns = [ columns = [
{"label": _("Item"), "fieldname": "item_code", "fieldtype": "Link", "options": "Item", "width": 100}, {"label": _("Item"), "fieldname": "item_code", "fieldtype": "Link", "options": "Item", "width": 100},
{"label": _("Item Name"), "fieldname": "item_name", "width": 150}, {"label": _("Item Name"), "fieldname": "item_name", "width": 150},
@@ -97,14 +102,14 @@ def get_columns(filters):
{"label": _("Warehouse"), "fieldname": "warehouse", "fieldtype": "Link", "options": "Warehouse", "width": 100}, {"label": _("Warehouse"), "fieldname": "warehouse", "fieldtype": "Link", "options": "Warehouse", "width": 100},
{"label": _("Stock UOM"), "fieldname": "stock_uom", "fieldtype": "Link", "options": "UOM", "width": 90}, {"label": _("Stock UOM"), "fieldname": "stock_uom", "fieldtype": "Link", "options": "UOM", "width": 90},
{"label": _("Balance Qty"), "fieldname": "bal_qty", "fieldtype": "Float", "width": 100, "convertible": "qty"}, {"label": _("Balance Qty"), "fieldname": "bal_qty", "fieldtype": "Float", "width": 100, "convertible": "qty"},
{"label": _("Balance Value"), "fieldname": "bal_val", "fieldtype": "Currency", "width": 100}, {"label": _("Balance Value"), "fieldname": "bal_val", "fieldtype": "Currency", "width": 100, "options": "currency"},
{"label": _("Opening Qty"), "fieldname": "opening_qty", "fieldtype": "Float", "width": 100, "convertible": "qty"}, {"label": _("Opening Qty"), "fieldname": "opening_qty", "fieldtype": "Float", "width": 100, "convertible": "qty"},
{"label": _("Opening Value"), "fieldname": "opening_val", "fieldtype": "Float", "width": 110}, {"label": _("Opening Value"), "fieldname": "opening_val", "fieldtype": "Currency", "width": 110, "options": "currency"},
{"label": _("In Qty"), "fieldname": "in_qty", "fieldtype": "Float", "width": 80, "convertible": "qty"}, {"label": _("In Qty"), "fieldname": "in_qty", "fieldtype": "Float", "width": 80, "convertible": "qty"},
{"label": _("In Value"), "fieldname": "in_val", "fieldtype": "Float", "width": 80}, {"label": _("In Value"), "fieldname": "in_val", "fieldtype": "Float", "width": 80},
{"label": _("Out Qty"), "fieldname": "out_qty", "fieldtype": "Float", "width": 80, "convertible": "qty"}, {"label": _("Out Qty"), "fieldname": "out_qty", "fieldtype": "Float", "width": 80, "convertible": "qty"},
{"label": _("Out Value"), "fieldname": "out_val", "fieldtype": "Float", "width": 80}, {"label": _("Out Value"), "fieldname": "out_val", "fieldtype": "Float", "width": 80},
{"label": _("Valuation Rate"), "fieldname": "val_rate", "fieldtype": "Currency", "width": 90, "convertible": "rate"}, {"label": _("Valuation Rate"), "fieldname": "val_rate", "fieldtype": "Currency", "width": 90, "convertible": "rate", "options": "currency"},
{"label": _("Reorder Level"), "fieldname": "reorder_level", "fieldtype": "Float", "width": 80, "convertible": "qty"}, {"label": _("Reorder Level"), "fieldname": "reorder_level", "fieldtype": "Float", "width": 80, "convertible": "qty"},
{"label": _("Reorder Qty"), "fieldname": "reorder_qty", "fieldtype": "Float", "width": 80, "convertible": "qty"}, {"label": _("Reorder Qty"), "fieldname": "reorder_qty", "fieldtype": "Float", "width": 80, "convertible": "qty"},
{"label": _("Company"), "fieldname": "company", "fieldtype": "Link", "options": "Company", "width": 100} {"label": _("Company"), "fieldname": "company", "fieldtype": "Link", "options": "Company", "width": 100}

View File

@@ -4,6 +4,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import frappe import frappe
from frappe import _ from frappe import _
from frappe.utils import cint, flt
from erpnext.stock.utils import update_included_uom_in_report from erpnext.stock.utils import update_included_uom_in_report
def execute(filters=None): def execute(filters=None):
@@ -13,6 +14,7 @@ def execute(filters=None):
sl_entries = get_stock_ledger_entries(filters, items) sl_entries = get_stock_ledger_entries(filters, items)
item_details = get_item_details(items, sl_entries, include_uom) item_details = get_item_details(items, sl_entries, include_uom)
opening_row = get_opening_balance(filters, columns) opening_row = get_opening_balance(filters, columns)
precision = cint(frappe.db.get_single_value("System Settings", "float_precision"))
data = [] data = []
conversion_factors = [] conversion_factors = []
@@ -27,10 +29,10 @@ def execute(filters=None):
sle.update(item_detail) sle.update(item_detail)
if filters.get("batch_no"): if filters.get("batch_no"):
actual_qty += sle.actual_qty actual_qty += flt(sle.actual_qty, precision)
stock_value += sle.stock_value_difference stock_value += sle.stock_value_difference
if sle.voucher_type == 'Stock Reconciliation': if sle.voucher_type == 'Stock Reconciliation' and not sle.actual_qty:
actual_qty = sle.qty_after_transaction actual_qty = sle.qty_after_transaction
stock_value = sle.stock_value stock_value = sle.stock_value

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":