Back to list
OpenAEC-Foundation

erpnext-impl-scheduler

by OpenAEC-Foundation

28 deterministic Claude AI skills for flawless ERPNext/Frappe v14-16 development. Agent Skills standard compliant.

1🍴 1📅 Jan 23, 2026

SKILL.md


name: erpnext-impl-scheduler description: "Implementation workflows for Frappe scheduled tasks and background jobs (v14/v15/v16). Covers hooks.py scheduler_events, frappe.enqueue, queue selection, job deduplication, and error handling. Triggers: how to schedule task, background job, cron job, async processing, queue selection, job deduplication, scheduler implementation."

ERPNext Scheduler - Implementation

This skill helps you implement scheduled tasks and background jobs. For exact syntax, see erpnext-syntax-scheduler.

Version: v14/v15/v16 compatible

Main Decision: What Are You Trying to Do?

┌─────────────────────────────────────────────────────────────────────┐
│ SCHEDULER DECISION                                                  │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│ Run at fixed intervals or times?                                   │
│ ├── YES → Scheduler Event (hooks.py)                               │
│ │         See: references/workflows.md §1-2                        │
│ │                                                                   │
│ └── NO → Run in response to user action?                           │
│          ├── YES → frappe.enqueue()                                │
│          │         See: references/workflows.md §3-4               │
│          │                                                          │
│          └── NO → Probably neither - reconsider requirements       │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

Scheduler Event vs frappe.enqueue

AspectScheduler Eventfrappe.enqueue
Triggered byTime/intervalCode execution
Defined inhooks.pyPython code
ArgumentsNone (must be parameterless)Any serializable data
Use caseDaily cleanup, hourly syncUser-triggered long task
Restart behaviorRuns on scheduleLost if worker restarts

Which Scheduler Event Type?

┌─────────────────────────────────────────────────────────────────────┐
│ SCHEDULER EVENT TYPE                                                │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│ Simple recurring interval?                                         │
│ ├── Every minute    → scheduler_events.cron["* * * * *"]          │
│ ├── Hourly          → scheduler_events.hourly                      │
│ ├── Daily           → scheduler_events.daily                       │
│ ├── Weekly          → scheduler_events.weekly                      │
│ └── Monthly         → scheduler_events.monthly                     │
│                                                                     │
│ Complex schedule (e.g., "weekdays at 9am")?                        │
│ └── scheduler_events.cron["0 9 * * 1-5"]                          │
│                                                                     │
│ Run after every request?                                           │
│ └── scheduler_events.all (use sparingly!)                          │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

Which Queue?

QueueTimeoutUse For
short5 minQuick operations (<1 min)
default5 minStandard tasks (1-3 min)
long30 minHeavy processing (>3 min)

Rule: Always specify queue explicitly. Default is short.

Quick Start: Basic Scheduled Task

# myapp/tasks.py
import frappe

def daily_cleanup():
    """Daily cleanup task - no parameters allowed"""
    frappe.db.delete("Error Log", {"creation": ("<", frappe.utils.add_days(None, -30))})
    frappe.db.commit()
# hooks.py
scheduler_events = {
    "daily": [
        "myapp.tasks.daily_cleanup"
    ]
}

After editing hooks.py: bench migrate

Quick Start: Background Job

# myapp/api.py
import frappe
from frappe import enqueue

@frappe.whitelist()
def process_documents(doctype, filters):
    enqueue(
        "myapp.tasks.process_batch",
        queue="long",
        timeout=1800,
        job_id=f"process_{doctype}_{frappe.session.user}",  # v15+ dedup
        doctype=doctype,
        filters=filters
    )
    return {"status": "queued"}

Critical Rules

1. Scheduler tasks receive NO arguments

# ❌ WRONG
def my_task(doctype):  # Arguments not supported
    pass

# ✅ CORRECT
def my_task():  # Parameterless
    doctype = "Sales Invoice"  # Hardcode or read from settings

2. ALWAYS migrate after hooks.py changes

bench migrate  # Required to register new scheduler events

3. Jobs run as Administrator

Scheduler and enqueued jobs run with Administrator permissions. Always commit explicitly.

4. Commit after batches, not per record

# ❌ WRONG - Slow
for doc in docs:
    doc.save()
    frappe.db.commit()  # Commit per record

# ✅ CORRECT - Fast
for doc in docs:
    doc.save()
frappe.db.commit()  # Single commit after batch

5. Use job_id for deduplication (v15+)

enqueue(..., job_id="unique_identifier")  # Prevents duplicate jobs

Version Differences

Aspectv14v15v16
Tick interval4 min60 sec60 sec
Job dedupjob_namejob_idjob_id
Cron support

V14 deduplication uses different parameter:

# v14
enqueue(..., job_name="unique_id")
# v15+
enqueue(..., job_id="unique_id")

Reference Files

FileContents
workflows.mdStep-by-step implementation patterns
decision-tree.mdDetailed decision flowcharts
examples.mdComplete working examples
anti-patterns.mdCommon mistakes to avoid

See Also

  • erpnext-syntax-scheduler - Exact syntax reference
  • erpnext-errors-serverscripts - Error handling patterns

Score

Total Score

75/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

+10
説明文

100文字以上の説明がある

+10
人気

GitHub Stars 100以上

0/15
最近の活動

1ヶ月以内に更新

+10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

+5

Reviews

💬

Reviews coming soon