Custom Button function not working

I have two Doctypes named Log_Test and Log_Schedule which have two separate child tables each
Log_Test_Machines, Log_Test_Readings and Log_Schedule_Machines, Log_Schedule_Readings

I have created a template in Log_Test doctype in which i have put the data of different fields in both of its child tables
machine_group, unit_measure, unit, min_max
unit_measure, unit, min_max

min_max is a data field and all other are link fields i have put the data in the Log_Test_Machines and Log_Test_Readings

i have created a custom button in Log_Test Create Schedule which will create a new log_schedule with details of its child tables and its fields

Custom Button Code :-

frappe.ui.form.on(‘Log_Test’, {
refresh: function(frm) {
frm.add_custom_button(__(“Create Schedule”), function() {
frm.events.make_log_schedule(frm);
}, __(‘Create’));
},
make_log_schedule: function(frm) {
frappe.model.open_mapped_doc({
method: “workwings.plcm.doctype.log_schedule.make_log_schedule”,
frm: frm,
run_link_triggers: true
});
}
});

Code to create new Log_Schedule document :-
import json
import frappe
from frappe import _, msgprint
from frappe.model.mapper import get_mapped_doc
from frappe.query_builder.functions import Sum
from frappe.utils import cint, cstr, flt, get_link_to_form, getdate, new_line_sep, nowdate
from frappe.model.document import Document

class Log_Test(Document):
@frappe.whitelist()
def make_log_schedule(source_name, target_doc=None):
“”“Creates a new Log_Schedule document based on a Log_Test document and its child tables.”“”

    log_test = frappe.get_doc("Log_Test", source_name)

    # Create the new Log_Schedule document
    log_schedule = frappe.new_doc("Log_Schedule")

    # Copy relevant fields from Log_Test to Log_Schedule 
    log_schedule.update({
        "machine_related_readings": log_test.machine_related_readings,
        "other_measurable_readings": log_test.other_measurable_readings,
    })

    # Create child table entries for Log_Schedule_Machines 
    for machine in log_test.get("log_test_machines"):
        new_machine = frappe.new_doc("Log_Schedule_Machines")
        new_machine.log_test = log_schedule.name
        new_machine.machine_group = machine.machine_group
        new_machine.unit_measure = machine.unit_measure  
        new_machine.unit = machine.unit
        new_machine.min_max = machine.min_max
        new_machine.save()
        log_schedule.append("log_schedule_machines", new_machine)

    # Create child table entries for Log_Schedule_Readings 
    for reading in log_test.get("log_test_readings"):
        new_reading = frappe.new_doc("Log_Schedule_Readings")
        new_reading.log_test = log_schedule.name
        new_reading.unit_measure = reading.unit_measure
        new_reading.unit = reading.unit
        new_reading.min_max = reading.min_max
        new_reading.save()
        log_schedule.append("log_schedule_readings", new_reading)

    # Save the new Log_Schedule document
    log_schedule.save()
    return log_schedule

I am getting this error when clicking create schedule button :-

App Versions

{
	"frappe": "15.15.0",
	"workwings": "0.0.1"
}

Route

Form/Log_Test/RIPL-PP-AFBC-2024-00046

Traceback

Traceback (most recent call last):
  File "apps/frappe/frappe/app.py", line 110, in application
    response = frappe.api.handle(request)
  File "apps/frappe/frappe/api/__init__.py", line 49, in handle
    data = endpoint(**arguments)
  File "apps/frappe/frappe/api/v1.py", line 36, in handle_rpc_call
    return frappe.handler.handle()
  File "apps/frappe/frappe/handler.py", line 49, in handle
    data = execute_cmd(cmd)
  File "apps/frappe/frappe/handler.py", line 85, in execute_cmd
    return frappe.call(method, **frappe.form_dict)
  File "apps/frappe/frappe/__init__.py", line 1682, in call
    return fn(*args, **newargs)
  File "apps/frappe/frappe/utils/typing_validations.py", line 31, in wrapper
    return func(*args, **kwargs)
  File "apps/frappe/frappe/model/mapper.py", line 23, in make_mapped_doc
    method = frappe.get_attr(method)
  File "apps/frappe/frappe/__init__.py", line 1672, in get_attr
    return getattr(get_module(modulename), methodname)
