Skip to content

Instantly share code, notes, and snippets.

@esafwan
Created July 4, 2024 07:49
Show Gist options
  • Save esafwan/bc98258ce73528451239a666b3add873 to your computer and use it in GitHub Desktop.
Save esafwan/bc98258ce73528451239a666b3add873 to your computer and use it in GitHub Desktop.
Purchase Reciept PR

Logical Issues

  1. Redundant List Initialization: stock_and_asset_items is initialized twice.
  2. Confusing Conditional Logic: The logic to determine if the tax amount should be proportionally distributed or based on item-specific rates can be streamlined.
  3. Tax Calculation: The tax rate calculation logic might be unclear and could lead to errors if the item_tax_rate JSON structure or tax conditions are not consistent.

Code Improvement Suggestions

  1. Remove Redundant List Initialization: Only initialize stock_and_asset_items once.
  2. Simplify Conditional Logic: Streamline the conditions for tax amount calculation to improve readability and maintainability.
  3. Use Modern Python Constructs: Utilize list comprehensions and modern Python features for cleaner code.
  4. Improve Error Handling: Add clear error messages and handle potential edge cases, such as empty tax rates or missing item details.
  5. Use Meaningful Variable Names: Ensure variable names clearly convey their purpose, improving code readability.
  6. Optimize JSON Handling: Ensure consistent and efficient handling of JSON data, avoiding repeated parsing.

General Frappe/ERPNext Coding Style

  1. Follow Frappe Naming Conventions: Use consistent naming for methods and variables as per Frappe guidelines.
  2. Modular Functions: Break down large functions into smaller, reusable ones to enhance readability and maintainability.
  3. Clear Documentation: Add docstrings and comments where necessary to explain complex logic.
  4. Efficient Database Calls: Minimize database calls within loops to enhance performance.
  5. Code Formatting: Ensure consistent code formatting and indentation as per Frappe standards.

--

Logical Issues

1. Redundant List Initialization Current:

stock_and_asset_items = []
stock_and_asset_items = self.get_stock_items() + self.get_asset_items()

Improved:

stock_and_asset_items = self.get_stock_items() + self.get_asset_items()

2. Confusing Conditional Logic Current:

if ((item_tax_data == {} and (not any_non_empty_dict or self.taxes_and_charges not in ["", None])) or \
	(self.taxes_and_charges not in ["", None] and item_tax_data != {})):

Improved:

if not item_tax_data and (not any_non_empty_dict or self.taxes_and_charges):
    ...
elif self.taxes_and_charges and item_tax_data:
    ...

3. Tax Calculation Current:

item_tax_rate = 0.0
for key, value in item_tax_data.items():
	for d in self.get("taxes"):
		if d.category in ["Valuation", "Valuation and Total"] and d.account_head == key:
			item_tax_rate += value
			item.item_tax_amount = flt(
				((item_tax_rate / 100) * item.rate), self.precision("item_tax_amount", item)
			)

Improved:

item_tax_amount = 0.0
for key, value in item_tax_data.items():
	for d in self.get("taxes"):
		if d.category in ["Valuation", "Valuation and Total"] and d.account_head == key:
			item_tax_amount += (value / 100) * item.rate
item.item_tax_amount = flt(item_tax_amount, self.precision("item_tax_amount", item))

Code Improvement Suggestions

1. Remove Redundant List Initialization Already shown above.

2. Simplify Conditional Logic Already shown above.

3. Use Modern Python Constructs Current:

if item.item_code and item.item_code in stock_and_asset_items:
    ...

Improved:

if item.item_code in stock_and_asset_items:
    ...

4. Improve Error Handling Current:

if flt(item.conversion_factor) == 0.0:
	frappe.throw(_("Conversion factor cannot be zero for item {0}").format(item.item_code))

Improved:

if not flt(item.conversion_factor):
	item.conversion_factor = get_conversion_factor(item.item_code, item.uom).get("conversion_factor", 1.0)

5. Use Meaningful Variable Names Current:

last_item_idx = 1
for d in self.get("items"):
    ...

Improved:

last_item_index = 1
for item in self.get("items"):
    ...

6. Optimize JSON Handling Current:

import json
item_tax_data = json.loads(item.item_tax_rate)

Improved:

item_tax_data = frappe.parse_json(item.item_tax_rate)

General Frappe/ERPNext Coding Style

1. Follow Frappe Naming Conventions Current:

last_item_idx = 1

Convention:

  • Use descriptive variable names.
  • Follow snake_case for variable names.

2. Modular Functions Example: Current:

def update_valuation_rate(self, reset_outgoing_rate=True):
	...
	item_tax_data = frappe.parse_json(item.item_tax_rate)
	any_non_empty_dict = any(frappe.parse_json(ite.item_tax_rate) != {} for ite in self.get("items"))

Improved:

def update_valuation_rate(self, reset_outgoing_rate=True):
	...
	item_tax_data = frappe.parse_json(item.item_tax_rate)
	any_non_empty_dict = self._any_non_empty_tax_data()

def _any_non_empty_tax_data(self):
	return any(frappe.parse_json(ite.item_tax_rate) != {} for ite in self.get("items"))

3. Clear Documentation Example:

def update_valuation_rate(self, reset_outgoing_rate=True):
	"""
	Update the valuation rate of items based on tax and other factors.
	:param reset_outgoing_rate: Boolean indicating if outgoing rates should be reset
	"""
	...

4. Efficient Database Calls Current:

for item in self.get("items"):
    item_tax_data = frappe.parse_json(item.item_tax_rate)
    for key, value in item_tax_data.items():
        for d in self.get("taxes"):
            ...

Improved:

tax_details = {d.account_head: d for d in self.get("taxes") if d.category in ["Valuation", "Valuation and Total"]}
for item in self.get("items"):
    item_tax_data = frappe.parse_json(item.item_tax_rate)
    for key, value in item_tax_data.items():
        if key in tax_details:
            ...

5. Code Formatting Ensure consistent indentation, line breaks, and use of spaces around operators as per PEP 8 standards.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment