Merge branch 'develop' into report-data-trnslation

This commit is contained in:
Abdeali Chharchhoda
2024-12-02 11:33:00 +05:30
25 changed files with 10677 additions and 11231 deletions

View File

@@ -29,6 +29,12 @@ from erpnext.accounts.utils import get_fiscal_year
from erpnext.exceptions import InvalidAccountCurrency, PartyDisabled, PartyFrozen
from erpnext.utilities.regional import temporary_flag
try:
from frappe.contacts.doctype.address.address import render_address as _render_address
except ImportError:
# Older frappe versions where this function is not available
from frappe.contacts.doctype.address.address import get_address_display as _render_address
PURCHASE_TRANSACTION_TYPES = {
"Supplier Quotation",
"Purchase Order",
@@ -987,10 +993,4 @@ def add_party_account(party_type, party, company, account):
def render_address(address, check_permissions=True):
try:
from frappe.contacts.doctype.address.address import render_address as _render
except ImportError:
# Older frappe versions where this function is not available
from frappe.contacts.doctype.address.address import get_address_display as _render
return frappe.call(_render, address, check_permissions=check_permissions)
return frappe.call(_render_address, address, check_permissions=check_permissions)

View File

@@ -1013,7 +1013,7 @@ class ReceivablePayableReport:
def get_columns(self):
self.columns = []
self.add_column(_("Posting Date"), fieldtype="Date")
self.add_column(_("Posting Date"), fieldname="posting_date", fieldtype="Date")
self.add_column(
label=_("Party Type"),
fieldname="party_type",
@@ -1073,7 +1073,7 @@ class ReceivablePayableReport:
width=180,
)
self.add_column(label=_("Due Date"), fieldtype="Date")
self.add_column(label=_("Due Date"), fieldname="due_date", fieldtype="Date")
if self.account_type == "Payable":
self.add_column(label=_("Bill No"), fieldname="bill_no", fieldtype="Data")

View File

@@ -8,25 +8,20 @@
"document_type": "Document",
"engine": "InnoDB",
"field_order": [
"company",
"naming_series",
"item_code",
"item_name",
"asset_name",
"asset_category",
"location",
"image",
"column_break_3",
"status",
"company",
"asset_owner",
"asset_owner_company",
"is_existing_asset",
"is_composite_asset",
"supplier",
"customer",
"image",
"journal_entry_for_scrap",
"column_break_3",
"naming_series",
"asset_name",
"asset_category",
"location",
"split_from",
"custodian",
"department",
"purchase_details_section",
"purchase_receipt",
"purchase_receipt_item",
@@ -34,12 +29,13 @@
"purchase_invoice_item",
"purchase_date",
"available_for_use_date",
"disposal_date",
"column_break_23",
"gross_purchase_amount",
"purchase_amount",
"asset_quantity",
"additional_asset_cost",
"total_asset_cost",
"disposal_date",
"depreciation_tab",
"calculate_depreciation",
"column_break_33",
@@ -57,8 +53,6 @@
"next_depreciation_date",
"depreciation_schedule_sb",
"depreciation_schedule_view",
"accounting_dimensions_tab",
"cost_center",
"insurance_details_tab",
"policy_number",
"insurer",
@@ -68,21 +62,28 @@
"insurance_end_date",
"comprehensive_insurance",
"other_info_tab",
"booked_fixed_asset",
"maintenance_required",
"column_break_51",
"status",
"purchase_amount",
"accounting_dimensions_section",
"cost_center",
"section_break_jtou",
"custodian",
"default_finance_book",
"depr_entry_posting_status",
"booked_fixed_asset",
"customer",
"supplier",
"column_break_51",
"department",
"split_from",
"journal_entry_for_scrap",
"amended_from",
"maintenance_required",
"connections_tab"
],
"fields": [
{
"fieldname": "naming_series",
"fieldtype": "Select",
"label": "Naming Series",
"label": "Series",
"options": "ACC-ASS-.YYYY.-"
},
{
@@ -123,6 +124,7 @@
"read_only": 1
},
{
"default": "Company",
"fieldname": "asset_owner",
"fieldtype": "Select",
"label": "Asset Owner",
@@ -260,7 +262,6 @@
"columns": 10,
"fieldname": "finance_books",
"fieldtype": "Table",
"label": "Finance Books",
"options": "Asset Finance Book"
},
{
@@ -339,7 +340,6 @@
{
"allow_on_submit": 1,
"default": "0",
"description": "Check if Asset requires Preventive Maintenance or Calibration",
"fieldname": "maintenance_required",
"fieldtype": "Check",
"label": "Maintenance Required"
@@ -360,6 +360,7 @@
"default": "0",
"fieldname": "booked_fixed_asset",
"fieldtype": "Check",
"hidden": 1,
"label": "Booked Fixed Asset",
"no_copy": 1,
"read_only": 1
@@ -518,15 +519,10 @@
"label": "Purchase Invoice Item",
"options": "Purchase Invoice Item"
},
{
"fieldname": "accounting_dimensions_tab",
"fieldtype": "Tab Break",
"label": "Accounting Dimensions"
},
{
"fieldname": "insurance_details_tab",
"fieldtype": "Tab Break",
"label": "Insurance Details"
"label": "Insurance"
},
{
"fieldname": "other_info_tab",
@@ -542,7 +538,17 @@
{
"fieldname": "depreciation_tab",
"fieldtype": "Tab Break",
"label": "Depreciation Details"
"label": "Depreciation"
},
{
"fieldname": "accounting_dimensions_section",
"fieldtype": "Section Break",
"label": "Accounting Dimensions"
},
{
"fieldname": "section_break_jtou",
"fieldtype": "Section Break",
"label": "Additional Info"
}
],
"idx": 72,
@@ -586,7 +592,7 @@
"link_fieldname": "target_asset"
}
],
"modified": "2024-11-20 11:52:06.332683",
"modified": "2024-11-29 14:25:56.436124",
"modified_by": "Administrator",
"module": "Assets",
"name": "Asset",

View File

@@ -322,7 +322,7 @@ erpnext.assets.AssetCapitalization = class AssetCapitalization extends erpnext.s
method: "erpnext.assets.doctype.asset_capitalization.asset_capitalization.get_consumed_stock_item_details",
child: row,
args: {
args: {
ctx: {
item_code: row.item_code,
warehouse: row.warehouse,
stock_qty: flt(row.stock_qty),
@@ -350,7 +350,7 @@ erpnext.assets.AssetCapitalization = class AssetCapitalization extends erpnext.s
method: "erpnext.assets.doctype.asset_capitalization.asset_capitalization.get_consumed_asset_details",
child: row,
args: {
args: {
ctx: {
asset: row.asset,
doctype: me.frm.doc.doctype,
name: me.frm.doc.name,
@@ -377,7 +377,7 @@ erpnext.assets.AssetCapitalization = class AssetCapitalization extends erpnext.s
method: "erpnext.assets.doctype.asset_capitalization.asset_capitalization.get_service_item_details",
child: row,
args: {
args: {
ctx: {
item_code: row.item_code,
qty: flt(row.qty),
expense_account: row.expense_account,

View File

@@ -7,17 +7,19 @@
"field_order": [
"finance_book",
"depreciation_method",
"total_number_of_depreciations",
"total_number_of_booked_depreciations",
"daily_prorata_based",
"shift_based",
"column_break_5",
"frequency_of_depreciation",
"total_number_of_depreciations",
"depreciation_start_date",
"column_break_5",
"salvage_value_percentage",
"expected_value_after_useful_life",
"rate_of_depreciation",
"daily_prorata_based",
"shift_based",
"section_break_jkdf",
"value_after_depreciation",
"rate_of_depreciation"
"column_break_sigk",
"total_number_of_booked_depreciations"
],
"fields": [
{
@@ -67,9 +69,10 @@
"columns": 1,
"default": "0",
"depends_on": "eval:parent.doctype == 'Asset'",
"description": "Expected Value After Useful Life",
"fieldname": "expected_value_after_useful_life",
"fieldtype": "Currency",
"label": "Expected Value After Useful Life",
"label": "Salvage Value",
"options": "Company:company:default_currency"
},
{
@@ -83,10 +86,9 @@
},
{
"depends_on": "eval:doc.depreciation_method == 'Written Down Value'",
"description": "In Percentage",
"fieldname": "rate_of_depreciation",
"fieldtype": "Percent",
"label": "Rate of Depreciation"
"label": "Rate of Depreciation (%)"
},
{
"fieldname": "salvage_value_percentage",
@@ -108,16 +110,25 @@
},
{
"default": "0",
"depends_on": "total_number_of_booked_depreciations",
"fieldname": "total_number_of_booked_depreciations",
"fieldtype": "Int",
"label": "Total Number of Booked Depreciations ",
"read_only": 1
},
{
"fieldname": "section_break_jkdf",
"fieldtype": "Section Break"
},
{
"fieldname": "column_break_sigk",
"fieldtype": "Column Break"
}
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2024-05-21 15:48:20.907250",
"modified": "2024-11-29 14:36:54.399034",
"modified_by": "Administrator",
"module": "Assets",
"name": "Asset Finance Book",

View File

@@ -11,7 +11,13 @@ def set_print_templates_for_item_table(doc, settings):
"items": {
"qty": "templates/print_formats/includes/item_table_qty.html",
"serial_and_batch_bundle": "templates/print_formats/includes/serial_and_batch_bundle.html",
}
},
"packed_items": {
"serial_and_batch_bundle": "templates/print_formats/includes/serial_and_batch_bundle.html",
},
"supplied_items": {
"serial_and_batch_bundle": "templates/print_formats/includes/serial_and_batch_bundle.html",
},
}
doc.flags.compact_item_fields = ["description", "qty", "rate", "amount"]

View File

@@ -74,19 +74,13 @@ class SellingController(StockController):
if customer:
from erpnext.accounts.party import _get_party_details
fetch_payment_terms_template = False
if self.get("__islocal") or self.company != frappe.db.get_value(
self.doctype, self.name, "company"
):
fetch_payment_terms_template = True
party_details = _get_party_details(
customer,
ignore_permissions=self.flags.ignore_permissions,
doctype=self.doctype,
company=self.company,
posting_date=self.get("posting_date"),
fetch_payment_terms_template=fetch_payment_terms_template,
fetch_payment_terms_template=self.has_value_changed("company"),
party_address=self.customer_address,
shipping_address=self.shipping_address_name,
company_address=self.get("company_address"),
@@ -378,12 +372,32 @@ class SellingController(StockController):
return il
def has_product_bundle(self, item_code):
product_bundle = frappe.qb.DocType("Product Bundle")
return (
frappe.qb.from_(product_bundle)
.select(product_bundle.name)
.where((product_bundle.new_item_code == item_code) & (product_bundle.disabled == 0))
).run()
product_bundle_items = getattr(self, "_product_bundle_items", None)
if product_bundle_items is None:
self._product_bundle_items = product_bundle_items = {}
if item_code not in product_bundle_items:
self._fetch_product_bundle_items(item_code)
return product_bundle_items[item_code]
def _fetch_product_bundle_items(self, item_code):
product_bundle_items = self._product_bundle_items
items_to_fetch = {row.item_code for row in self.items if row.item_code not in product_bundle_items}
# fetch for requisite item_code even if it is not in items
items_to_fetch.add(item_code)
items_with_product_bundle = {
row.new_item_code
for row in frappe.get_all(
"Product Bundle",
filters={"new_item_code": ("in", items_to_fetch), "disabled": 0},
fields="new_item_code",
)
}
for item_code in items_to_fetch:
product_bundle_items[item_code] = item_code in items_with_product_bundle
def get_already_delivered_qty(self, current_docname, so, so_detail):
delivered_via_dn = frappe.db.sql(

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -178,10 +178,18 @@ class WorkOrder(Document):
self.validate_workstation_type()
self.reset_use_multi_level_bom()
if self.source_warehouse:
self.set_warehouses()
validate_uom_is_integer(self, "stock_uom", ["qty", "produced_qty"])
self.set_required_items(reset_only_qty=len(self.get("required_items")))
def set_warehouses(self):
for row in self.required_items:
if not row.source_warehouse:
row.source_warehouse = self.source_warehouse
def reset_use_multi_level_bom(self):
if self.is_new():
return

View File

@@ -432,8 +432,6 @@ class SerialandBatchBundle(Document):
valuation_field = "rate"
child_table = "Subcontracting Receipt Item"
precision = frappe.get_precision(child_table, valuation_field) or 2
if not rate and self.voucher_detail_no and self.voucher_no:
rate = frappe.db.get_value(child_table, self.voucher_detail_no, valuation_field)
@@ -443,9 +441,9 @@ class SerialandBatchBundle(Document):
elif (d.incoming_rate == rate) and d.qty and d.stock_value_difference:
continue
d.incoming_rate = flt(rate, precision)
d.incoming_rate = rate
if d.qty:
d.stock_value_difference = flt(d.qty) * flt(d.incoming_rate)
d.stock_value_difference = d.qty * d.incoming_rate
if save:
d.db_set(
@@ -609,8 +607,10 @@ class SerialandBatchBundle(Document):
precision = row.precision
if abs(abs(flt(self.total_qty, precision)) - abs(flt(qty, precision))) > 0.01:
total_qty = frappe.format_value(abs(flt(self.total_qty)), "Float", row)
set_qty = frappe.format_value(abs(flt(row.get(qty_field))), "Float", row)
self.throw_error_message(
f"Total quantity {abs(flt(self.total_qty))} in the Serial and Batch Bundle {bold(self.name)} does not match with the quantity {abs(flt(row.get(qty_field)))} for the Item {bold(self.item_code)} in the {self.voucher_type} # {self.voucher_no}"
f"Total quantity {total_qty} in the Serial and Batch Bundle {bold(self.name)} does not match with the quantity {set_qty} for the Item {bold(self.item_code)} in the {self.voucher_type} # {self.voucher_no}"
)
def get_qty_field(self, row, qty_field=None) -> str:
@@ -972,6 +972,9 @@ class SerialandBatchBundle(Document):
):
return
if self.voucher_type in ["Sales Invoice", "Delivery Note"] and self.type_of_transaction == "Inward":
return
if not self.has_batch_no:
return

View File

@@ -478,7 +478,7 @@ def get_serial_or_batch_nos(bundle):
html = "<table class= 'table table-borderless' style='margin-top: 0px;margin-bottom: 0px;'>"
for d in data:
if d.serial_no:
html += f"<tr><td>{d.batch_no}</th><th>{d.serial_no}</th ><th>{abs(d.qty)}</th></tr>"
html += f"<tr><td>{d.batch_no}</td><td>{d.serial_no}</td><td>{abs(d.qty)}</td></tr>"
else:
html += f"<tr><td>{d.batch_no}</td><td>{abs(d.qty)}</td></tr>"

View File

@@ -257,11 +257,11 @@ def validate_uom_is_integer(doc, uom_field, qty_fields, child_dt=None):
if isinstance(qty_fields, str):
qty_fields = [qty_fields]
distinct_uoms = list(set(d.get(uom_field) for d in doc.get_all_children()))
integer_uoms = list(
filter(
lambda uom: frappe.db.get_value("UOM", uom, "must_be_whole_number", cache=True) or None,
distinct_uoms,
distinct_uoms = tuple(set(uom for uom in (d.get(uom_field) for d in doc.get_all_children()) if uom))
integer_uoms = set(
d[0]
for d in frappe.db.get_values(
"UOM", (("name", "in", distinct_uoms), ("must_be_whole_number", "=", 1)), cache=True
)
)