AttributeError: module 'workwings.plcm.doctype.log_schedule' has no attribute 'make_log_schedule'

Request Data

{
	"type": "POST",
	"args": {
		"method": "workwings.plcm.doctype.log_schedule.make_log_schedule",
		"source_name": "RIPL-PP-AFBC-2024-00046",
		"args": null,
		"selected_children": "{}"
	},
	"freeze": true,
	"freeze_message": "",
	"headers": {},
	"error_handlers": {},
	"url": "/api/method/frappe.model.mapper.make_mapped_doc",
	"request_id": null
}

Response Data

{
	"exception": "AttributeError: module 'workwings.plcm.doctype.log_schedule' has no attribute 'make_log_schedule'",
	"exc_type": "AttributeError"
}

Hi @ashutosh.realgroup
Maybe :thinking: the path is not found correctly Please Verify.
Thank You!

I have checked the path but the error remains same

Hi @ashutosh.realgroup
Please pass the class

class Log_Test(Document):
    pass

@frappe.whitelist()
def make_log_schedule(source_name, target_doc=None):
    #your code

Thank You!

Hi @Mohammadali thanks for response but this didn’t helped and caused different error

IndentationError: unexpected indent

App Versions

{
	"frappe": "15.15.0",
	"workwings": "0.0.1"
}

Route

Workspaces/Core Masters

Traceback

Traceback (most recent call last):
  File "apps/frappe/frappe/app.py", line 110, in application
    response = frappe.api.handle(request)
  File "apps/frappe/frappe/api/__init__.py", line 49, in handle
    data = endpoint(**arguments)
  File "apps/frappe/frappe/api/v1.py", line 36, in handle_rpc_call
    return frappe.handler.handle()
  File "apps/frappe/frappe/handler.py", line 49, in handle
    data = execute_cmd(cmd)
  File "apps/frappe/frappe/handler.py", line 85, in execute_cmd
    return frappe.call(method, **frappe.form_dict)
  File "apps/frappe/frappe/__init__.py", line 1682, in call
    return fn(*args, **newargs)
  File "apps/frappe/frappe/utils/typing_validations.py", line 31, in wrapper
    return func(*args, **kwargs)
  File "apps/frappe/frappe/desk/form/load.py", line 72, in getdoctype
    docs = get_meta_bundle(doctype)
  File "apps/frappe/frappe/desk/form/load.py", line 83, in get_meta_bundle
    bundle = [frappe.desk.form.meta.get_meta(doctype)]
  File "apps/frappe/frappe/desk/form/meta.py", line 46, in get_meta
    meta = FormMeta(doctype)
  File "apps/frappe/frappe/desk/form/meta.py", line 57, in __init__
    self.load_assets()
  File "apps/frappe/frappe/desk/form/meta.py", line 71, in load_assets
    self.load_templates()
  File "apps/frappe/frappe/desk/form/meta.py", line 252, in load_templates
    module = load_doctype_module(self.name)
  File "apps/frappe/frappe/modules/utils.py", line 237, in load_doctype_module
    doctype_python_modules[key] = frappe.get_module(module_name)
  File "apps/frappe/frappe/__init__.py", line 1414, in get_module
    return importlib.import_module(modulename)
  File "/usr/lib/python3.10/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 879, in exec_module
  File "<frozen importlib._bootstrap_external>", line 1017, in get_code
  File "<frozen importlib._bootstrap_external>", line 947, in source_to_code
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "apps/workwings/workwings/plcm/doctype/log_test/log_test.py", line 14
    def make_log_schedule(source_name, target_doc=None):
IndentationError: unexpected indent

Request Data

