mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-06 21:59:13 +00:00
Merge branch 'develop' into fix/github-issue/28766
This commit is contained in:
@@ -1758,6 +1758,8 @@ def get_payment_entry(
|
|||||||
pe.setup_party_account_field()
|
pe.setup_party_account_field()
|
||||||
pe.set_missing_values()
|
pe.set_missing_values()
|
||||||
|
|
||||||
|
update_accounting_dimensions(pe, doc)
|
||||||
|
|
||||||
if party_account and bank:
|
if party_account and bank:
|
||||||
pe.set_exchange_rate(ref_doc=reference_doc)
|
pe.set_exchange_rate(ref_doc=reference_doc)
|
||||||
pe.set_amounts()
|
pe.set_amounts()
|
||||||
@@ -1775,6 +1777,18 @@ def get_payment_entry(
|
|||||||
return pe
|
return pe
|
||||||
|
|
||||||
|
|
||||||
|
def update_accounting_dimensions(pe, doc):
|
||||||
|
"""
|
||||||
|
Updates accounting dimensions in Payment Entry based on the accounting dimensions in the reference document
|
||||||
|
"""
|
||||||
|
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
|
||||||
|
get_accounting_dimensions,
|
||||||
|
)
|
||||||
|
|
||||||
|
for dimension in get_accounting_dimensions():
|
||||||
|
pe.set(dimension, doc.get(dimension))
|
||||||
|
|
||||||
|
|
||||||
def get_bank_cash_account(doc, bank_account):
|
def get_bank_cash_account(doc, bank_account):
|
||||||
bank = get_default_bank_cash_account(
|
bank = get_default_bank_cash_account(
|
||||||
doc.company, "Bank", mode_of_payment=doc.get("mode_of_payment"), account=bank_account
|
doc.company, "Bank", mode_of_payment=doc.get("mode_of_payment"), account=bank_account
|
||||||
|
|||||||
@@ -32,6 +32,10 @@
|
|||||||
"iban",
|
"iban",
|
||||||
"branch_code",
|
"branch_code",
|
||||||
"swift_number",
|
"swift_number",
|
||||||
|
"accounting_dimensions_section",
|
||||||
|
"cost_center",
|
||||||
|
"dimension_col_break",
|
||||||
|
"project",
|
||||||
"recipient_and_message",
|
"recipient_and_message",
|
||||||
"print_format",
|
"print_format",
|
||||||
"email_to",
|
"email_to",
|
||||||
@@ -362,13 +366,35 @@
|
|||||||
"label": "Payment Channel",
|
"label": "Payment Channel",
|
||||||
"options": "\nEmail\nPhone",
|
"options": "\nEmail\nPhone",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collapsible": 1,
|
||||||
|
"fieldname": "accounting_dimensions_section",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Accounting Dimensions"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "cost_center",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Cost Center",
|
||||||
|
"options": "Cost Center"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "dimension_col_break",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "project",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Project",
|
||||||
|
"options": "Project"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"in_create": 1,
|
"in_create": 1,
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-09-30 16:19:43.680025",
|
"modified": "2022-12-21 16:56:40.115737",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Payment Request",
|
"name": "Payment Request",
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ from frappe.model.document import Document
|
|||||||
from frappe.utils import flt, get_url, nowdate
|
from frappe.utils import flt, get_url, nowdate
|
||||||
from frappe.utils.background_jobs import enqueue
|
from frappe.utils.background_jobs import enqueue
|
||||||
|
|
||||||
|
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
|
||||||
|
get_accounting_dimensions,
|
||||||
|
)
|
||||||
from erpnext.accounts.doctype.payment_entry.payment_entry import (
|
from erpnext.accounts.doctype.payment_entry.payment_entry import (
|
||||||
get_company_defaults,
|
get_company_defaults,
|
||||||
get_payment_entry,
|
get_payment_entry,
|
||||||
@@ -270,6 +273,17 @@ class PaymentRequest(Document):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Update dimensions
|
||||||
|
payment_entry.update(
|
||||||
|
{
|
||||||
|
"cost_center": self.get("cost_center"),
|
||||||
|
"project": self.get("project"),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
for dimension in get_accounting_dimensions():
|
||||||
|
payment_entry.update({dimension: self.get(dimension)})
|
||||||
|
|
||||||
if payment_entry.difference_amount:
|
if payment_entry.difference_amount:
|
||||||
company_details = get_company_defaults(ref_doc.company)
|
company_details = get_company_defaults(ref_doc.company)
|
||||||
|
|
||||||
@@ -449,6 +463,17 @@ def make_payment_request(**args):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Update dimensions
|
||||||
|
pr.update(
|
||||||
|
{
|
||||||
|
"cost_center": ref_doc.get("cost_center"),
|
||||||
|
"project": ref_doc.get("project"),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
for dimension in get_accounting_dimensions():
|
||||||
|
pr.update({dimension: ref_doc.get(dimension)})
|
||||||
|
|
||||||
if args.order_type == "Shopping Cart" or args.mute_email:
|
if args.order_type == "Shopping Cart" or args.mute_email:
|
||||||
pr.flags.mute_email = True
|
pr.flags.mute_email = True
|
||||||
|
|
||||||
|
|||||||
@@ -252,10 +252,15 @@ def get_other_conditions(conditions, values, args):
|
|||||||
|
|
||||||
if args.get("doctype") in [
|
if args.get("doctype") in [
|
||||||
"Quotation",
|
"Quotation",
|
||||||
|
"Quotation Item",
|
||||||
"Sales Order",
|
"Sales Order",
|
||||||
|
"Sales Order Item",
|
||||||
"Delivery Note",
|
"Delivery Note",
|
||||||
|
"Delivery Note Item",
|
||||||
"Sales Invoice",
|
"Sales Invoice",
|
||||||
|
"Sales Invoice Item",
|
||||||
"POS Invoice",
|
"POS Invoice",
|
||||||
|
"POS Invoice Item",
|
||||||
]:
|
]:
|
||||||
conditions += """ and ifnull(`tabPricing Rule`.selling, 0) = 1"""
|
conditions += """ and ifnull(`tabPricing Rule`.selling, 0) = 1"""
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -890,7 +890,7 @@
|
|||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-11-02 12:53:12.693217",
|
"modified": "2022-12-28 16:17:33.484531",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Sales Invoice Item",
|
"name": "Sales Invoice Item",
|
||||||
|
|||||||
@@ -53,9 +53,6 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
|||||||
item_details = get_item_details()
|
item_details = get_item_details()
|
||||||
|
|
||||||
for d in item_list:
|
for d in item_list:
|
||||||
if not d.stock_qty:
|
|
||||||
continue
|
|
||||||
|
|
||||||
item_record = item_details.get(d.item_code)
|
item_record = item_details.get(d.item_code)
|
||||||
|
|
||||||
purchase_receipt = None
|
purchase_receipt = None
|
||||||
@@ -94,7 +91,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
|||||||
"expense_account": expense_account,
|
"expense_account": expense_account,
|
||||||
"stock_qty": d.stock_qty,
|
"stock_qty": d.stock_qty,
|
||||||
"stock_uom": d.stock_uom,
|
"stock_uom": d.stock_uom,
|
||||||
"rate": d.base_net_amount / d.stock_qty,
|
"rate": d.base_net_amount / d.stock_qty if d.stock_qty else d.base_net_amount,
|
||||||
"amount": d.base_net_amount,
|
"amount": d.base_net_amount,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -207,31 +207,36 @@ class PurchaseOrder(BuyingController):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def validate_fg_item_for_subcontracting(self):
|
def validate_fg_item_for_subcontracting(self):
|
||||||
if self.is_subcontracted and not self.is_old_subcontracting_flow:
|
if self.is_subcontracted:
|
||||||
|
if not self.is_old_subcontracting_flow:
|
||||||
|
for item in self.items:
|
||||||
|
if not item.fg_item:
|
||||||
|
frappe.throw(
|
||||||
|
_("Row #{0}: Finished Good Item is not specified for service item {1}").format(
|
||||||
|
item.idx, item.item_code
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
if not frappe.get_value("Item", item.fg_item, "is_sub_contracted_item"):
|
||||||
|
frappe.throw(
|
||||||
|
_(
|
||||||
|
"Row #{0}: Finished Good Item {1} must be a sub-contracted item for service item {2}"
|
||||||
|
).format(item.idx, item.fg_item, item.item_code)
|
||||||
|
)
|
||||||
|
elif not frappe.get_value("Item", item.fg_item, "default_bom"):
|
||||||
|
frappe.throw(
|
||||||
|
_("Row #{0}: Default BOM not found for FG Item {1}").format(item.idx, item.fg_item)
|
||||||
|
)
|
||||||
|
if not item.fg_item_qty:
|
||||||
|
frappe.throw(
|
||||||
|
_("Row #{0}: Finished Good Item Qty is not specified for service item {0}").format(
|
||||||
|
item.idx, item.item_code
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
for item in self.items:
|
for item in self.items:
|
||||||
if not item.fg_item:
|
item.set("fg_item", None)
|
||||||
frappe.throw(
|
item.set("fg_item_qty", 0)
|
||||||
_("Row #{0}: Finished Good Item is not specified for service item {1}").format(
|
|
||||||
item.idx, item.item_code
|
|
||||||
)
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
if not frappe.get_value("Item", item.fg_item, "is_sub_contracted_item"):
|
|
||||||
frappe.throw(
|
|
||||||
_(
|
|
||||||
"Row #{0}: Finished Good Item {1} must be a sub-contracted item for service item {2}"
|
|
||||||
).format(item.idx, item.fg_item, item.item_code)
|
|
||||||
)
|
|
||||||
elif not frappe.get_value("Item", item.fg_item, "default_bom"):
|
|
||||||
frappe.throw(
|
|
||||||
_("Row #{0}: Default BOM not found for FG Item {1}").format(item.idx, item.fg_item)
|
|
||||||
)
|
|
||||||
if not item.fg_item_qty:
|
|
||||||
frappe.throw(
|
|
||||||
_("Row #{0}: Finished Good Item Qty is not specified for service item {0}").format(
|
|
||||||
item.idx, item.item_code
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_schedule_dates(self):
|
def get_schedule_dates(self):
|
||||||
for d in self.get("items"):
|
for d in self.get("items"):
|
||||||
|
|||||||
@@ -584,7 +584,12 @@ class AccountsController(TransactionBase):
|
|||||||
if bool(uom) != bool(stock_uom): # xor
|
if bool(uom) != bool(stock_uom): # xor
|
||||||
item.stock_uom = item.uom = uom or stock_uom
|
item.stock_uom = item.uom = uom or stock_uom
|
||||||
|
|
||||||
item.conversion_factor = get_uom_conv_factor(item.get("uom"), item.get("stock_uom"))
|
# UOM cannot be zero so substitute as 1
|
||||||
|
item.conversion_factor = (
|
||||||
|
get_uom_conv_factor(item.get("uom"), item.get("stock_uom"))
|
||||||
|
or item.get("conversion_factor")
|
||||||
|
or 1
|
||||||
|
)
|
||||||
|
|
||||||
if self.doctype == "Purchase Invoice":
|
if self.doctype == "Purchase Invoice":
|
||||||
self.set_expense_account(for_validate)
|
self.set_expense_account(for_validate)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"creation": "2019-05-21 07:41:53.536536",
|
"creation": "2019-05-21 07:41:53.536536",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
@@ -7,10 +8,14 @@
|
|||||||
"section_break_2",
|
"section_break_2",
|
||||||
"account_sid",
|
"account_sid",
|
||||||
"api_key",
|
"api_key",
|
||||||
"api_token"
|
"api_token",
|
||||||
|
"section_break_6",
|
||||||
|
"map_custom_field_to_doctype",
|
||||||
|
"target_doctype"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
|
"default": "0",
|
||||||
"fieldname": "enabled",
|
"fieldname": "enabled",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Enabled"
|
"label": "Enabled"
|
||||||
@@ -18,7 +23,8 @@
|
|||||||
{
|
{
|
||||||
"depends_on": "enabled",
|
"depends_on": "enabled",
|
||||||
"fieldname": "section_break_2",
|
"fieldname": "section_break_2",
|
||||||
"fieldtype": "Section Break"
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Credentials"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "account_sid",
|
"fieldname": "account_sid",
|
||||||
@@ -34,10 +40,31 @@
|
|||||||
"fieldname": "api_key",
|
"fieldname": "api_key",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "API Key"
|
"label": "API Key"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "enabled",
|
||||||
|
"fieldname": "section_break_6",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Custom Field"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "map_custom_field_to_doctype",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Map Custom Field to DocType"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "map_custom_field_to_doctype",
|
||||||
|
"fieldname": "target_doctype",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Target DocType",
|
||||||
|
"mandatory_depends_on": "map_custom_field_to_doctype",
|
||||||
|
"options": "DocType"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"modified": "2019-05-22 06:25:18.026997",
|
"links": [],
|
||||||
|
"modified": "2022-12-14 17:24:50.176107",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "ERPNext Integrations",
|
"module": "ERPNext Integrations",
|
||||||
"name": "Exotel Settings",
|
"name": "Exotel Settings",
|
||||||
@@ -57,5 +84,6 @@
|
|||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "ASC",
|
"sort_order": "ASC",
|
||||||
|
"states": [],
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
}
|
}
|
||||||
@@ -72,6 +72,24 @@ def get_call_log(call_payload):
|
|||||||
return frappe.get_doc("Call Log", call_log_id)
|
return frappe.get_doc("Call Log", call_log_id)
|
||||||
|
|
||||||
|
|
||||||
|
def map_custom_field(call_payload, call_log):
|
||||||
|
field_value = call_payload.get("CustomField")
|
||||||
|
|
||||||
|
if not field_value:
|
||||||
|
return call_log
|
||||||
|
|
||||||
|
settings = get_exotel_settings()
|
||||||
|
target_doctype = settings.target_doctype
|
||||||
|
mapping_enabled = settings.map_custom_field_to_doctype
|
||||||
|
|
||||||
|
if not mapping_enabled or not target_doctype:
|
||||||
|
return call_log
|
||||||
|
|
||||||
|
call_log.append("links", {"link_doctype": target_doctype, "link_name": field_value})
|
||||||
|
|
||||||
|
return call_log
|
||||||
|
|
||||||
|
|
||||||
def create_call_log(call_payload):
|
def create_call_log(call_payload):
|
||||||
call_log = frappe.new_doc("Call Log")
|
call_log = frappe.new_doc("Call Log")
|
||||||
call_log.id = call_payload.get("CallSid")
|
call_log.id = call_payload.get("CallSid")
|
||||||
@@ -79,6 +97,7 @@ def create_call_log(call_payload):
|
|||||||
call_log.medium = call_payload.get("To")
|
call_log.medium = call_payload.get("To")
|
||||||
call_log.status = "Ringing"
|
call_log.status = "Ringing"
|
||||||
setattr(call_log, "from", call_payload.get("CallFrom"))
|
setattr(call_log, "from", call_payload.get("CallFrom"))
|
||||||
|
map_custom_field(call_payload, call_log)
|
||||||
call_log.save(ignore_permissions=True)
|
call_log.save(ignore_permissions=True)
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
return call_log
|
return call_log
|
||||||
@@ -93,10 +112,10 @@ def get_call_status(call_id):
|
|||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def make_a_call(from_number, to_number, caller_id):
|
def make_a_call(from_number, to_number, caller_id, **kwargs):
|
||||||
endpoint = get_exotel_endpoint("Calls/connect.json?details=true")
|
endpoint = get_exotel_endpoint("Calls/connect.json?details=true")
|
||||||
response = requests.post(
|
response = requests.post(
|
||||||
endpoint, data={"From": from_number, "To": to_number, "CallerId": caller_id}
|
endpoint, data={"From": from_number, "To": to_number, "CallerId": caller_id, **kwargs}
|
||||||
)
|
)
|
||||||
|
|
||||||
return response.json()
|
return response.json()
|
||||||
|
|||||||
@@ -319,3 +319,4 @@ erpnext.patches.v14_0.create_accounting_dimensions_for_asset_capitalization
|
|||||||
erpnext.patches.v14_0.update_partial_tds_fields
|
erpnext.patches.v14_0.update_partial_tds_fields
|
||||||
erpnext.patches.v14_0.create_incoterms_and_migrate_shipment
|
erpnext.patches.v14_0.create_incoterms_and_migrate_shipment
|
||||||
erpnext.patches.v14_0.setup_clear_repost_logs
|
erpnext.patches.v14_0.setup_clear_repost_logs
|
||||||
|
erpnext.patches.v14_0.create_accounting_dimensions_for_payment_request
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import frappe
|
||||||
|
from frappe.custom.doctype.custom_field.custom_field import create_custom_field
|
||||||
|
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
accounting_dimensions = frappe.db.get_all(
|
||||||
|
"Accounting Dimension", fields=["fieldname", "label", "document_type", "disabled"]
|
||||||
|
)
|
||||||
|
|
||||||
|
if not accounting_dimensions:
|
||||||
|
return
|
||||||
|
|
||||||
|
doctype = "Payment Request"
|
||||||
|
|
||||||
|
for d in accounting_dimensions:
|
||||||
|
field = frappe.db.get_value("Custom Field", {"dt": doctype, "fieldname": d.fieldname})
|
||||||
|
|
||||||
|
if field:
|
||||||
|
continue
|
||||||
|
|
||||||
|
df = {
|
||||||
|
"fieldname": d.fieldname,
|
||||||
|
"label": d.label,
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": d.document_type,
|
||||||
|
"insert_after": "accounting_dimensions_section",
|
||||||
|
}
|
||||||
|
|
||||||
|
create_custom_field(doctype, df, ignore_validate=True)
|
||||||
|
|
||||||
|
frappe.clear_cache(doctype=doctype)
|
||||||
@@ -737,7 +737,7 @@ def get_customer_primary_contact(doctype, txt, searchfield, start, page_len, fil
|
|||||||
qb.from_(con)
|
qb.from_(con)
|
||||||
.join(dlink)
|
.join(dlink)
|
||||||
.on(con.name == dlink.parent)
|
.on(con.name == dlink.parent)
|
||||||
.select(con.name, con.full_name, con.email_id)
|
.select(con.name, con.email_id)
|
||||||
.where((dlink.link_name == customer) & (con.name.like(f"%{txt}%")))
|
.where((dlink.link_name == customer) & (con.name.like(f"%{txt}%")))
|
||||||
.run()
|
.run()
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1024,6 +1024,15 @@ def make_purchase_order(source_name, selected_items=None, target_doc=None):
|
|||||||
]
|
]
|
||||||
items_to_map = list(set(items_to_map))
|
items_to_map = list(set(items_to_map))
|
||||||
|
|
||||||
|
def is_drop_ship_order(target):
|
||||||
|
drop_ship = True
|
||||||
|
for item in target.items:
|
||||||
|
if not item.delivered_by_supplier:
|
||||||
|
drop_ship = False
|
||||||
|
break
|
||||||
|
|
||||||
|
return drop_ship
|
||||||
|
|
||||||
def set_missing_values(source, target):
|
def set_missing_values(source, target):
|
||||||
target.supplier = ""
|
target.supplier = ""
|
||||||
target.apply_discount_on = ""
|
target.apply_discount_on = ""
|
||||||
@@ -1031,6 +1040,14 @@ def make_purchase_order(source_name, selected_items=None, target_doc=None):
|
|||||||
target.discount_amount = 0.0
|
target.discount_amount = 0.0
|
||||||
target.inter_company_order_reference = ""
|
target.inter_company_order_reference = ""
|
||||||
target.shipping_rule = ""
|
target.shipping_rule = ""
|
||||||
|
|
||||||
|
if is_drop_ship_order(target):
|
||||||
|
target.customer = source.customer
|
||||||
|
target.customer_name = source.customer_name
|
||||||
|
target.shipping_address = source.shipping_address_name
|
||||||
|
else:
|
||||||
|
target.customer = target.customer_name = target.shipping_address = None
|
||||||
|
|
||||||
target.run_method("set_missing_values")
|
target.run_method("set_missing_values")
|
||||||
target.run_method("calculate_taxes_and_totals")
|
target.run_method("calculate_taxes_and_totals")
|
||||||
|
|
||||||
@@ -1057,11 +1074,9 @@ def make_purchase_order(source_name, selected_items=None, target_doc=None):
|
|||||||
"contact_email",
|
"contact_email",
|
||||||
"contact_person",
|
"contact_person",
|
||||||
"taxes_and_charges",
|
"taxes_and_charges",
|
||||||
|
"shipping_address",
|
||||||
"terms",
|
"terms",
|
||||||
],
|
],
|
||||||
"field_map": [
|
|
||||||
["shipping_address_name", "shipping_address"],
|
|
||||||
],
|
|
||||||
"validation": {"docstatus": ["=", 1]},
|
"validation": {"docstatus": ["=", 1]},
|
||||||
},
|
},
|
||||||
"Sales Order Item": {
|
"Sales Order Item": {
|
||||||
|
|||||||
@@ -102,6 +102,9 @@ erpnext.stock.ItemDashboard = class ItemDashboard {
|
|||||||
args: args,
|
args: args,
|
||||||
callback: function (r) {
|
callback: function (r) {
|
||||||
me.render(r.message);
|
me.render(r.message);
|
||||||
|
if(me.after_refresh) {
|
||||||
|
me.after_refresh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,15 @@ frappe.ui.form.on('Pick List', {
|
|||||||
if (!(frm.doc.locations && frm.doc.locations.length)) {
|
if (!(frm.doc.locations && frm.doc.locations.length)) {
|
||||||
frappe.msgprint(__('Add items in the Item Locations table'));
|
frappe.msgprint(__('Add items in the Item Locations table'));
|
||||||
} else {
|
} else {
|
||||||
frm.call('set_item_locations', {save: save});
|
frappe.call({
|
||||||
|
method: "set_item_locations",
|
||||||
|
doc: frm.doc,
|
||||||
|
args: {
|
||||||
|
"save": save,
|
||||||
|
},
|
||||||
|
freeze: 1,
|
||||||
|
freeze_message: __("Setting Item Locations..."),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
get_item_locations: (frm) => {
|
get_item_locations: (frm) => {
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ class PickList(Document):
|
|||||||
|
|
||||||
# reset
|
# reset
|
||||||
self.delete_key("locations")
|
self.delete_key("locations")
|
||||||
|
updated_locations = frappe._dict()
|
||||||
for item_doc in items:
|
for item_doc in items:
|
||||||
item_code = item_doc.item_code
|
item_code = item_doc.item_code
|
||||||
|
|
||||||
@@ -155,7 +156,26 @@ class PickList(Document):
|
|||||||
for row in locations:
|
for row in locations:
|
||||||
location = item_doc.as_dict()
|
location = item_doc.as_dict()
|
||||||
location.update(row)
|
location.update(row)
|
||||||
self.append("locations", location)
|
key = (
|
||||||
|
location.item_code,
|
||||||
|
location.warehouse,
|
||||||
|
location.uom,
|
||||||
|
location.batch_no,
|
||||||
|
location.serial_no,
|
||||||
|
location.sales_order_item or location.material_request_item,
|
||||||
|
)
|
||||||
|
|
||||||
|
if key not in updated_locations:
|
||||||
|
updated_locations.setdefault(key, location)
|
||||||
|
else:
|
||||||
|
updated_locations[key].qty += location.qty
|
||||||
|
updated_locations[key].stock_qty += location.stock_qty
|
||||||
|
|
||||||
|
for location in updated_locations.values():
|
||||||
|
if location.picked_qty > location.stock_qty:
|
||||||
|
location.picked_qty = location.stock_qty
|
||||||
|
|
||||||
|
self.append("locations", location)
|
||||||
|
|
||||||
# If table is empty on update after submit, set stock_qty, picked_qty to 0 so that indicator is red
|
# If table is empty on update after submit, set stock_qty, picked_qty to 0 so that indicator is red
|
||||||
# and give feedback to the user. This is to avoid empty Pick Lists.
|
# and give feedback to the user. This is to avoid empty Pick Lists.
|
||||||
@@ -441,7 +461,7 @@ def get_available_item_locations_for_batched_item(
|
|||||||
sle.`batch_no`,
|
sle.`batch_no`,
|
||||||
sle.`item_code`
|
sle.`item_code`
|
||||||
HAVING `qty` > 0
|
HAVING `qty` > 0
|
||||||
ORDER BY IFNULL(batch.`expiry_date`, '2200-01-01'), batch.`creation`
|
ORDER BY IFNULL(batch.`expiry_date`, '2200-01-01'), batch.`creation`, sle.`batch_no`, sle.`warehouse`
|
||||||
""".format(
|
""".format(
|
||||||
warehouse_condition=warehouse_condition
|
warehouse_condition=warehouse_condition
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -112,6 +112,10 @@ frappe.ui.form.on('Stock Entry', {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
attach_bom_items(frm.doc.bom_no);
|
attach_bom_items(frm.doc.bom_no);
|
||||||
|
|
||||||
|
if(!check_should_not_attach_bom_items(frm.doc.bom_no)) {
|
||||||
|
erpnext.accounts.dimensions.update_dimension(frm, frm.doctype);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setup_quality_inspection: function(frm) {
|
setup_quality_inspection: function(frm) {
|
||||||
@@ -326,7 +330,11 @@ frappe.ui.form.on('Stock Entry', {
|
|||||||
}
|
}
|
||||||
|
|
||||||
frm.trigger("setup_quality_inspection");
|
frm.trigger("setup_quality_inspection");
|
||||||
attach_bom_items(frm.doc.bom_no)
|
attach_bom_items(frm.doc.bom_no);
|
||||||
|
|
||||||
|
if(!check_should_not_attach_bom_items(frm.doc.bom_no)) {
|
||||||
|
erpnext.accounts.dimensions.update_dimension(frm, frm.doctype);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
before_save: function(frm) {
|
before_save: function(frm) {
|
||||||
@@ -939,7 +947,10 @@ erpnext.stock.StockEntry = class StockEntry extends erpnext.stock.StockControlle
|
|||||||
method: "get_items",
|
method: "get_items",
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
if(!r.exc) refresh_field("items");
|
if(!r.exc) refresh_field("items");
|
||||||
if(me.frm.doc.bom_no) attach_bom_items(me.frm.doc.bom_no)
|
if(me.frm.doc.bom_no) {
|
||||||
|
attach_bom_items(me.frm.doc.bom_no);
|
||||||
|
erpnext.accounts.dimensions.update_dimension(me.frm, me.frm.doctype);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user