Token导航 LogoToken导航

Agent Skill · 待分类

payment-application-processor(支付应用处理器)

payment-application-processor 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

payment-application-processor 是待分类类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为权限未标注;许可证信息还不明确,第三方扫描已通过,按安装量在待分类类的 11,209 个 Skill 里排第 7,194。

总安装 380周安装 16GitHub Stars 111下载 133核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:payment-application-processor(支付应用处理器)
来源仓库:https://github.com/datadrivenconstruction/ddc_skills_for_ai_agents_in_construction
仓库路径:skills/payment-application-processor
安装命令:
npx skills add https://github.com/datadrivenconstruction/ddc_skills_for_ai_agents_in_construction --skill payment-application-processor
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/datadrivenconstruction/ddc_skills_for_ai_agents_in_construction --skill payment-application-processor

这个 Skill 是做什么的

这个 Skill 的分类还没最终确定,用法以来源仓库的说明为准。

payment-application-processor 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中围绕仓库状态、代码变更或协作事项进行整理时使用。适用于待分类的协作流程管理,可结合项目实际维护状态使用。

通过 npx skills add 命令从 GitHub 安装,需确认权限范围和维护状态。安装前建议检查是否会触发联网、命令执行或文件读写等操作。适用宿主包括 Codex、Claude、Cursor、Gemini CLI,接入前应确认版本、权限和运行环境要求。

来源仓库内路径:skills/payment-application-processor

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/datadrivenconstruction/ddc_skills_for_ai_agent…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    权限没有明确标注,第一次使用时只给一个无关紧要的任务,观察它到底读了哪些文件和网络。

常见问题

6 条

payment-application-processor 怎么安装?

在终端执行 npx skills add https://github.com/datadrivenconstruction/ddc_skills_for_ai_agents_in_const…。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

payment-application-processor 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

payment-application-processor 需要什么权限?

权限级别没有明确标注。第一次使用时建议只给无关紧要的任务,观察它实际读写了哪些内容。

payment-application-processor 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

payment-application-processor 用的人多吗?

公开数据是累计安装 380 次,近一周安装 16 次,下载 133 次,GitHub 111 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

payment-application-processor 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理待分类类任务、又不想每次都手写提示词的人。

不太适合

  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

待分类类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
infsh-cli

infsh CLI · Codex、Claude

4,374,576382权限未标注未明确未收录
ai-video-generation

AI 视频生成 · Codex、Claude

4,313,376382调用外部服务未明确有提醒
lark-openapi-explorer

云雀 OpenAPI 浏览器 · Codex、Claude

2,064,1209,011需要联网未明确有提醒
lark-workflow-standup-report

Lark 工作流程站立报告 · Codex、Claude

2,041,6328,978需要联网未明确通过
use-my-browser

使用我的浏览器 · Codex、Claude

1,848,49140操作浏览器未明确未通过
payment-application-processor

支付应用处理器 · 本页

380111权限未标注未明确通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Payment Application Processor

Overview

Process construction payment applications from creation through approval. Validate against schedule of values, calculate retainage, generate AIA G702/G703 forms, and track payment status.

Payment Application Flow

┌─────────────────────────────────────────────────────────────────┐
│                PAYMENT APPLICATION FLOW                          │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  Schedule of    →    Draft      →    Review    →    Approve    │
│  Values              Pay App         & Verify        & Pay      │
│  ──────────          ───────         ────────        ────────   │
│  📋 SOV items        📝 Enter %      ✓ Verify        ✅ Approve │
│  💰 Line values      📊 Calculate    📸 Field        💵 Release │
│  📅 Billing plan     📄 G702/703     📧 Submit       📄 Record  │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

Technical Implementation

from dataclasses import dataclass, field
from typing import List, Dict, Optional
from datetime import datetime, timedelta
from enum import Enum

class PayAppStatus(Enum):
    DRAFT = "draft"
    SUBMITTED = "submitted"
    UNDER_REVIEW = "under_review"
    APPROVED = "approved"
    REJECTED = "rejected"
    PAID = "paid"
    PARTIAL_PAID = "partial_paid"

