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

This commit is contained in:
Nabin Hait
2021-01-06 09:33:56 +05:30
committed by GitHub
7 changed files with 50 additions and 21 deletions

View File

@@ -4,7 +4,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import frappe, erpnext import frappe, erpnext
import frappe.defaults import frappe.defaults
from frappe.utils import cint, flt, add_months, today, date_diff, getdate, add_days, cstr, nowdate from frappe.utils import cint, flt, getdate, add_days, cstr, nowdate, formatdate
from frappe import _, msgprint, throw from frappe import _, msgprint, throw
from erpnext.accounts.party import get_party_account, get_due_date from erpnext.accounts.party import get_party_account, get_due_date
from erpnext.controllers.stock_controller import update_gl_entries_after from erpnext.controllers.stock_controller import update_gl_entries_after
@@ -537,7 +537,12 @@ class SalesInvoice(SellingController):
self.against_income_account = ','.join(against_acc) self.against_income_account = ','.join(against_acc)
def add_remarks(self): def add_remarks(self):
if not self.remarks: self.remarks = 'No Remarks' if not self.remarks:
if self.po_no and self.po_date:
self.remarks = _("Against Customer Order {0} dated {1}").format(self.po_no,
formatdate(self.po_date))
else:
self.remarks = _("No Remarks")
def validate_auto_set_posting_time(self): def validate_auto_set_posting_time(self):
# Don't auto set the posting date and time if invoice is amended # Don't auto set the posting date and time if invoice is amended

View File

@@ -279,6 +279,7 @@ def make_return_doc(doctype, source_name, target_doc=None):
target_doc.po_detail = source_doc.po_detail target_doc.po_detail = source_doc.po_detail
target_doc.pr_detail = source_doc.pr_detail target_doc.pr_detail = source_doc.pr_detail
target_doc.purchase_invoice_item = source_doc.name target_doc.purchase_invoice_item = source_doc.name
target_doc.price_list_rate = 0
elif doctype == "Delivery Note": elif doctype == "Delivery Note":
target_doc.against_sales_order = source_doc.against_sales_order target_doc.against_sales_order = source_doc.against_sales_order
@@ -297,6 +298,7 @@ def make_return_doc(doctype, source_name, target_doc=None):
target_doc.dn_detail = source_doc.dn_detail target_doc.dn_detail = source_doc.dn_detail
target_doc.expense_account = source_doc.expense_account target_doc.expense_account = source_doc.expense_account
target_doc.sales_invoice_item = source_doc.name target_doc.sales_invoice_item = source_doc.name
target_doc.price_list_rate = 0
if default_warehouse_for_sales_return: if default_warehouse_for_sales_return:
target_doc.warehouse = default_warehouse_for_sales_return target_doc.warehouse = default_warehouse_for_sales_return

View File

@@ -521,6 +521,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
company: me.frm.doc.company, company: me.frm.doc.company,
order_type: me.frm.doc.order_type, order_type: me.frm.doc.order_type,
is_pos: cint(me.frm.doc.is_pos), is_pos: cint(me.frm.doc.is_pos),
is_return: cint(me.frm.doc.is_return),
is_subcontracted: me.frm.doc.is_subcontracted, is_subcontracted: me.frm.doc.is_subcontracted,
transaction_date: me.frm.doc.transaction_date || me.frm.doc.posting_date, transaction_date: me.frm.doc.transaction_date || me.frm.doc.posting_date,
ignore_pricing_rule: me.frm.doc.ignore_pricing_rule, ignore_pricing_rule: me.frm.doc.ignore_pricing_rule,

View File

