Merge pull request #32494 from frappe/version-13-hotfix

chore: release v13
This commit is contained in:
Deepesh Garg
2022-10-04 17:41:06 +05:30
committed by GitHub
15 changed files with 151 additions and 24 deletions

View File

@@ -12,17 +12,13 @@ erpnext/selling @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
erpnext/support/ @nextchamp-saqib @deepeshgarg007
pos* @nextchamp-saqib
erpnext/buying/ @marination @rohitwaghchaure @s-aga-r
erpnext/e_commerce/ @marination
erpnext/maintenance/ @marination @rohitwaghchaure @s-aga-r
erpnext/manufacturing/ @marination @rohitwaghchaure @s-aga-r
erpnext/portal/ @marination
erpnext/quality_management/ @marination @rohitwaghchaure @s-aga-r
erpnext/shopping_cart/ @marination
erpnext/stock/ @marination @rohitwaghchaure @s-aga-r
erpnext/buying/ @rohitwaghchaure @s-aga-r
erpnext/maintenance/ @rohitwaghchaure @s-aga-r
erpnext/manufacturing/ @rohitwaghchaure @s-aga-r
erpnext/quality_management/ @rohitwaghchaure @s-aga-r
erpnext/stock/ @rohitwaghchaure @s-aga-r
erpnext/crm/ @NagariaHussain
erpnext/education/ @rutwikhdev
erpnext/healthcare/ @chillaranand
erpnext/hr/ @ruchamahabal
erpnext/non_profit/ @ruchamahabal
@@ -30,7 +26,7 @@ erpnext/payroll @ruchamahabal
erpnext/projects/ @ruchamahabal
erpnext/controllers @deepeshgarg007 @nextchamp-saqib @rohitwaghchaure @marination
erpnext/patches/ @deepeshgarg007 @nextchamp-saqib @marination rohitwaghchaure
erpnext/patches/ @deepeshgarg007 @nextchamp-saqib @rohitwaghchaure
erpnext/public/ @nextchamp-saqib @marination
.github/ @ankush

View File

@@ -357,7 +357,7 @@ class PaymentReconciliation(Document):
def get_conditions(self, get_invoices=False, get_payments=False, get_return_invoices=False):
condition = " and company = '{0}' ".format(self.company)
if self.get("cost_center") and (get_invoices or get_payments or get_return_invoices):
if self.get("cost_center"):
condition = " and cost_center = '{0}' ".format(self.cost_center)
if get_invoices:

View File

@@ -186,8 +186,10 @@
{
"fetch_from": "bank_account.bank",
"fieldname": "bank",
"fieldtype": "Read Only",
"label": "Bank"
"fieldtype": "Link",
"label": "Bank",
"options": "Bank",
"read_only": 1
},
{
"fetch_from": "bank_account.bank_account_no",
@@ -366,10 +368,11 @@
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2020-09-18 12:24:14.178853",
"modified": "2022-09-30 16:19:43.680025",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Request",
"naming_rule": "By \"Naming Series\" field",
"owner": "Administrator",
"permissions": [
{
@@ -401,5 +404,6 @@
}
],
"sort_field": "modified",
"sort_order": "DESC"
"sort_order": "DESC",
"states": []
}

View File

@@ -7,7 +7,7 @@ import unittest
import frappe
from frappe.model.dynamic_links import get_dynamic_link_map
from frappe.model.naming import make_autoname
from frappe.utils import add_days, flt, getdate, nowdate
from frappe.utils import add_days, flt, getdate, nowdate, today
from six import iteritems
from erpnext.accounts.doctype.account.test_account import create_account, get_inventory_account
@@ -3396,6 +3396,37 @@ class TestSalesInvoice(unittest.TestCase):
"Accounts Settings", "Accounts Settings", "unlink_payment_on_cancel_of_invoice", unlink_enabled
)
def test_batch_expiry_for_sales_invoice_return(self):
from erpnext.controllers.sales_and_purchase_return import make_return_doc
from erpnext.stock.doctype.item.test_item import make_item
item = make_item(
"_Test Batch Item For Return Check",
{
"is_purchase_item": 1,
"is_stock_item": 1,
"has_batch_no": 1,
"create_new_batch": 1,
"batch_number_series": "TBIRC.#####",
},
)
pr = make_purchase_receipt(qty=1, item_code=item.name)
batch_no = pr.items[0].batch_no
si = create_sales_invoice(qty=1, item_code=item.name, update_stock=1, batch_no=batch_no)
si.load_from_db()
batch_no = si.items[0].batch_no
self.assertTrue(batch_no)
frappe.db.set_value("Batch", batch_no, "expiry_date", add_days(today(), -1))
return_si = make_return_doc(si.doctype, si.name)
return_si.save().submit()
self.assertTrue(return_si.docstatus == 1)
def get_sales_invoice_for_e_invoice():
si = make_sales_invoice_for_ewaybill()
@@ -3666,6 +3697,7 @@ def create_sales_invoice(**args):
"serial_no": args.serial_no,
"conversion_factor": 1,
"incoming_rate": args.incoming_rate or 0,
"batch_no": args.batch_no or None,
},
)