class LineItemStatus(Enum):
    NOT_STARTED = "not_started"
    IN_PROGRESS = "in_progress"
    COMPLETE = "complete"

@dataclass
class SOVLineItem:
    number: str
    description: str
    scheduled_value: float
    previous_completed: float = 0.0
    current_completed: float = 0.0
    materials_stored: float = 0.0
    percent_complete: float = 0.0
    balance_to_finish: float = 0.0
    retainage: float = 0.0

    def calculate(self, retainage_rate: float = 0.10):
        """Calculate line item values."""
        self.percent_complete = (
            (self.previous_completed + self.current_completed + self.materials_stored)
            / self.scheduled_value * 100
            if self.scheduled_value > 0 else 0
        )
        self.balance_to_finish = (
            self.scheduled_value - self.previous_completed -
            self.current_completed - self.materials_stored
        )
        total_completed = self.previous_completed + self.current_completed + self.materials_stored
        self.retainage = total_completed * retainage_rate

@dataclass
class PaymentApplication:
    application_number: int
    project_name: str
    contractor: str
    period_from: datetime
    period_to: datetime

    # Contract info
    original_contract: float
    change_orders: float = 0.0
    contract_sum: float = 0.0

    # Line items
    line_items: List[SOVLineItem] = field(default_factory=list)

    # Totals
    total_scheduled: float = 0.0
    previous_completed: float = 0.0
    current_completed: float = 0.0
    materials_stored: float = 0.0
    total_completed: float = 0.0
    percent_complete: float = 0.0
    balance_to_finish: float = 0.0
    retainage: float = 0.0
    net_amount_due: float = 0.0

    # Status
    status: PayAppStatus = PayAppStatus.DRAFT
    submitted_date: Optional[datetime] = None
    approved_date: Optional[datetime] = None
    approved_amount: float = 0.0
    paid_date: Optional[datetime] = None
    paid_amount: float = 0.0

    # Retainage rates
    work_retainage_rate: float = 0.10
    stored_retainage_rate: float = 0.10

@dataclass
class G702Data:
    """AIA G702 Application and Certificate for Payment data."""
    application_number: int
    period_to: datetime
    project_name: str
    owner: str
    contractor: str
    architect: str

    original_contract_sum: float
    net_change_orders: float
    contract_sum_to_date: float
    total_completed_stored: float
    retainage: float
    total_earned_less_retainage: float
    less_previous_certificates: float
    current_payment_due: float
    balance_to_finish: float