{
	"type": "GET",
	"args": {
		"doctype": "Log_Test",
		"with_parent": 1,
		"cached_timestamp": null
	},
	"headers": {},
	"error_handlers": {},
	"url": "/api/method/frappe.desk.form.load.getdoctype",
	"request_id": null
}

Response Data

{
	"exception": "IndentationError: unexpected indent",
	"exc_type": "IndentationError",
	"_exc_source": "workwings (app)"
}

the log_schedule is the folder i guess. your make_log_schedule function should under the log_schedule file.
can you try the method with workwings.plcm.doctype.log_schedule.log_schedule.make_log_schedule

@Safvan_Ph thanks for your response

But that method also not working
Yes the log_schedule is a folder with all the code files of that doctype

Can you show me the path in vs code?

Hi @ashutosh.realgroup
Please check It

Thank You!

@Mohammadali thanks for the video

it solved the indentation error but the Attribute error still remains same

it showing your function is in the log test file.
Try the method using workwings.plcm.doctype.log_test.log_test.make_log_schedule

and in the log_test.py file
change like this:

class Log_Test(Document):
    pass

@frappe.whitelist()
def make_log_schedule(source_name, target_doc=None):
    #your code```

@Safvan_Ph thanks idk i how i have done this silly mistake of naming different file

I have changed the name
But it popped a new error

TypeError: ‘NoneType’ object is not iterable
Possible source of error: workwings (app)

App Versions

{
	"frappe": "15.15.0",
	"workwings": "0.0.1"
}

Route

Form/Log_Test/RIPL-PP-AFBC-2024-00046

Traceback

Traceback (most recent call last):
  File "apps/frappe/frappe/app.py", line 110, in application
    response = frappe.api.handle(request)
  File "apps/frappe/frappe/api/__init__.py", line 49, in handle
    data = endpoint(**arguments)
  File "apps/frappe/frappe/api/v1.py", line 36, in handle_rpc_call
    return frappe.handler.handle()
  File "apps/frappe/frappe/handler.py", line 49, in handle
    data = execute_cmd(cmd)
  File "apps/frappe/frappe/handler.py", line 85, in execute_cmd
    return frappe.call(method, **frappe.form_dict)
  File "apps/frappe/frappe/__init__.py", line 1682, in call
    return fn(*args, **newargs)
  File "apps/frappe/frappe/utils/typing_validations.py", line 31, in wrapper
    return func(*args, **kwargs)
  File "apps/frappe/frappe/model/mapper.py", line 36, in make_mapped_doc
    return method(source_name)
  File "apps/frappe/frappe/utils/typing_validations.py", line 31, in wrapper
    return func(*args, **kwargs)
  File "apps/workwings/workwings/plcm/doctype/log_test/log_test.py", line 26, in make_log_schedule
    for machine in log_test.get("log_test_machines"):
TypeError: 'NoneType' object is not iterable

Request Data

{
	"type": "POST",
	"args": {
		"method": "workwings.plcm.doctype.log_test.log_test.make_log_schedule",
		"source_name": "RIPL-PP-AFBC-2024-00046",
		"args": null,
		"selected_children": "{}"
	},
	"freeze": true,
	"freeze_message": "",
	"headers": {},
	"error_handlers": {},
	"url": "/api/method/frappe.model.mapper.make_mapped_doc",
	"request_id": null
}

Response Data

{
	"exception": "TypeError: 'NoneType' object is not iterable",
	"exc_type": "TypeError",
	"_exc_source": "workwings (app)"
}

which means your log_test_machines table is empty please add a condition before the loop.

log_test_machines = log_test.get("log_test_machines")

if log_test_machines is not None:
    for machine in log_test_machines:

It has two rows added the machine related readings

try to print log_test.get("log_test_machines") this in the error log

added the print statement its not printing the data already exist in the machine related readings

  1. please cross check the table field name
  2. try to print log_test after try this also log_test.log_test_machines

table field names are same in both doctypes Log_Test and Log_Schedule

machine_related_readings
other_measurable_readings

Oh but in the code you added log_test_machines in log_test.get(“log_test_machines”)
what is that