@@ -92,21 +92,18 @@ def get_party_details(address_name):
location = gstin_details.get('AddrLoc') or address.get('city') location = gstin_details.get('AddrLoc') or address.get('city')
state_code = gstin_details.get('StateCode') state_code = gstin_details.get('StateCode')
pincode = gstin_details.get('AddrPncd') pincode = gstin_details.get('AddrPncd')
address_line1 = '{} {}'.format(gstin_details.get('AddrBno'), gstin_details.get('AddrFlno')) address_line1 = '{} {}'.format(gstin_details.get('AddrBno') or "", gstin_details.get('AddrFlno') or "")
address_line2 = '{} {}'.format(gstin_details.get('AddrBnm'), gstin_details.get('AddrSt')) address_line2 = '{} {}'.format(gstin_details.get('AddrBnm') or "", gstin_details.get('AddrSt') or "")
email_id = address.get('email_id')
phone = address.get('phone')
# get last 10 digit
phone = phone.replace(" ", "")[-10:] if phone else ''
if state_code == 97: if state_code == 97:
# according to einvoice standard # according to einvoice standard
pincode = 999999 pincode = 999999
return frappe._dict(dict( return frappe._dict(dict(
gstin=gstin, legal_name=legal_name, location=location, gstin=gstin, legal_name=legal_name,
pincode=pincode, state_code=state_code, address_line1=address_line1, location=location, pincode=pincode,
address_line2=address_line2, email=email_id, phone=phone state_code=state_code, address_line1=address_line1,
address_line2=address_line2
)) ))
def get_gstin_details(gstin): def get_gstin_details(gstin):
@@ -146,16 +143,18 @@ def get_item_list(invoice):
item.update(d.as_dict()) item.update(d.as_dict())
item.sr_no = d.idx item.sr_no = d.idx
item.discount_amount = abs(item.discount_amount * item.qty) item.description = d.item_name.replace('"', '\\"')
item.description = d.item_name
item.qty = abs(item.qty) item.qty = abs(item.qty)
item.unit_rate = abs(item.base_net_amount / item.qty) item.discount_amount = abs(item.discount_amount * item.qty)
item.gross_amount = abs(item.base_net_amount) item.unit_rate = abs(item.base_amount / item.qty)
item.taxable_value = abs(item.base_net_amount) item.gross_amount = abs(item.base_amount)
item.taxable_value = abs(item.base_amount)
item.batch_expiry_date = frappe.db.get_value('Batch', d.batch_no, 'expiry_date') if d.batch_no else None item.batch_expiry_date = frappe.db.get_value('Batch', d.batch_no, 'expiry_date') if d.batch_no else None
item.batch_expiry_date = format_date(item.batch_expiry_date, 'dd/mm/yyyy') if item.batch_expiry_date else None item.batch_expiry_date = format_date(item.batch_expiry_date, 'dd/mm/yyyy') if item.batch_expiry_date else None
item.is_service_item = 'N' if frappe.db.get_value('Item', d.item_code, 'is_stock_item') else 'Y' item.is_service_item = 'N' if frappe.db.get_value('Item', d.item_code, 'is_stock_item') else 'Y'
item.serial_no = ""
item = update_item_taxes(invoice, item) item = update_item_taxes(invoice, item)
@@ -272,7 +271,25 @@ def get_eway_bill_details(invoice):
vehicle_type=vehicle_type[invoice.gst_vehicle_type] vehicle_type=vehicle_type[invoice.gst_vehicle_type]
)) ))
def validate_mandatory_fields(invoice):
if not invoice.company_address:
frappe.throw(_('Company Address is mandatory to fetch company GSTIN details.'), title=_('Missing Fields'))
if not invoice.customer_address:
frappe.throw(_('Customer Address is mandatory to fetch customer GSTIN details.'), title=_('Missing Fields'))
if not frappe.db.get_value('Address', invoice.company_address, 'gstin'):
frappe.throw(
_('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'):
frappe.throw(
_('GSTIN is mandatory to fetch customer GSTIN details. Please enter GSTIN in selected customer address.'),
title=_('Missing Fields')
)
def make_einvoice(invoice): def make_einvoice(invoice):
validate_mandatory_fields(invoice)
schema = read_json('einv_template') schema = read_json('einv_template')
transaction_details = get_transaction_details(invoice) transaction_details = get_transaction_details(invoice)
@@ -358,7 +375,7 @@ def validate_einvoice(validations, einvoice, errors=[]):
# remove empty dicts # remove empty dicts
einvoice.pop(fieldname, None) einvoice.pop(fieldname, None)
continue continue
# convert to int or str # convert to int or str
if value_type == 'string': if value_type == 'string':
einvoice[fieldname] = str(value) einvoice[fieldname] = str(value)

View File

@@ -488,6 +488,8 @@ class StockEntry(StockController):
if self.purpose in ["Manufacture", "Repack"]: if self.purpose in ["Manufacture", "Repack"]:
for d in self.get("items"): for d in self.get("items"):
if d.set_basic_rate_manually: continue
if (d.transfer_qty and (d.bom_no or d.t_warehouse) if (d.transfer_qty and (d.bom_no or d.t_warehouse)
and (getattr(self, "pro_doc", frappe._dict()).scrap_warehouse != d.t_warehouse)): and (getattr(self, "pro_doc", frappe._dict()).scrap_warehouse != d.t_warehouse)):
@@ -499,7 +501,7 @@ class StockEntry(StockController):
if raw_material_cost and self.purpose == "Manufacture": if raw_material_cost and self.purpose == "Manufacture":
d.basic_rate = flt((raw_material_cost - scrap_material_cost) / flt(d.transfer_qty), d.precision("basic_rate")) d.basic_rate = flt((raw_material_cost - scrap_material_cost) / flt(d.transfer_qty), d.precision("basic_rate"))
d.basic_amount = flt((raw_material_cost - scrap_material_cost), d.precision("basic_amount")) d.basic_amount = flt((raw_material_cost - scrap_material_cost), d.precision("basic_amount"))
elif self.purpose == "Repack" and total_fg_qty and not d.set_basic_rate_manually: elif self.purpose == "Repack" and total_fg_qty:
d.basic_rate = flt(raw_material_cost) / flt(total_fg_qty) d.basic_rate = flt(raw_material_cost) / flt(total_fg_qty)
d.basic_amount = d.basic_rate * flt(d.qty) d.basic_amount = d.basic_rate * flt(d.qty)

View File

@@ -494,7 +494,7 @@
}, },
{ {
"default": "0", "default": "0",
"depends_on": "eval:parent.purpose===\"Repack\" && doc.t_warehouse", "depends_on": "eval:in_list([\"Repack\", \"Manufacture\"], parent.purpose) && doc.t_warehouse",
"fieldname": "set_basic_rate_manually", "fieldname": "set_basic_rate_manually",
"fieldtype": "Check", "fieldtype": "Check",
"label": "Set Basic Rate Manually" "label": "Set Basic Rate Manually"
@@ -502,7 +502,7 @@
], ],
"idx": 1, "idx": 1,
"istable": 1, "istable": 1,
"modified": "2020-09-04 12:12:35.668198", "modified": "2021-01-05 15:05:04.891447",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Stock", "module": "Stock",
"name": "Stock Entry Detail", "name": "Stock Entry Detail",

View File

@@ -72,7 +72,9 @@ def get_item_details(args, doc=None, for_validate=False, overwrite_warehouse=Tru
update_party_blanket_order(args, out) update_party_blanket_order(args, out)
get_price_list_rate(args, item, out) if not doc or cint(doc.get('is_return')) == 0:
# get price list rate only if the invoice is not a credit or debit note
get_price_list_rate(args, item, out)
if args.customer and cint(args.is_pos): if args.customer and cint(args.is_pos):
out.update(get_pos_profile_item_details(args.company, args)) out.update(get_pos_profile_item_details(args.company, args))