class PaymentApplicationProcessor:
    """Process construction payment applications."""

    def __init__(self, project_name: str, contractor: str,
                 original_contract: float):
        self.project_name = project_name
        self.contractor = contractor
        self.original_contract = original_contract
        self.change_orders_total = 0.0

        self.schedule_of_values: List[SOVLineItem] = []
        self.pay_apps: Dict[int, PaymentApplication] = {}
        self.next_app_number = 1

        self.work_retainage_rate = 0.10
        self.stored_retainage_rate = 0.10

    def set_retainage_rates(self, work_rate: float, stored_rate: float = None):
        """Set retainage rates."""
        self.work_retainage_rate = work_rate
        self.stored_retainage_rate = stored_rate if stored_rate else work_rate

    def add_sov_item(self, number: str, description: str,
                    scheduled_value: float) -> SOVLineItem:
        """Add line item to schedule of values."""
        item = SOVLineItem(
            number=number,
            description=description,
            scheduled_value=scheduled_value
        )
        self.schedule_of_values.append(item)
        return item

    def import_sov(self, items: List[Dict]) -> int:
        """Import schedule of values from list."""
        count = 0
        for item in items:
            self.add_sov_item(
                item['number'],
                item['description'],
                item['value']
            )
            count += 1
        return count

    def add_change_order(self, amount: float, description: str = ""):
        """Add approved change order to contract."""
        self.change_orders_total += amount

        # Add as new SOV item
        co_number = f"CO-{len([i for i in self.schedule_of_values if 'CO-' in i.number])+1:03d}"
        self.add_sov_item(co_number, description or f"Change Order", amount)

    def create_pay_app(self, period_from: datetime,
                      period_to: datetime) -> PaymentApplication:
        """Create new payment application."""
        app_number = self.next_app_number

        # Copy SOV with previous values
        line_items = []
        for sov_item in self.schedule_of_values:
            # Get previous completed from last pay app
            prev_completed = 0.0
            if app_number > 1:
                prev_app = self.pay_apps.get(app_number - 1)
                if prev_app:
                    prev_item = next(
                        (i for i in prev_app.line_items if i.number == sov_item.number),
                        None
                    )
                    if prev_item:
                        prev_completed = (prev_item.previous_completed +
                                        prev_item.current_completed +
                                        prev_item.materials_stored)

            line_items.append(SOVLineItem(
                number=sov_item.number,
                description=sov_item.description,
                scheduled_value=sov_item.scheduled_value,
                previous_completed=prev_completed
            ))

        pay_app = PaymentApplication(
            application_number=app_number,
            project_name=self.project_name,
            contractor=self.contractor,
            period_from=period_from,
            period_to=period_to,
            original_contract=self.original_contract,
            change_orders=self.change_orders_total,
            contract_sum=self.original_contract + self.change_orders_total,
            line_items=line_items,
            work_retainage_rate=self.work_retainage_rate,
            stored_retainage_rate=self.stored_retainage_rate
        )

        self.pay_apps[app_number] = pay_app
        self.next_app_number += 1

        return pay_app

    def update_line_item(self, app_number: int, line_number: str,
                        current_completed: float = None,
                        materials_stored: float = None) -> SOVLineItem:
        """Update line item progress."""
        if app_number not in self.pay_apps:
            raise ValueError(f"Pay app {app_number} not found")

        pay_app = self.pay_apps[app_number]
        item = next((i for i in pay_app.line_items if i.number == line_number), None)

        if not item:
            raise ValueError(f"Line item {line_number} not found")

        if current_completed is not None:
            item.current_completed = current_completed
        if materials_stored is not None:
            item.materials_stored = materials_stored

        item.calculate(pay_app.work_retainage_rate)

        # Recalculate pay app totals
        self._calculate_totals(pay_app)

        return item

    def update_by_percentage(self, app_number: int, line_number: str,
                            percent_complete: float) -> SOVLineItem:
        """Update line item by percentage complete."""
        if app_number not in self.pay_apps:
            raise ValueError(f"Pay app {app_number} not found")

        pay_app = self.pay_apps[app_number]
        item = next((i for i in pay_app.line_items if i.number == line_number), None)

        if not item:
            raise ValueError(f"Line item {line_number} not found")

        # Calculate current completed from percentage
        total_earned = item.scheduled_value * (percent_complete / 100)
        item.current_completed = total_earned - item.previous_completed - item.materials_stored

        if item.current_completed < 0:
            item.current_completed = 0

        item.calculate(pay_app.work_retainage_rate)
        self._calculate_totals(pay_app)

        return item

    def _calculate_totals(self, pay_app: PaymentApplication):
        """Calculate pay app totals."""
        pay_app.total_scheduled = sum(i.scheduled_value for i in pay_app.line_items)
        pay_app.previous_completed = sum(i.previous_completed for i in pay_app.line_items)
        pay_app.current_completed = sum(i.current_completed for i in pay_app.line_items)
        pay_app.materials_stored = sum(i.materials_stored for i in pay_app.line_items)

        pay_app.total_completed = (
            pay_app.previous_completed +
            pay_app.current_completed +
            pay_app.materials_stored
        )

        pay_app.percent_complete = (
            pay_app.total_completed / pay_app.total_scheduled * 100
            if pay_app.total_scheduled > 0 else 0
        )

        pay_app.balance_to_finish = pay_app.contract_sum - pay_app.total_completed

        # Calculate retainage
        work_retainage = (pay_app.previous_completed + pay_app.current_completed) * pay_app.work_retainage_rate
        stored_retainage = pay_app.materials_stored * pay_app.stored_retainage_rate
        pay_app.retainage = work_retainage + stored_retainage

        # Previous certificates
        previous_certs = 0
        if pay_app.application_number > 1:
            prev_app = self.pay_apps.get(pay_app.application_number - 1)
            if prev_app:
                previous_certs = prev_app.total_completed - prev_app.retainage

        # Net amount due
        pay_app.net_amount_due = (
            pay_app.total_completed - pay_app.retainage - previous_certs
        )

    def submit_pay_app(self, app_number: int) -> PaymentApplication:
        """Submit pay app for review."""
        if app_number not in self.pay_apps:
            raise ValueError(f"Pay app {app_number} not found")

        pay_app = self.pay_apps[app_number]
        pay_app.status = PayAppStatus.SUBMITTED
        pay_app.submitted_date = datetime.now()

        return pay_app

    def approve_pay_app(self, app_number: int,
                       approved_amount: float = None) -> PaymentApplication:
        """Approve pay app."""
        if app_number not in self.pay_apps:
            raise ValueError(f"Pay app {app_number} not found")

        pay_app = self.pay_apps[app_number]
        pay_app.status = PayAppStatus.APPROVED
        pay_app.approved_date = datetime.now()
        pay_app.approved_amount = approved_amount if approved_amount else pay_app.net_amount_due

        return pay_app

    def record_payment(self, app_number: int, paid_amount: float,
                      paid_date: datetime = None) -> PaymentApplication:
        """Record payment received."""
        if app_number not in self.pay_apps:
            raise ValueError(f"Pay app {app_number} not found")

        pay_app = self.pay_apps[app_number]
        pay_app.paid_date = paid_date or datetime.now()
        pay_app.paid_amount = paid_amount

        if paid_amount >= pay_app.approved_amount:
            pay_app.status = PayAppStatus.PAID
        else:
            pay_app.status = PayAppStatus.PARTIAL_PAID

        return pay_app

    def generate_g702(self, app_number: int, owner: str,
                     architect: str) -> G702Data:
        """Generate AIA G702 data."""
        if app_number not in self.pay_apps:
            raise ValueError(f"Pay app {app_number} not found")

        pay_app = self.pay_apps[app_number]

        # Previous certificates
        previous_certs = 0
        if app_number > 1:
            prev_app = self.pay_apps.get(app_number - 1)
            if prev_app:
                previous_certs = prev_app.total_completed - prev_app.retainage

        return G702Data(
            application_number=pay_app.application_number,
            period_to=pay_app.period_to,
            project_name=pay_app.project_name,
            owner=owner,
            contractor=pay_app.contractor,
            architect=architect,
            original_contract_sum=pay_app.original_contract,
            net_change_orders=pay_app.change_orders,
            contract_sum_to_date=pay_app.contract_sum,
            total_completed_stored=pay_app.total_completed,
            retainage=pay_app.retainage,
            total_earned_less_retainage=pay_app.total_completed - pay_app.retainage,
            less_previous_certificates=previous_certs,
            current_payment_due=pay_app.net_amount_due,
            balance_to_finish=pay_app.balance_to_finish
        )

    def generate_g703(self, app_number: int) -> str:
        """Generate AIA G703 continuation sheet."""
        if app_number not in self.pay_apps:
            return "Pay app not found"

        pay_app = self.pay_apps[app_number]

        lines = [
            "# AIA G703 - Continuation Sheet",
            "",
            f"**Application Number:** {pay_app.application_number}",
            f"**Period To:** {pay_app.period_to.strftime('%Y-%m-%d')}",
            "",
            "| Item | Description | Scheduled | Previous | This Period | Stored | Total | % | Balance | Retainage |",
            "|------|-------------|-----------|----------|-------------|--------|-------|---|---------|-----------|"
        ]

        for item in pay_app.line_items:
            lines.append(
                f"| {item.number} | {item.description[:20]} | "
                f"${item.scheduled_value:,.0f} | ${item.previous_completed:,.0f} | "
                f"${item.current_completed:,.0f} | ${item.materials_stored:,.0f} | "
                f"${item.previous_completed + item.current_completed + item.materials_stored:,.0f} | "
                f"{item.percent_complete:.0f}% | ${item.balance_to_finish:,.0f} | "
                f"${item.retainage:,.0f} |"
            )

        lines.extend([
            "",
            f"| **TOTALS** | | ${pay_app.total_scheduled:,.0f} | "
            f"${pay_app.previous_completed:,.0f} | ${pay_app.current_completed:,.0f} | "
            f"${pay_app.materials_stored:,.0f} | ${pay_app.total_completed:,.0f} | "
            f"{pay_app.percent_complete:.0f}% | ${pay_app.balance_to_finish:,.0f} | "
            f"${pay_app.retainage:,.0f} |"
        ])

        return "\n".join(lines)

    def get_billing_summary(self) -> Dict:
        """Get billing summary across all pay apps."""
        total_billed = sum(pa.total_completed for pa in self.pay_apps.values())
        total_paid = sum(pa.paid_amount for pa in self.pay_apps.values())
        total_retainage = sum(pa.retainage for pa in self.pay_apps.values())

        pending = [pa for pa in self.pay_apps.values()
                   if pa.status in [PayAppStatus.SUBMITTED, PayAppStatus.UNDER_REVIEW, PayAppStatus.APPROVED]]

        return {
            "contract_sum": self.original_contract + self.change_orders_total,
            "total_billed": total_billed,
            "total_paid": total_paid,
            "total_retainage": total_retainage,
            "outstanding": total_billed - total_paid - total_retainage,
            "pending_apps": len(pending),
            "pending_amount": sum(pa.net_amount_due for pa in pending),
            "percent_billed": total_billed / (self.original_contract + self.change_orders_total) * 100
        }

