-
Notifications
You must be signed in to change notification settings - Fork 9.9k
feat: add support for printing batch and serial number barcodes with customization #50654
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
…ctypes Purchase receipt, Stock Entry and Delivery Note
📝 WalkthroughWalkthroughAdds barcode printing support across print settings, controllers, doctypes, and templates. Two new Print Settings checkboxes ( Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Suggested labels
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
erpnext/controllers/print_settings.py (1)
25-44: Barcode templates are shadowed bycompact_item_printBecause
compact_item_printis checked first, the barcode branches never run unless the user manually disables compact printing in Print Settings. That makes the newprint_*_barcodesflags confusing: enabling them alone has no effect.Consider giving barcode layouts precedence over the compact layout:
- if settings.compact_item_print: - doc.child_print_templates["items"][ - "description" - ] = "templates/print_formats/includes/item_table_description.html" - doc.flags.format_columns = format_columns - - elif (settings.print_batch_no_barcodes and settings.print_serial_no_barcodes): - doc.print_templates = { - "items": "templates/print_formats/includes/serial_and_batch_no_barcodes.html" - } - - elif settings.print_batch_no_barcodes: - doc.print_templates = { - "items": "templates/print_formats/includes/batch_no_barcodes.html" - } - - elif settings.print_serial_no_barcodes: - doc.print_templates = { - "items": "templates/print_formats/includes/serial_no_barcodes.html" - } + if settings.print_batch_no_barcodes and settings.print_serial_no_barcodes: + doc.print_templates = { + "items": "templates/print_formats/includes/serial_and_batch_no_barcodes.html" + } + elif settings.print_batch_no_barcodes: + doc.print_templates = { + "items": "templates/print_formats/includes/batch_no_barcodes.html" + } + elif settings.print_serial_no_barcodes: + doc.print_templates = { + "items": "templates/print_formats/includes/serial_no_barcodes.html" + } + elif settings.compact_item_print: + doc.child_print_templates["items"][ + "description" + ] = "templates/print_formats/includes/item_table_description.html" + doc.flags.format_columns = format_columns
🧹 Nitpick comments (4)
erpnext/templates/print_formats/includes/batch_no_barcodes.html (1)
1-70: Batch barcode template looks correct; consider minor polish onlyMarkup and JsBarcode usage are consistent and should render batch barcodes per item correctly. Any follow‑ups here are optional (e.g., wrapping column headers in
{{ _() }}for i18n, or prefetching bundle data server‑side if performance becomes an issue on very large receipts).erpnext/setup/install.py (1)
117-130: Custom fields wiring is fine; ensure upgrade path covers existing sitesThe two new Print Settings checks are defined correctly and inserted after
print_taxes_with_zero_amount. Sincecreate_print_setting_custom_fields()is only called fromafter_install(), please make sure there is a separate patch/migration to create these fields on existing sites as well; otherwise barcode toggles will only appear on fresh installs.erpnext/templates/print_formats/includes/serial_no_barcodes.html (1)
1-69: Serial barcode template is consistent and soundThe serial‑number barcode template mirrors the batch version correctly and should work as expected with the new Purchase Receipt print settings. Any remaining tweaks (e.g., i18n for headers, prefetching bundle data if performance becomes an issue) are optional.
erpnext/stock/doctype/purchase_receipt/purchase_receipt.json (1)
140-147: Purchase Receipt barcode configuration fields are wired coherentlyThe eight new print‑time configuration fields (item name/cost toggle, width/height, font, font size, color, and serial/batch label toggle) are correctly added to
field_orderunderprinting_settingsand defined with sensible defaults and types. This lines up with how the new templates consumedoc.print_*values.If you later want the same level of styling control on Delivery Note and Stock Entry, you’ll need analogous fields on those DocTypes; right now they’ll just fall back to JsBarcode/CSS defaults via the templates.
Also applies to: 1315-1370, 1377-1377
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
erpnext/controllers/accounts_controller.py(1 hunks)erpnext/controllers/print_settings.py(1 hunks)erpnext/setup/install.py(1 hunks)erpnext/stock/doctype/purchase_receipt/purchase_receipt.json(2 hunks)erpnext/stock/doctype/purchase_receipt/purchase_receipt.py(1 hunks)erpnext/templates/print_formats/includes/batch_no_barcodes.html(1 hunks)erpnext/templates/print_formats/includes/serial_and_batch_no_barcodes.html(1 hunks)erpnext/templates/print_formats/includes/serial_no_barcodes.html(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
erpnext/controllers/accounts_controller.py (2)
erpnext/selling/page/point_of_sale/pos_payment.js (1)
docstatus(666-666)erpnext/public/js/controllers/transaction.js (1)
doctype(3123-3123)
🪛 Ruff (0.14.5)
erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
107-107: Undefined name Helvetica
(F821)
107-107: Undefined name Arial
(F821)
107-107: Undefined name sans
(F821)
107-107: Undefined name serif
(F821)
107-107: Undefined name Arial
(F821)
107-107: Undefined name sans
(F821)
107-107: Undefined name serif
(F821)
107-107: Undefined name Verdana
(F821)
107-107: Undefined name sans
(F821)
107-107: Undefined name serif
(F821)
107-107: Undefined name Tahoma
(F821)
107-107: Undefined name sans
(F821)
107-107: Undefined name serif
(F821)
107-107: Syntax error in forward annotation: Unexpected token at the end of an expression
(F722)
107-107: Undefined name "\"Times New Roman\", Times, serif"
(F821)
107-107: Undefined name "\"Times New Roman\", Times, serif"
(F821)
107-107: Undefined name "\"Roboto\", sans-serif"
(F821)
107-107: Undefined name "\"Roboto\", sans-serif"
(F821)
107-107: Undefined name "\"Roboto\", sans-serif"
(F821)
107-107: Undefined name "\"Lato\", sans-serif"
(F821)
107-107: Undefined name "\"Lato\", sans-serif"
(F821)
107-107: Undefined name "\"Lato\", sans-serif"
(F821)
107-107: Undefined name Consolas
(F821)
107-107: Undefined name Helvetica
(F821)
107-107: Undefined name Arial
(F821)
107-107: Undefined name sans
(F821)
107-107: Undefined name serif
(F821)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Summary
🔇 Additional comments (2)
erpnext/controllers/accounts_controller.py (1)
114-116: Barcode print settings only available post‑submit for selected doctypes
print_batch_no_barcodesandprint_serial_no_barcodesare surfaced in print settings only for submitted Purchase Receipts, Stock Entries, and Delivery Notes. This matches an “after submit” barcode workflow; just confirm you don’t need these options for draft prints as well, otherwise thedocstatus == 1guard should be relaxed.erpnext/stock/doctype/purchase_receipt/purchase_receipt.py (1)
106-113: The review comment's premise is incorrect; F722 is explicitly ignored by Ruff.The pyproject.toml configuration explicitly includes
"F722"in the ignore list with the comment "syntax error in forward type annotation". Ruff will not report errors on line 107'sDF.Literalannotation. The long literal with escaped quotes is valid Python syntax and is not flagged by the configured linter.Additionally, changing from
DF.Literal[...]toDF.Datawould sacrifice type specificity (the field becomes an unconstrained string) without fixing an actual linter error.Likely an incorrect or invalid review comment.
erpnext/templates/print_formats/includes/serial_and_batch_no_barcodes.html
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (2)
erpnext/templates/print_formats/includes/serial_and_batch_no_barcodes.html (2)
99-105: Add error handling for JsBarcode initialization.The JsBarcode library is loaded from a CDN and initialized without error handling. If the library fails to load or the initialization fails, barcodes won't render with no user feedback.
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/JsBarcode.all.min.js"></script> <script> document.addEventListener('DOMContentLoaded', function() { - JsBarcode('.batch_no').init(); - JsBarcode('.serial_no').init(); + if (typeof JsBarcode !== 'undefined') { + try { + JsBarcode('.batch_no').init(); + JsBarcode('.serial_no').init(); + } catch (error) { + console.error('JsBarcode initialization failed:', error); + } + } else { + console.warn('JsBarcode library failed to load'); + } }); </script>
99-99: Evaluate CDN reliability for offline/air-gapped deployments.The template depends on loading JsBarcode from
cdn.jsdelivr.net, which requires internet access. For deployments in offline environments or with restricted external access, barcode rendering will fail silently.Consider whether ERPNext deployments support offline scenarios, and if so, whether JsBarcode should be bundled as a static asset instead of loaded from a CDN. You may want to verify this with the deployment/operations team or check existing precedents in the codebase for how third-party client libraries are managed.
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
erpnext/templates/print_formats/includes/batch_no_barcodes.html(1 hunks)erpnext/templates/print_formats/includes/serial_and_batch_no_barcodes.html(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- erpnext/templates/print_formats/includes/batch_no_barcodes.html
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Summary
erpnext/templates/print_formats/includes/serial_and_batch_no_barcodes.html
Show resolved
Hide resolved
✅ Actions performedComments resolved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
erpnext/stock/doctype/delivery_note/delivery_note.json(2 hunks)erpnext/stock/doctype/delivery_note/delivery_note.py(1 hunks)erpnext/stock/doctype/stock_entry/stock_entry.json(3 hunks)erpnext/stock/doctype/stock_entry/stock_entry.py(1 hunks)
🧰 Additional context used
🪛 Ruff (0.14.5)
erpnext/stock/doctype/stock_entry/stock_entry.py
127-127: Undefined name Helvetica
(F821)
127-127: Undefined name Arial
(F821)
127-127: Undefined name sans
(F821)
127-127: Undefined name serif
(F821)
127-127: Undefined name Arial
(F821)
127-127: Undefined name sans
(F821)
127-127: Undefined name serif
(F821)
127-127: Undefined name Verdana
(F821)
127-127: Undefined name sans
(F821)
127-127: Undefined name serif
(F821)
127-127: Undefined name Tahoma
(F821)
127-127: Undefined name sans
(F821)
127-127: Undefined name serif
(F821)
127-127: Syntax error in forward annotation: Unexpected token at the end of an expression
(F722)
127-127: Undefined name "\"Times New Roman\", Times, serif"
(F821)
127-127: Undefined name "\"Times New Roman\", Times, serif"
(F821)
127-127: Undefined name "\"Roboto\", sans-serif"
(F821)
127-127: Undefined name "\"Roboto\", sans-serif"
(F821)
127-127: Undefined name "\"Roboto\", sans-serif"
(F821)
127-127: Undefined name "\"Lato\", sans-serif"
(F821)
127-127: Undefined name "\"Lato\", sans-serif"
(F821)
127-127: Undefined name "\"Lato\", sans-serif"
(F821)
127-127: Undefined name Consolas
(F821)
127-127: Undefined name Helvetica
(F821)
127-127: Undefined name Arial
(F821)
127-127: Undefined name sans
(F821)
127-127: Undefined name serif
(F821)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Summary
🔇 Additional comments (2)
erpnext/stock/doctype/stock_entry/stock_entry.json (1)
729-785: LGTM - Barcode printing fields are properly defined.All 8 barcode printing configuration fields are correctly defined with appropriate types, defaults, and properties. The JSON schema follows DocType field definition standards.
Minor observation:
print_item_cost_for_barcode(line 744-749) is markedread_only: 1in Stock Entry, but in Delivery Note it hasallow_on_submit: 1instead. This difference might be intentional based on business logic, but please verify consistency is intended across doctypes.erpnext/stock/doctype/delivery_note/delivery_note.json (1)
1461-1464: I'm encountering persistent repository access issues that prevent me from executing shell scripts to verify the field definition. Since I cannot access the repository to inspect the actualdelivery_note.jsonfile and confirm whether theoptionsproperty exists, I need to provide my assessment based on the available information.The
optionsproperty definition for theprint_font_for_barcodesSelect field cannot be verified due to repository access limitations.The original review comment correctly identifies that:
- The visible diff snippet shows a Select field without an
optionsproperty in the shown context- Select fields require
optionsto function properly- This could indicate a critical issue
However, the
optionsproperty may exist in the full file but simply not be visible in the diff context provided. Without access to the complete field definition or the ability to compare it with similar fields instock_entry.json, I cannot definitively confirm whether this is:
- A genuine missing
optionsproperty (critical issue)- An incomplete diff context (not an issue)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
erpnext/stock/doctype/delivery_note/delivery_note.json(2 hunks)erpnext/stock/doctype/delivery_note/delivery_note.py(1 hunks)
🧰 Additional context used
🪛 Ruff (0.14.5)
erpnext/stock/doctype/delivery_note/delivery_note.py
113-113: Undefined name Helvetica
(F821)
113-113: Undefined name Arial
(F821)
113-113: Undefined name sans
(F821)
113-113: Undefined name serif
(F821)
113-113: Undefined name Arial
(F821)
113-113: Undefined name sans
(F821)
113-113: Undefined name serif
(F821)
113-113: Undefined name Verdana
(F821)
113-113: Undefined name sans
(F821)
113-113: Undefined name serif
(F821)
113-113: Undefined name Tahoma
(F821)
113-113: Undefined name sans
(F821)
113-113: Undefined name serif
(F821)
113-113: Syntax error in forward annotation: Unexpected token at the end of an expression
(F722)
113-113: Undefined name "\"Times New Roman\", Times, serif"
(F821)
113-113: Undefined name "\"Times New Roman\", Times, serif"
(F821)
113-113: Undefined name "\"Roboto\", sans-serif"
(F821)
113-113: Undefined name "\"Roboto\", sans-serif"
(F821)
113-113: Undefined name "\"Roboto\", sans-serif"
(F821)
113-113: Undefined name "\"Lato\", sans-serif"
(F821)
113-113: Undefined name "\"Lato\", sans-serif"
(F821)
113-113: Undefined name "\"Lato\", sans-serif"
(F821)
113-113: Undefined name Consolas
(F821)
113-113: Undefined name Helvetica
(F821)
113-113: Undefined name Arial
(F821)
113-113: Undefined name sans
(F821)
113-113: Undefined name serif
(F821)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Summary
🔇 Additional comments (2)
erpnext/stock/doctype/delivery_note/delivery_note.py (2)
113-113: Static analysis false positives – annotation is correct.The Ruff errors flagging undefined names and syntax errors are false positives. The tool is misinterpreting the commas inside the string literals (which are CSS font-family values) as type argument separators. The
DF.Literalannotation with multiple quoted font-family strings is valid Python syntax and correctly matches the Select field options in the JSON schema.
112-119: LGTM!The type hints for the barcode configuration fields are correct and align with the JSON schema definitions. The nullable Color field, Literal for font options, Int fields for dimensions, and Check fields for boolean flags are all appropriately typed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
erpnext/stock/doctype/stock_entry/stock_entry.py (1)
126-133: Replace invalidDF.Literalforprint_font_for_barcodewith a simple string typeThe current
DF.Literal[...]forprint_font_for_barcodeis not valid Python (CSS font-family strings with embedded quotes/commas trigger Ruff F821/F722 and break annotation parsing). A Select field doesn’t need a Literal here; the JSON already constrains values.Consider simplifying the annotation:
- print_font_for_barcode: DF.Literal["Helvetica, Arial, sans-serif", "Arial, sans-serif", "Verdana, sans-serif", "Tahoma, sans-serif", "\"Times New Roman\", Times, serif", "\"Roboto\", sans-serif", "\"Lato\", sans-serif", "Consolas, Helvetica, Arial, sans-serif"] + print_font_for_barcode: DF.Data | NoneThis keeps type-checkers happy while still reflecting that the field is a string (or unset).
🧹 Nitpick comments (3)
erpnext/stock/doctype/delivery_note/delivery_note.json (1)
154-161: Barcode configuration fields for Delivery Note look consistentThe eight barcode-related fields are wired correctly (fieldnames match between
field_orderandfields, sensible defaults, and non‑negative constraints on numeric settings). Remaining polish like descriptions/units for height/width is optional.Also applies to: 1439-1498
erpnext/stock/doctype/delivery_note/delivery_note.py (1)
112-119: I'll verify the review comment by examining the actual code, checking for type annotation issues, and confirming the recommendation. Let me start by inspecting the file and understanding the context.
<function_calls>
<aml:invoke name="shell">
aml:command#!/bin/bashFirst, let's check if the file exists and view the lines in question
wc -l erpnext/stock/doctype/delivery_note/delivery_note.py
</function_calls>Let me read the relevant lines from the file:
<function_calls>
<aml:invoke name="shell">
aml:command#!/bin/bashRead lines 110-125 to see the context around the barcode fields
sed -n '110,125p' erpnext/stock/doctype/delivery_note/delivery_note.py
</function_calls>Now let me check the delivery_note.json file to understand what the Select field options are:
<function_calls>
#!/bin/bashFind and examine the delivery_note.json file
find . -name "delivery_note.json" -path "/delivery_note/" | head -1 | xargs cat | python3 -m json.tool | grep -A 30 "print_font_for_barcodes"
</function_calls>Let me also check the similar stock_entry.py to see if there's a parallel pattern:
<function_calls>
#!/bin/bashCheck stock_entry.py for similar font pattern
find . -name "stock_entry.py" -path "/stock_entry/" | head -1 | xargs cat | grep -n "print_font_for_barcodes" -A 1 -B 1
</function_calls>Let me understand what DF module is and check type annotation patterns:
<function_calls>
#!/bin/bashCheck what DF is imported as and its usage
head -50 erpnext/stock/doctype/delivery_note/delivery_note.py | grep -E "^import|^from"
</function_calls>Let me check if there are any ruff or type checking configurations:
<function_calls>
#!/bin/bashLook for ruff configuration and pyproject.toml
find . -maxdepth 2 -name "pyproject.toml" -o -name "ruff.toml" -o -name ".ruff.toml" | head -3
</function_calls>Let me check the DF type definitions to understand what DF.Data and DF.Literal are:
<function_calls>
#!/bin/bashSearch for DF type definitions in the codebase
rg "class Literal" --type python | head -5
rg "^DF\s*=" --type python | head -3
</function_calls>Let me search for how DF is typically used in type hints:
<function_calls>
#!/bin/bashLook for DF import and usage patterns
rg "from.*import.*DF" erpnext/stock/doctype/delivery_note/ | head -5
</function_calls>Let me get a broader view of the import at the top of delivery_note.py:
<function_calls>
#!/bin/bashShow first 20 lines to see imports
head -20 erpnext/stock/doctype/delivery_note/delivery_note.py
</function_calls>Now let me search for DF definitions in the frappe module:
<function_calls>
#!/bin/bashCheck if there's a frappe or docstatus module defining DF types
find . -path "frappe" -name "*.py" -type f | xargs grep -l "class Literal" | head -3
</function_calls>Let me check what the actual type annotation should be by looking at similar fields in the codebase:
<function_calls>
#!/bin/bashSearch for DF.Literal usage to understand how it's used
rg "DF.Literal[" --type python | head -10
</function_calls>Let me check how other Select fields with string options are typed:
<function_calls>
#!/bin/bashLook for pattern of Select fields with options
rg "DF.Literal[.Arial.]" --type python
</function_calls>Let me check the actual json schema to see the Select field definition:
<function_calls>
<command">#!/bin/bashFind and extract the print_font_for_barcodes field definition from JSON
fd "delivery_note.json" | head -1 | xargs cat | python3 << 'EOFPYTHON'
import json
import sys
data = json.load(sys.stdin)
for field in data.get('fields', []):
if field.get('fieldname') == 'print_font_for_barcodes':
print(json.dumps(field, indent=2))
break
EOFPYTHON
</function_calls>Let me try a different approach to find the JSON file:
<function_calls>
<command">#!/bin/bashLocate delivery_note.json
find . -name "delivery_note.json" 2>/dev/null | head -1
</function_calls>Now let me check the actual Python syntax validity of the DF.Literal line:
<function_calls>
<command">#!/bin/bashTry to parse the Python file to check for syntax errors
python3 -m py_compile erpnext/stock/doctype/delivery_note/delivery_note.py 2>&1
</function_calls>Let me check what Python version is being used and look at the actual syntax more carefully:
<function_calls>
<command">#!/bin/bashExtract the exact print_font_for_barcodes line
sed -n '113p' erpnext/stock/doctype/delivery_note/delivery_note.py
</function_calls>Let me look at a broader context to understand the pattern better:
<function_calls>
<command">#!/bin/bashView the entire type hints section for barcode fields
sed -n '100,150p' erpnext/stock/doctype/delivery_note/delivery_note.py
</function_calls>Let me check if DF.Literal is actually a typing construct or a Frappe-specific alias:
<function_calls>
<command">#!/bin/bashSearch for DF module definition
rg "^class DF\b|^DF\s*=|from.*DF\s|import.*DF\b" --type python | head -10
</function_calls>Let me check if there's a stub file (.pyi) defining DF:
<function_calls>
<command">#!/bin/bashLook for DF type stubs
find . -name "*.pyi" | xargs grep -l "Literal" 2>/dev/null | head -3
</function_calls>Let me search in the frappe module if it's installed or present:
<function_calls>
<command">#!/bin/bashCheck if frappe is imported and look at docstatus_pydantic or similar
find . -type d -name frappe | head -1
</function_calls>Let me try a different approach - checking what DF actually resolves to:
<function_calls>
<command">#!/bin/bashExtract imports and look for DF
sed -n '1,30p' erpnext/stock/doctype/delivery_note/delivery_note.py | cat -n
</function_calls>Let me use Python to analyze whether the Literal annotation is valid:
<function_calls>
<command">#!/bin/bashTest if the Literal syntax is valid
python3 << 'EOFPYTHON'
from typing import LiteralTry to evaluate the DF.Literal line to see if it's syntactically valid
test_literal = Literal["Helvetica, Arial, sans-serif", "Arial, sans-serif", "Verdana, sans-serif", "Tahoma, sans-serif", ""Times New Roman", Times, serif", ""Roboto", sans-serif", ""Lato", sans-serif", "Consolas, Helvetica, Arial, sans-serif"]
print("Literal annotation is syntactically valid")
print(f"Literal type: {test_literal}")
EOFPYTHON
</function_calls>Let me check for actual Ruff errors by looking at git or any lint output:
<function_calls>
<command">#!/bin/bashCheck if Ruff is available and run it on the file
which ruff && ruff check erpnext/stock/doctype/delivery_note/delivery_note.py --select F821,F722 2>&1 | head -20
</function_calls>Let me check what the DF module actually is in the context of this code:
<function_calls>
<command">#!/bin/bashFind where DF comes from in the imports or usage
python3 << 'EOFPYTHON'
import astwith open('erpnext/stock/doctype/delivery_note/delivery_note.py', 'r') as f:
tree = ast.parse(f.read())Find imports
for node in ast.walk(tree):
if isinstance(node, ast.ImportFrom):
if 'DF' in [alias.name for alias in node.names] or any(alias.asname == 'DF' for alias in node.names):
print(f"Found import: from {node.module} import ...")
for alias in node.names:
if alias.name == 'DF' or alias.asname == 'DF':
print(f" - {alias.name} {'as ' + alias.asname if alias.asname else ''}")
elif isinstance(node, ast.Import):
for alias in node.names:
if alias.name == 'DF' or alias.asname == 'DF':
print(f"Found import: import {alias.name}")
EOFPYTHON
</function_calls>Let me search more directly for the DF import:
<function_calls>
<command">#!/bin/bashGet all imports from delivery_note.py
head -50 erpnext/stock/doctype/delivery_note/delivery_note.py | grep -E "^from|^import"
</function_calls>Let me look at stock_entry.py to see if it has a similar pattern that was already flagged:
<function_calls>
<command">#!/bin/bashFind stock_entry.py and check for print_font_for_barcodes
find . -path "/stock_entry/" -name "stock_entry.py" | head -1 | xargs sed -n '1,150p' | grep -n "print_font"
</function_calls>Let me search for any existing discussion or issues about this pattern in the codebase:
<function_calls>
<command">#!/bin/bashCheck if there are other similar Literal definitions with complex strings
rg "DF.Literal[".,."" --type python | head -5
</function_calls>Let me check the actual file and understand the TYPE_CHECKING context:
<function_calls>
<command">#!/bin/bashLook for TYPE_CHECKING import
grep -n "TYPE_CHECKING" erpnext/stock/doctype/delivery_note/delivery_note.py
</function_calls>Let me examine the complete structure around the type hints:
<function_calls>
<command">#!/bin/bashGet broader context - lines 80-130
sed -n '80,130p' erpnext/stock/doctype/delivery_note/delivery_note.py | cat -n
</function_calls>Now let me search for how DF.Data is used in the codebase as an alternative:
<function_calls>
<command">#!/bin/bashLook for examples of DF.Data usage
rg "DF.Data" --type python | head -10
</function_calls>Let me check if there's any documentation about DF types:
<function_calls>
<command">#!/bin/bashSearch for documentation or comments about DF types
rg "DF.(Check|Data|Literal|Int|Color)" --type python -B1 | head -30
</function_calls>Let me look at the context of the class to understand if this is a Pydantic model or DocType:
<function_calls>
<command">#!/bin/bashFind class definition and its type annotations pattern
sed -n '1,200p' erpnext/stock/doctype/delivery_note/delivery_note.py | grep -n "^class|^if TYPE_CHECKING" -A 20 | head -40
</function_calls>Let me check if there's a frappe module in the repo or if it's external:
<function_calls>
<command">#!/bin/bashSearch for where frappe defines DF
find . -type f -name ".py" -path "frappe" | xargs grep -l "^DF\s=" 2>/dev/null | head -3
</function_calls>Let me get the actual import statement correctly:
<function_calls>
<command">#!/bin/bashUse python to extract and show imports
python3 << 'EOFPYTHON'
with open('erpnext/stock/doctype/delivery_note/delivery_note.py', 'r') as f:
lines = f.readlines()
for i, line in enumerate(lines[:60], 1):
if 'import' in line.lower() or 'from' in line.lower():
print(f"{i}: {line.rstrip()}")
EOFPYTHON
</function_calls>Let me take a more direct approach and look at the actual file content systematically:
<function_calls>
<command">#!/bin/bashSimply cat the first 100 lines to see the imports clearly
head -100 erpnext/stock/doctype/delivery_note/delivery_note.py
</function_calls>Perfect! Now I can see the context. Let me verify the claim about DF.Literal being malformed by checking how DF types are actually used:
<function_calls>
<command">#!/bin/bashCheck if there are similar Literal patterns elsewhere that work
rg "DF.Literal[" erpnext/stock/doctype/ --type python | head -20
</function_calls>Now let me verify whether the JSON schema confirms the Select field options:
<function_calls>
<command">#!/bin/bashFind and examine the delivery_note.json file
fd "delivery_note.json$" --path "delivery_note" | head -1
</function_calls><function_calls>
<command">#!/bin/bashExtract the print_font_for_barcodes field from JSON
find . -name "delivery_note.json" 2>/dev/null | head -1 | xargs python3 << 'EOFPYTHON'
import json
import sysdata = json.load(sys.stdin)
for field in data.get('fields', []):
if field.get('fieldname') == 'print_font_for_barcodes':
print("Found field: print_font_for_barcodes")
print(json.dumps(field, indent=2))
break
else:
print("Field not found")
EOFPYTHON
</function_calls>Let me check the actual type checking behavior by looking for test files or type checking configuration:
<function_calls>
<command">#!/bin/bashCheck for pyproject.toml or setup.cfg with mypy/ruff config
find . -maxdepth 3 ( -name "pyproject.toml" -o -name "setup.cfg" ) -exec grep -l "mypy|ruff|tool.mypy" {} ; 2>/dev/null | head -2
</function_calls>Let me verify the original claim about Stock Entry to understand the pattern better:
<function_calls>
<command">#!/bin/bashFind and check stock_entry.py for the same pattern
find . -path "/stock_entry/" -name "stock_entry.py" 2>/dev/null | head -1 | xargs grep -n "print_font_for_barcodes"
</function_calls>Let me check the alternative type annotation (DF.Data) to see if it's used:
<function_calls>
<command">#!/bin/bashSearch for DF.Data usage
rg ":\s*DF.Data" --type python | head -10
</function_calls>Let me verify if the actual recommendation (DF.Data | None) is actually used elsewhere:
<function_calls>
<command">#!/bin/bashLook for union type patterns with DF
rg "DF.\w+\s*|\s*(None|str|int)" --type python | head -20
</function_calls>Let me check what DF actually exports by looking at import patterns:
<function_calls>
<command">#!/bin/bashSee all DF type usages in the delivery_note.py file
grep "DF." erpnext/stock/doctype/delivery_note/delivery_note.py | head -20
</function_calls>Based on my investigation, let me create a comprehensive verification script to understand the actual issue:
<function_calls>
<command">#!/bin/bashComprehensive analysis of the Literal annotation issue
python3 << 'EOFPYTHON'
import re
import jsonRead the delivery_note.py file
with open('erpnext/stock/doctype/delivery_note/delivery_note.py', 'r') as f:
content = f.read()
lines = content.split('\n')Find line 113 (0-indexed, so 112)
if len(lines) > 112:
line_113 = lines[112]
print("Line 113:", line_113[:100] + "..." if len(line_113) > 100 else line_113)# Check if it contains DF.Literal if 'DF.Literal' in line_113: print("\nFound DF.Literal in line 113") # Extract the full Literal content start_idx = content.find('print_font_for_barcodes: DF.Literal[') if start_idx != -1: end_idx = content.find(']', start_idx) + 1 literal_part = content[start_idx:end_idx] print(f"\nFull annotation: {literal_part[:150]}...") # Count the strings strings = re.findall(r'"[^"]*"', literal_part) print(f"\nNumber of string values: {len(strings)}") for s in strings: print(f" - {s}")Now check delivery_note.json for the field
import os
json_path = 'erpnext/stock/doctype/delivery_note/delivery_note.json'
if os.path.exists(json_path):
with open(json_path, 'r') as f:
data = json.load(f)
for field in data.get('fields', []):
if field.get('fieldname') == 'print_font_for_barcodes':
print("\n\nFound field in JSON:")
print(f" Type: {field.get('fieldtype')}")
print(f" Options: {field.get('options', 'N/A')[:200]}...")
break
EOFPYTHON
</function_calls>Excellent! Now I have concrete information. Let me verify the actual type definition of DF by searching for its module:
<function_calls>
<command">#!/bin/bashSearch for DF type definitions in frappe modules if available
find . -type f -name ".py" -o -name ".pyi" | xargs grep -l "class Literal" 2>/dev/null | head -5
</function_calls>Let me check if this is related to Frappe's docstatus_pydantic or a similar module:
<function_calls>
<command">#!/bin/bashSearch for module that might define DF
find . -type f -name "*.py" | xargs grep "^from.*import.*DF|^import.*DF" | grep -v "erpnext/stock" | head -10
</function_calls>Let me look directly at a frappe-related import to understand the DF source:
<function_calls>
<command">#!/bin/bashCheck what frappe.types exports
find . -path "/frappe/types" -name "*.py" 2>/dev/null | head -5
</function_calls>Let me verify the Python syntax validity of the actual line more rigorously:
<function_calls>
shell
aml:command#!/bin/bashTest if Python can parse the file without errors
python3 -m py_compile erpnext/stock/doctype/delivery_note/delivery_note.py && echo "✓ File compiles successfully" || echo "✗ Compilation error"
</function_calls>Now let me verify whether Ruff would actually report errors on this code by checking if ruff is available and what it reports:
<function_calls>
<command">#!/bin/bashCheck if ruff is available and run it on the specific file
if command -v ruff &> /dev/null; then
echo "Ruff is available. Running checks..."
ruff check erpnext/stock/doctype/delivery_note/delivery_note.py --select F821,F722,E999 2>&1 | grep -E "delivery_note.py:|F821|F722|E999" || echo "No F821/F722/E999 errors found"
else
echo "Ruff not available in sandbox"
fi
</function_calls>Let me check if there's any mypy configuration that might flag this as an issue:
<function_calls>
<command">#!/bin/bashLook for mypy or type checking configuration
find . -maxdepth 2 -name "mypy.ini" -o -name "py.typed" 2>/dev/null
</function_calls>Let me verify whether the suggestion to use DF.Data | None is actually valid by checking what DF.Data represents:
<function_calls>
<command">#!/bin/bashCheck how other simple string fields are typed
grep -n "DF.(Data|String)" erpnext/stock/doctype/delivery_note/delivery_note.py | head -10
</function_calls>Now let me create a summary check of all the claims in the review comment:
<function_calls>
<command">#!/bin/bashFinal verification script
python3 << 'EOFPYTHON'
import re
import json
import osprint("=" * 60)
print("VERIFICATION CHECKLIST FOR REVIEW COMMENT")
print("=" * 60)1. Check line 113 exists and contains DF.Literal
print("\n1. Line 113 contains DF.Literal:")
with open('erpnext/stock/doctype/delivery_note/delivery_note.py', 'r') as f:
lines = f.readlines()
if len(lines) > 112:
line_113 = lines[112].strip()
has_literal = 'DF.Literal' in line_113
print(f" ✓ Found: {has_literal}")
if has_literal:
print(f" Content: {line_113[:80]}...")2. Check if it's a font-family Select field
print("\n2. Field contains font-family CSS strings:")
if 'Helvetica' in line_113 and 'Arial' in line_113:
print(f" ✓ Yes - contains Helvetica, Arial, and other font family strings")3. Check if strings contain embedded quotes and commas
print("\n3. Strings contain embedded quotes and commas:")
if 'Times New Roman' in line_113 and ', ' in line_113:
print(f" ✓ Yes - found 'Times New Roman' and commas in values")4. Check Python compilation
print("\n4. Python file compiles without syntax errors:")
try:
compile(open('erpnext/stock/doctype/delivery_note/delivery_note.py').read(), 'delivery_note.py', 'exec')
print(f" ✓ Yes - no syntax errors")
except SyntaxError as e:
print(f" ✗ No - {e}")5. Check delivery_note.json for Select field options
print("\n5. delivery_note.json has Select options for print_font_for_barcodes:")
json_path = 'erpnext/stock/doctype/delivery_note/delivery_note.json'
if os.path.exists(json_path):
with open(json_path, 'r') as f:
data = json.load(f)
for field in data.get('fields', []):
if field.get('fieldname') == 'print_font_for_barcodes':
ftype = field.get('fieldtype')
options = field.get('options', '')
print(f" ✓ Yes - Field type: {ftype}")
if options:
print(f" Options (first 100 chars): {options[:100]}...")
break
else:
print(f" ? JSON file not found")6. Check if this is similar to stock_entry.py
print("\n6. Similar pattern exists in stock_entry.py:")
stock_entry_path = 'erpnext/stock/doctype/stock_entry/stock_entry.py'
if os.path.exists(stock_entry_path):
with open(stock_entry_path, 'r') as f:
content = f.read()
if 'print_font_for_barcodes' in content and 'DF.Literal' in content:
print(f" ✓ Yes - similar pattern found")
else:
print(f" ✗ No - pattern not found")
else:
print(f" ? File not found")print("\n" + "=" * 60)
EOFPYTHON
</function_calls>Perfect! Now let me check if the recommendation (DF.Data | None) is actually used and valid elsewhere:
<function_calls>
<command">#!/bin/bashCheck existing usage of DF.Data and union types
echo "=== Checking DF.Data usage ==="
grep -n ":\s*DF.Data" erpnext/stock/doctype/delivery_note/delivery_note.py | head -5echo -e "\n=== Checking union type patterns ==="
grep -n "DF.\w+\s*|\s*None" erpnext/stock/doctype/delivery_note/delivery_note.py | head -5echo -e "\n=== Checking what types are used for string fields ==="
grep -n ":\s*DF.(Data|String|Literal)" erpnext/stock/doctype/delivery_note/delivery_note.py | head -10
</function_calls>Let me check the imports again to understand the DF module better:
<function_calls>
<command">#!/bin/bashGet a clear picture of what DF is
sed -n '1,30p' erpnext/stock/doctype/delivery_note/delivery_note.py | cat -n | grep -E "^.*from|^.*import"
</function_calls>Now let me verify the exact file location and format one more time:
<function_calls>
<command">#!/bin/bashGet exact context - lines 110-120 with line numbers
sed -n '110,120p' erpnext/stock/doctype/delivery_note/delivery_note.py | cat -n | sed 's/^[[:space:]]([0-9])/Line \1:/g'
</function_calls>Perfect! Now I have all the information I need to complete the verification. Let me create my final analysis:
Based on my verification, I need to rewrite the review comment with corrected information.
Simplify
print_font_for_barcodestype annotation: DF.Data is more appropriate than DF.LiteralThe
DF.Literal[...]annotation forprint_font_for_barcodesis syntactically valid, but unnecessary and unconventional. Since the Select field indelivery_note.jsonalready constrains the allowed values, usingDF.Data | None(as used for other simple string fields in this file) would be clearer:- print_font_for_barcodes: DF.Literal["Helvetica, Arial, sans-serif", "Arial, sans-serif", "Verdana, sans-serif", "Tahoma, sans-serif", "\"Times New Roman\", Times, serif", "\"Roboto\", sans-serif", "\"Lato\", sans-serif", "Consolas, Helvetica, Arial, sans-serif"] + print_font_for_barcodes: DF.Data | NoneThis removes unnecessary type verbosity while maintaining the runtime behavior and leveraging the JSON schema's Select constraint.
erpnext/stock/doctype/stock_entry/stock_entry.json (1)
79-86: Barcode print settings for Stock Entry look consistent; clarify intent for cost checkbox.The new barcode-printing fields under
printing_settingsare wired cleanly:
field_orderadditions (Lines 79‑86) match the new field definitions (Lines 728‑788).- Defaults and
allow_on_submitflags on the font, size, height, width, and color fields make sense and align with the PythonDF.Literal/ type hints for tooling.- This keeps Stock Entry in step with the Purchase Receipt / Delivery Note barcode configuration story.
One minor point to confirm:
print_item_cost_for_barcodeisread_only: 1with default"0". That effectively disables users from enabling cost in the UI (even pre‑submit), unless something else sets it programmatically. If the intent is to keep item cost out of printed barcodes by default but still let admins opt‑in through the standard form, consider droppingread_only(or replacing it with a role-baseddepends_on/ permission pattern) so it behaves like the other two checkboxes.Otherwise, the schema changes themselves look good.
Also applies to: 728-788, 796-796
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
erpnext/stock/doctype/delivery_note/delivery_note.json(2 hunks)erpnext/stock/doctype/delivery_note/delivery_note.py(1 hunks)erpnext/stock/doctype/purchase_receipt/purchase_receipt.json(2 hunks)erpnext/stock/doctype/purchase_receipt/purchase_receipt.py(1 hunks)erpnext/stock/doctype/stock_entry/stock_entry.json(3 hunks)erpnext/stock/doctype/stock_entry/stock_entry.py(1 hunks)
🧰 Additional context used
🪛 Ruff (0.14.5)
erpnext/stock/doctype/stock_entry/stock_entry.py
127-127: Undefined name Helvetica
(F821)
127-127: Undefined name Arial
(F821)
127-127: Undefined name sans
(F821)
127-127: Undefined name serif
(F821)
127-127: Undefined name Arial
(F821)
127-127: Undefined name sans
(F821)
127-127: Undefined name serif
(F821)
127-127: Undefined name Verdana
(F821)
127-127: Undefined name sans
(F821)
127-127: Undefined name serif
(F821)
127-127: Undefined name Tahoma
(F821)
127-127: Undefined name sans
(F821)
127-127: Undefined name serif
(F821)
127-127: Syntax error in forward annotation: Unexpected token at the end of an expression
(F722)
127-127: Undefined name "\"Times New Roman\", Times, serif"
(F821)
127-127: Undefined name "\"Times New Roman\", Times, serif"
(F821)
127-127: Undefined name "\"Roboto\", sans-serif"
(F821)
127-127: Undefined name "\"Roboto\", sans-serif"
(F821)
127-127: Undefined name "\"Roboto\", sans-serif"
(F821)
127-127: Undefined name "\"Lato\", sans-serif"
(F821)
127-127: Undefined name "\"Lato\", sans-serif"
(F821)
127-127: Undefined name "\"Lato\", sans-serif"
(F821)
127-127: Undefined name Consolas
(F821)
127-127: Undefined name Helvetica
(F821)
127-127: Undefined name Arial
(F821)
127-127: Undefined name sans
(F821)
127-127: Undefined name serif
(F821)
erpnext/stock/doctype/delivery_note/delivery_note.py
113-113: Undefined name Helvetica
(F821)
113-113: Undefined name Arial
(F821)
113-113: Undefined name sans
(F821)
113-113: Undefined name serif
(F821)
113-113: Undefined name Arial
(F821)
113-113: Undefined name sans
(F821)
113-113: Undefined name serif
(F821)
113-113: Undefined name Verdana
(F821)
113-113: Undefined name sans
(F821)
113-113: Undefined name serif
(F821)
113-113: Undefined name Tahoma
(F821)
113-113: Undefined name sans
(F821)
113-113: Undefined name serif
(F821)
113-113: Syntax error in forward annotation: Unexpected token at the end of an expression
(F722)
113-113: Undefined name "\"Times New Roman\", Times, serif"
(F821)
113-113: Undefined name "\"Times New Roman\", Times, serif"
(F821)
113-113: Undefined name "\"Roboto\", sans-serif"
(F821)
113-113: Undefined name "\"Roboto\", sans-serif"
(F821)
113-113: Undefined name "\"Roboto\", sans-serif"
(F821)
113-113: Undefined name "\"Lato\", sans-serif"
(F821)
113-113: Undefined name "\"Lato\", sans-serif"
(F821)
113-113: Undefined name "\"Lato\", sans-serif"
(F821)
113-113: Undefined name Consolas
(F821)
113-113: Undefined name Helvetica
(F821)
113-113: Undefined name Arial
(F821)
113-113: Undefined name sans
(F821)
113-113: Undefined name serif
(F821)
erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
107-107: Undefined name Helvetica
(F821)
107-107: Undefined name Arial
(F821)
107-107: Undefined name sans
(F821)
107-107: Undefined name serif
(F821)
107-107: Undefined name Arial
(F821)
107-107: Undefined name sans
(F821)
107-107: Undefined name serif
(F821)
107-107: Undefined name Verdana
(F821)
107-107: Undefined name sans
(F821)
107-107: Undefined name serif
(F821)
107-107: Undefined name Tahoma
(F821)
107-107: Undefined name sans
(F821)
107-107: Undefined name serif
(F821)
107-107: Syntax error in forward annotation: Unexpected token at the end of an expression
(F722)
107-107: Undefined name "\"Times New Roman\", Times, serif"
(F821)
107-107: Undefined name "\"Times New Roman\", Times, serif"
(F821)
107-107: Undefined name "\"Roboto\", sans-serif"
(F821)
107-107: Undefined name "\"Roboto\", sans-serif"
(F821)
107-107: Undefined name "\"Roboto\", sans-serif"
(F821)
107-107: Undefined name "\"Lato\", sans-serif"
(F821)
107-107: Undefined name "\"Lato\", sans-serif"
(F821)
107-107: Undefined name "\"Lato\", sans-serif"
(F821)
107-107: Undefined name Consolas
(F821)
107-107: Undefined name Helvetica
(F821)
107-107: Undefined name Arial
(F821)
107-107: Undefined name sans
(F821)
107-107: Undefined name serif
(F821)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Summary
🔇 Additional comments (2)
erpnext/stock/doctype/purchase_receipt/purchase_receipt.json (1)
140-147: I'm unable to verify the fieldname mismatch claim due to persistent repository cloning failures. Without direct access to thepurchase_receipt.jsonfile andpurchase_receipt.pyfile, I cannot confirm whether the alleged mismatch betweenprint_font_for_barcodeandprint_font_for_barcodesactually exists in the codebase.Field name mismatch between field_order and field definitions requires manual verification
The original review claims that
field_orderreferencesprint_font_for_barcodewhile the field definition usesprint_font_for_barcodes(with trailing "s"). This should be verified by:
- Checking lines 140–147 in
erpnext/stock/doctype/purchase_receipt/purchase_receipt.jsonto confirm the exact fieldname infield_order- Checking lines 1315–1373 in the same file to confirm the actual field definition name
- Verifying that the Python type hints in
erpnext/stock/doctype/purchase_receipt/purchase_receipt.pyuse consistent namingIf a mismatch is confirmed, it should be standardized across all three locations.
erpnext/stock/doctype/purchase_receipt/purchase_receipt.py (1)
106-113: I attempted to verify the claims in this review comment by examining the actual codebase, but encountered a repository cloning failure that prevents local inspection of:
- The exact syntax of line 107 in
purchase_receipt.py- Whether Ruff actually reports F821/F722 errors on that line
- The generator code responsible for creating TYPE_CHECKING blocks
- The DocType JSON definition to confirm option matching
The review comment's technical reasoning is sound: if
DF.Literal[...]contains bare identifiers instead of quoted strings (e.g.,Helvetica, Arialinstead of"Helvetica, Arial"), Ruff would correctly flag them as undefined names (F821). However, without accessing the actual file to confirm the current syntax and verify the lint errors exist, I cannot validate whether the proposed fix is necessary or correct.Rewrite of review comment after verification:
Fix
print_font_for_barcodeLiteral to use proper string literals per lint requirements. TheDF.Literal[...]on line 107 should ensure all font-family options are proper string literals to avoid Ruff F821/F722 lint errors and maintain type-checking integrity. Suggested format:print_font_for_barcode: DF.Literal[ "Helvetica, Arial, sans-serif", "Arial, sans-serif", "Verdana, sans-serif", "Tahoma, sans-serif", '"Times New Roman", Times, serif', '"Roboto", sans-serif', '"Lato", sans-serif', "Consolas, Helvetica, Arial, sans-serif", ]Since this block is auto-generated, verify that the generator is updated to produce correctly quoted Literal definitions across all doctypes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
erpnext/stock/doctype/delivery_note/delivery_note.json (1)
154-161: Barcode fields are wired correctly; consider hiding them on printThe new barcode configuration fields are correctly added to
field_orderand defined with sensible defaults/options, and they line up with the Python type hints and templates.To avoid these internal settings showing up on generic/auto‑generated print formats, it’s worth marking them as hidden on print:
print_serial_or_batch_number_for_barcodeprint_item_name_for_barcodeprint_item_cost_for_barcodeprint_font_for_barcodeprint_font_size_for_barcodeprint_height_for_barcodeprint_width_for_barcodeprint_barcode_colorFor example:
{ "allow_on_submit": 1, "default": "1", "fieldname": "print_serial_or_batch_number_for_barcode", "fieldtype": "Check", - "label": "Print serial or batch number for barcode" + "label": "Print serial or batch number for barcode", + "print_hide": 1 }, { "allow_on_submit": 1, "default": "0", "fieldname": "print_item_name_for_barcode", "fieldtype": "Check", - "label": "Print item name for barcode" + "label": "Print item name for barcode", + "print_hide": 1 }, { "allow_on_submit": 1, "default": "0", "fieldname": "print_item_cost_for_barcode", "fieldtype": "Check", - "label": "Print item cost for barcode" + "label": "Print item cost for barcode", + "print_hide": 1 }, { "allow_on_submit": 1, "default": "Helvetica", "fieldname": "print_font_for_barcode", "fieldtype": "Select", "label": "Print font for barcode", - "options": "Helvetica\nArial\nVerdana\nsans-serif\nTahoma\nTimes\nConsolas" + "options": "Helvetica\nArial\nVerdana\nsans-serif\nTahoma\nTimes\nConsolas", + "print_hide": 1 }, { "allow_on_submit": 1, "default": "12", "fieldname": "print_font_size_for_barcode", "fieldtype": "Int", "label": "Print font size for barcode", - "non_negative": 1 + "non_negative": 1, + "print_hide": 1 }, { "allow_on_submit": 1, "default": "40", "fieldname": "print_height_for_barcode", "fieldtype": "Int", "label": "Print height for barcode", - "non_negative": 1 + "non_negative": 1, + "print_hide": 1 }, { "allow_on_submit": 1, "default": "2", "fieldname": "print_width_for_barcode", "fieldtype": "Int", "label": "Print width for barcode", - "non_negative": 1 + "non_negative": 1, + "print_hide": 1 }, { "allow_on_submit": 1, "default": "#000000", "fieldname": "print_barcode_color", "fieldtype": "Color", - "label": "Print color for barcode" + "label": "Print color for barcode", + "print_hide": 1 }Also applies to: 1439-1498
erpnext/stock/doctype/purchase_receipt/purchase_receipt.json (1)
140-147: Purchase Receipt barcode fields are correct; small JSON cleanups suggestedThe eight new barcode fields are correctly added to
field_orderunder “Printing Settings” and their definitions (checks, select, ints withnon_negative, color) match how they’re used in templates and type hints.Two small polish items:
- Hide config fields on printouts (same rationale as Delivery Note) to avoid these internal settings appearing in auto‑generated formats:
{ "allow_on_submit": 1, "default": "0", "fieldname": "print_item_name_for_barcode", "fieldtype": "Check", - "label": "Print item name for barcode" + "label": "Print item name for barcode", + "print_hide": 1 }, { "allow_on_submit": 1, "default": "0", "fieldname": "print_item_cost_for_barcode", "fieldtype": "Check", - "label": "Print item cost for barcode" + "label": "Print item cost for barcode", + "print_hide": 1 }, { "allow_on_submit": 1, "default": "2", "fieldname": "print_width_for_barcode", "fieldtype": "Int", - "label": "Print width for barcode", - "non_negative": 1 + "label": "Print width for barcode", + "non_negative": 1, + "print_hide": 1 }, { "allow_on_submit": 1, "default": "40", "fieldname": "print_height_for_barcode", "fieldtype": "Int", - "label": "Print height for barcode", - "non_negative": 1 + "label": "Print height for barcode", + "non_negative": 1, + "print_hide": 1 }, { "allow_on_submit": 1, "default": "Helvetica", "fieldname": "print_font_for_barcode", "fieldtype": "Select", "label": "Print font for barcode", - "options": "Helvetica\nArial\nVerdana\nsans-serif\nTahoma\nTimes\nConsolas" + "options": "Helvetica\nArial\nVerdana\nsans-serif\nTahoma\nTimes\nConsolas", + "print_hide": 1 }, { "allow_on_submit": 1, "default": "1", "fieldname": "print_serial_or_batch_number_for_barcode", "fieldtype": "Check", - "label": "Print serial or batch number for barcode" + "label": "Print serial or batch number for barcode", + "print_hide": 1 }, { "allow_on_submit": 1, "default": "#000000", "fieldname": "print_barcode_color", "fieldtype": "Color", - "label": "Print color for barcode" + "label": "Print color for barcode", + "print_hide": 1 }, { "allow_on_submit": 1, "default": "12", "fieldname": "print_font_size_for_barcode", "fieldtype": "Int", - "label": "Print font size for barcode", - "non_negative": 1, - "options": "Helvetica" + "label": "Print font size for barcode", + "non_negative": 1, + "print_hide": 1 }
- Drop the stray
optionsonprint_font_size_for_barcodeFor an
Intfield theoptionsvalue ("Helvetica") is unused and could confuse future readers; the diff above removes it.Also applies to: 1313-1374, 1381-1382
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
erpnext/stock/doctype/delivery_note/delivery_note.json(2 hunks)erpnext/stock/doctype/delivery_note/delivery_note.py(1 hunks)erpnext/stock/doctype/purchase_receipt/purchase_receipt.json(2 hunks)erpnext/stock/doctype/purchase_receipt/purchase_receipt.py(1 hunks)erpnext/stock/doctype/stock_entry/stock_entry.json(3 hunks)erpnext/stock/doctype/stock_entry/stock_entry.py(1 hunks)erpnext/templates/print_formats/includes/batch_no_barcodes.html(1 hunks)erpnext/templates/print_formats/includes/serial_and_batch_no_barcodes.html(1 hunks)erpnext/templates/print_formats/includes/serial_no_barcodes.html(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- erpnext/templates/print_formats/includes/serial_and_batch_no_barcodes.html
- erpnext/templates/print_formats/includes/serial_no_barcodes.html
- erpnext/templates/print_formats/includes/batch_no_barcodes.html
🧰 Additional context used
🪛 Ruff (0.14.5)
erpnext/stock/doctype/stock_entry/stock_entry.py
127-127: Undefined name Helvetica
(F821)
127-127: Undefined name Arial
(F821)
127-127: Undefined name Verdana
(F821)
127-127: Undefined name sans
(F821)
127-127: Undefined name serif
(F821)
127-127: Undefined name Tahoma
(F821)
127-127: Undefined name Times
(F821)
127-127: Undefined name Consolas
(F821)
erpnext/stock/doctype/delivery_note/delivery_note.py
113-113: Undefined name Helvetica
(F821)
113-113: Undefined name Arial
(F821)
113-113: Undefined name Verdana
(F821)
113-113: Undefined name sans
(F821)
113-113: Undefined name serif
(F821)
113-113: Undefined name Tahoma
(F821)
113-113: Undefined name Times
(F821)
113-113: Undefined name Consolas
(F821)
erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
107-107: Undefined name Helvetica
(F821)
107-107: Undefined name Arial
(F821)
107-107: Undefined name Verdana
(F821)
107-107: Undefined name sans
(F821)
107-107: Undefined name serif
(F821)
107-107: Undefined name Tahoma
(F821)
107-107: Undefined name Times
(F821)
107-107: Undefined name Consolas
(F821)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Summary
🔇 Additional comments (6)
erpnext/stock/doctype/stock_entry/stock_entry.json (3)
79-86: Field ordering for barcode configuration looks good.The eight new barcode-related fields are correctly added to
field_orderunder theprinting_settingssection, following existing entries. The logical sequence (serial/batch, item name, cost, font, font size, dimensions, color) makes sense for UI presentation.
729-788: Field definitions are well-structured; verify backend handling of read-only cost field.The barcode configuration fields are properly defined with:
- Appropriate field types (Check, Select, Int, Color)
- Sensible defaults (serial/batch enabled, item name/cost disabled, font size 12, height 40, width 2, black color)
non_negative: 1constraint on numeric fields to prevent invalid valuesallow_on_submit: 1consistently applied to editable fields onlyHowever,
print_item_cost_for_barcode(line 744–748) is marked read-only with no allow_on_submit. Verify that backend code properly controls this field and confirm the read-only behavior is intentional.
729-788: I'm unable to verify this claim due to repository access limitations. Both direct repository cloning and alternative verification methods have failed.Manual verification still required for barcode field consistency across doctypes.
The provided snippet confirms eight barcode-related fields are present in stock_entry.json (lines 729-788). However, I cannot verify that identical field definitions exist in purchase_receipt.json and delivery_note.json without direct access to those files.
Please execute the provided verification script locally or manually inspect the three doctype JSON files to confirm:
- All eight barcode fields are present in each doctype
- Field properties (fieldtype, defaults, options, allow_on_submit, read_only, etc.) match exactly across all three doctypes
erpnext/stock/doctype/stock_entry/stock_entry.py (1)
126-133: Barcode print config type hints look consistent and safeThe new DF attributes for barcode color, font, dimensions, and flags are well‑typed, align with the DocType JSON schema and mirror the pattern used on other stock doctypes. No runtime behavior change and type‑checking should be straightforward.
erpnext/stock/doctype/purchase_receipt/purchase_receipt.py (1)
106-113: Purchase Receipt barcode type hints are consistent with schemaThe added barcode‑related DF fields (color, font, font size, dimensions, and display flags) match the JSON field names and options and keep behavior unchanged while improving type‑checking.
erpnext/stock/doctype/delivery_note/delivery_note.py (1)
112-119: Delivery Note barcode type hints align with DocType JSONThe added barcode‑related DF fields on
DeliveryNote(color, font, sizes, and display flags) line up with the Delivery Note DocType JSON and with the same pattern used on Purchase Receipt and Stock Entry. Looks good.
feat: add support for printing batch and serial number barcodes with customization
This PR adds support for printing barcodes for serial and batch numbers, solving the problem where users previously could not print barcodes without creating their own extensions. Print options are added for the following DocTypes:
Other DocTypes, such as Purchase Invoice, are not supported yet, since serial and batch numbers are not tracked in them.
Barcodes are generated using the JsBarcode library. In the Print Format Selector, the barcodes appear empty because Jinja generates placeholders and JsBarcode renders them client-side, but they display correctly in full-page preview and when printing.
Checklist
Showcase
Closes: #50146