View File

@@ -326,6 +326,9 @@ def get_advance_vouchers(
"party": ["in", parties],
}
if party_type == "Customer":
filters.update({"against_voucher": ["is", "not set"]})
if company:
filters["company"] = company
if from_date and to_date:

View File

@@ -370,7 +370,7 @@ def get_conditions(filters):
where parent=`tabSales Invoice`.name
and ifnull(`tab{table}`.{field}, '') = %({field})s)"""
conditions += get_sales_invoice_item_field_condition("mode_of_payments", "Sales Invoice Payment")
conditions += get_sales_invoice_item_field_condition("mode_of_payment", "Sales Invoice Payment")
conditions += get_sales_invoice_item_field_condition("cost_center")
conditions += get_sales_invoice_item_field_condition("warehouse")
conditions += get_sales_invoice_item_field_condition("brand")

View File

@@ -100,6 +100,7 @@ def execute():
"mode_of_payment": loan.mode_of_payment,
"loan_account": loan.loan_account,
"payment_account": loan.payment_account,
"disbursement_account": loan.payment_account,
"interest_income_account": loan.interest_income_account,
"penalty_income_account": loan.penalty_income_account,
},
@@ -190,6 +191,7 @@ def create_loan_type(loan, loan_type_name, penalty_account):
loan_type_doc.company = loan.company
loan_type_doc.mode_of_payment = loan.mode_of_payment
loan_type_doc.payment_account = loan.payment_account
loan_type_doc.disbursement_account = loan.payment_account
loan_type_doc.loan_account = loan.loan_account
loan_type_doc.interest_income_account = loan.interest_income_account
loan_type_doc.penalty_income_account = penalty_account

View File

@@ -257,9 +257,16 @@ def get_regional_address_details(party_details, doctype, company):
update_party_details(party_details, doctype)
customer_gst_category = frappe.get_value(
"Customer", party_details.customer, ["gst_category", "export_type"]
)
party_details.place_of_supply = get_place_of_supply(party_details, doctype)
if is_internal_transfer(party_details, doctype):
if is_internal_transfer(party_details, doctype) or customer_gst_category == (
"SEZ",
"Without Payment of Tax",
):
party_details.taxes_and_charges = ""
party_details.taxes = []
return party_details
@@ -603,6 +610,10 @@ def get_ewb_data(dt, dn):
data = get_address_details(data, doc, company_address, billing_address, dispatch_address)
if is_intrastate_transfer_eway_bill(data):
data.docType = "CHL"
data.subSupplyType = 8
data.itemList = []
data.totalValue = doc.total
@@ -645,6 +656,10 @@ def get_ewb_data(dt, dn):
return data
def is_intrastate_transfer_eway_bill(data):
return data.fromGstin == data.toGstin
@frappe.whitelist()
def generate_ewb_json(dt, dn):
dn = json.loads(dn)

View File

@@ -6,7 +6,7 @@ import json
import frappe
from frappe.tests.utils import FrappeTestCase
from frappe.utils import cstr, flt, nowdate, nowtime
from frappe.utils import add_days, cstr, flt, nowdate, nowtime, today
from erpnext.accounts.doctype.account.test_account import get_inventory_account
from erpnext.accounts.utils import get_balance_on
@@ -1091,6 +1091,36 @@ class TestDeliveryNote(FrappeTestCase):
frappe.db.exists("GL Entry", {"voucher_no": dn.name, "voucher_type": dn.doctype})
)
def test_batch_expiry_for_delivery_note(self):
from erpnext.controllers.sales_and_purchase_return import make_return_doc
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt
item = make_item(
"_Test Batch Item For Return Check",
{
"is_purchase_item": 1,
"is_stock_item": 1,
"has_batch_no": 1,
"create_new_batch": 1,
"batch_number_series": "TBIRC.#####",
},
)
pi = make_purchase_receipt(qty=1, item_code=item.name)
dn = create_delivery_note(qty=1, item_code=item.name, batch_no=pi.items[0].batch_no)
dn.load_from_db()
batch_no = dn.items[0].batch_no
self.assertTrue(batch_no)
frappe.db.set_value("Batch", batch_no, "expiry_date", add_days(today(), -1))
return_dn = make_return_doc(dn.doctype, dn.name)
return_dn.save().submit()
self.assertTrue(return_dn.docstatus == 1)
def create_delivery_note(**args):
dn = frappe.new_doc("Delivery Note")
@@ -1117,6 +1147,7 @@ def create_delivery_note(**args):
"expense_account": args.expense_account or "Cost of Goods Sold - _TC",
"cost_center": args.cost_center or "_Test Cost Center - _TC",
"serial_no": args.serial_no,
"batch_no": args.batch_no or None,
"target_warehouse": args.target_warehouse,
},
)

View File

@@ -10,6 +10,31 @@ frappe.ui.form.on("Item", {
frm.add_fetch('attribute', 'to_range', 'to_range');
frm.add_fetch('attribute', 'increment', 'increment');
frm.add_fetch('tax_type', 'tax_rate', 'tax_rate');
frm.make_methods = {
'Sales Order': () => {
open_form(frm, "Sales Order", "Sales Order Item", "items");
},
'Delivery Note': () => {
open_form(frm, "Delivery Note", "Delivery Note Item", "items");
},
'Sales Invoice': () => {
open_form(frm, "Sales Invoice", "Sales Invoice Item", "items");
},
'Purchase Order': () => {
open_form(frm, "Purchase Order", "Purchase Order Item", "items");
},
'Purchase Receipt': () => {
open_form(frm, "Purchase Receipt", "Purchase Receipt Item", "items");
},
'Purchase Invoice': () => {
open_form(frm, "Purchase Invoice", "Purchase Invoice Item", "items");
},
'Material Request': () => {
open_form(frm, "Material Request", "Material Request Item", "items");
},
};
},
onload: function(frm) {
erpnext.item.setup_queries(frm);
@@ -813,3 +838,17 @@ frappe.ui.form.on("UOM Conversion Detail", {
}
}
});
function open_form(frm, doctype, child_doctype, parentfield) {
frappe.model.with_doctype(doctype, () => {
let new_doc = frappe.model.get_new_doc(doctype);
let new_child_doc = frappe.model.add_child(new_doc, child_doctype, parentfield);
new_child_doc.item_code = frm.doc.name;
new_child_doc.item_name = frm.doc.item_name;
new_child_doc.uom = frm.doc.stock_uom;
new_child_doc.description = frm.doc.description;
frappe.ui.form.make_quick_entry(doctype, null, null, new_doc);
});
}

View File

@@ -174,7 +174,7 @@ class PickList(Document):
frappe.throw("Row #{0}: Item Code is Mandatory".format(item.idx))
item_code = item.item_code
reference = item.sales_order_item or item.material_request_item
key = (item_code, item.uom, item.warehouse, reference)
key = (item_code, item.uom, item.warehouse, item.batch_no, reference)
item.idx = None
item.name = None

View File

@@ -153,7 +153,9 @@ class StockLedgerEntry(Document):
def validate_batch(self):
if self.batch_no and self.voucher_type != "Stock Entry":
if self.voucher_type in ["Purchase Receipt", "Purchase Invoice"] and self.actual_qty < 0:
if (self.voucher_type in ["Purchase Receipt", "Purchase Invoice"] and self.actual_qty < 0) or (
self.voucher_type in ["Delivery Note", "Sales Invoice"] and self.actual_qty > 0
):
return
expiry_date = frappe.db.get_value("Batch", self.batch_no, "expiry_date")

View File

@@ -18,7 +18,7 @@
<b class="caret"></b>
</button>
<ul class="dropdown-menu dropdown-menu-right" role="menu">
{% if doc.doctype == 'Purchase Order' %}
{% if doc.doctype == 'Purchase Order' and show_make_pi_button %}
<a class="dropdown-item" href="/api/method/erpnext.buying.doctype.purchase_order.purchase_order.make_purchase_invoice_from_portal?purchase_order_name={{ doc.name }}" data-action="make_purchase_invoice">{{ _("Make Purchase Invoice") }}</a>
{% endif %}
<a class="dropdown-item" href='/printview?doctype={{ doc.doctype}}&name={{ doc.name }}&format={{ print_format }}'

View File

@@ -53,6 +53,9 @@ def get_context(context):
)
context.available_loyalty_points = int(loyalty_program_details.get("loyalty_points"))
# show Make Purchase Invoice button based on permission
context.show_make_pi_button = frappe.has_permission("Purchase Invoice", "create")
def get_attachments(dt, dn):
return frappe.get_all(

View File

@@ -45,7 +45,7 @@
.time-slot.selected {
color: white;
background: #5e64ff;
background: var(--primary-color);
}
.time-slot.selected .text-muted {