Quick Start

from datetime import datetime

# Initialize processor
processor = PaymentApplicationProcessor(
    project_name="Office Tower",
    contractor="ABC Construction",
    original_contract=5000000
)

# Import schedule of values
processor.import_sov([
    {"number": "01", "description": "General Conditions", "value": 250000},
    {"number": "02", "description": "Sitework", "value": 300000},
    {"number": "03", "description": "Concrete", "value": 800000},
    {"number": "04", "description": "Structural Steel", "value": 1200000},
    {"number": "05", "description": "MEP", "value": 1500000},
    {"number": "06", "description": "Finishes", "value": 950000},
])

# Create pay application
pay_app = processor.create_pay_app(
    period_from=datetime(2024, 1, 1),
    period_to=datetime(2024, 1, 31)
)

# Update progress
processor.update_by_percentage(pay_app.application_number, "01", 100)  # GC 100%
processor.update_by_percentage(pay_app.application_number, "02", 75)   # Site 75%
processor.update_by_percentage(pay_app.application_number, "03", 50)   # Concrete 50%
processor.update_line_item(pay_app.application_number, "04",
                          current_completed=200000, materials_stored=300000)

# Submit and approve
processor.submit_pay_app(pay_app.application_number)
processor.approve_pay_app(pay_app.application_number)

# Generate G703
print(processor.generate_g703(pay_app.application_number))

# Get summary
summary = processor.get_billing_summary()
print(f"Percent Billed: {summary['percent_billed']:.1f}%")

Requirements

pip install (no external dependencies)

平台分布

Codex

37.51%
按下载量换算50

Claude

27.71%
按下载量换算37

Cursor

18.68%
按下载量换算25

Gemini CLI

10.13%
按下载量换算13

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

权限未标注

当前来源未能明确判断权限范围,默认进入异常复核队列。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills