External Transfer

The repository declares an External Transfer workflow, but no execution record proves completion. On the preparation success branch, start-transfer.php stores arranged account records in the ppmpdetails session and inserts an audit record; this session state is separate from the later version JSON snapshot. The client invokes the per-account transfer implementation, which is source-defined to process one account at a time, perform the declared external and local operations, and call the version-file write. Response values and client messages remain signals rather than verified external-write or snapshot results.

Declared transfer path

The primary PPMP flow is assembled by the handlers and implementations in imspr/novusoft/include/view-ppmp/custom.js, imspr/novusoft/include/view-ppmp/custom/start-transfer.php, and imspr/novusoft/include/view-ppmp/custom/transfering.php.

sequenceDiagram
    participant client as #trasfer_ppmp / transfer_item
    participant prep as start-transfer.php
    participant gpms as prdb
    participant session as ppmpdetails session
    participant loop as transfering.php
    participant local as Local database
    participant ext as External PUB tables
    participant snapshot as Version JSON file
    participant audit as tbl_mother_ppmp_log

    client->>prep: POST id
    prep->>gpms: arrange_ppmp(ppmp_id)
    alt preparation reports success
        prep->>session: Store arranged account records
        prep->>audit: Insert action=transfer record
        prep-->>client: session_id + first account_code
        client->>loop: POST ppmp_id + account_code + session_id
        loop->>session: Select requested account record
        loop->>local: Check tbl_transfer_record
        alt no existing transfer record
            loop->>ext: Insert annual-procurement and ap-detail
            loop->>local: Create tbl_transfer_record
        else existing transfer record
            loop->>ext: Replace ap-detail rows
            loop->>local: Increment stored version
        end
        loop->>snapshot: Write version JSON
        loop->>session: Unset account in working array
        alt accounts remain
            loop->>session: Persist reduced ppmpdetails
            loop-->>client: success + next account_code
            client->>loop: Recurse for next account
        else no accounts remain
            loop->>local: Set tbl_ppmp.transfer = 1
            loop-->>client: success + DONE (no reduced session write)
        end
    else preparation reports failure
        prep-->>client: Returned message
    end

The #trasfer_ppmp handler confirms the action, posts the selected id to component/custom/k1Qodw53nG/start-transfer, and calls transfer_item only when the preparation response has data.success. A failed preparation response displays data.message.

Preparation uses arrange_ppmp in imspr/novusoft/include/view-ppmp/custom/start-transfer.php. On its success branch, the implementation:

  • Stores the arranged results under the ppmpdetails session key beneath a random session ID.
  • Returns that session ID and the first account_code.
  • Inserts an action=transfer record into tbl_mother_ppmp_log, including the posted data, arranged record, previous log ID, and session user fields.

Transfer control availability

Inspected view Source-declared condition Transfer control
Generic consolidation view, imspr/novusoft/include/consolidation/view/view-consolidate.php Record is not uploaded, gpms_dept is present, and no item-code error is reported Renders .transfer-action with the consolidated record ID
Generic consolidation view Record is already uploaded ($cosolidated_record->uploaded) Transfer is unavailable from this view: no Transfer button is rendered, and the “not yet uploaded” presentation is not entered because that branch requires the record to be not uploaded
Generic consolidation view Empty gpms_dept Displays that the PPMP is not yet uploaded to GPMS
Generic consolidation view item_code_error is present Displays that transfer is unavailable because an item code does not exist in GPMS
PPMP-consolidation view, imspr/novusoft/include/ppmp-consolidate/view/view-consolidate.php !$cosolidated_record->uploaded && $approved_2==1 The .transfer-action button is inside an HTML comment and is disabled or unreachable from this rendered view

The generic view conditions are presentation-level controls. The legacy transfer implementation does not show a matching server-side ownership or status recheck: it reads the posted ID and session data before declaring its external writes.

Artifacts and state changes

Stage Source-declared artifact Role
Preparation ppmpdetails session key Holds arranged account records under a random session ID for subsequent calls
Preparation tbl_mother_ppmp_log Records the transfer action, input and arranged record, previous log ID, and session user
New account transfer PUB.\"annual-procurement\" Target of the declared insert with version 1
New account transfer PUB.\"ap-detail\" Target of the declared item-collection insert
New account transfer tbl_transfer_record Target of the declared local insert containing ppmp_id, account_code, and ap_plan_no
Existing account transfer PUB.\"ap-detail\" and tbl_transfer_record Declared delete/reinsert of detail rows, version increment, and local transfer-record update
Every account transfer PUBLICROOTPATH.'/public/uploaded/ppmp-version/<ppmp_id>-<account_code>-<version>.json' Target of the declared JSON snapshot write
Final account transfer tbl_ppmp.transfer and response account_code Declared local transfer-flag update to 1 and DONE response
Remaining accounts Reduced ppmpdetails session value Working-array removal; when accounts remain, the reduced value is persisted and the next account code is returned

Legacy consolidated-PR variant

The .transfer-action handler in imspr/novusoft/include/view-ppmp/custom.js posts the selected consolidated ID to component/custom/k1Qodw53nG/transfer. The source-defined implementation in imspr/novusoft/include/view-ppmp/custom/transfer.php reads the corresponding prdetails session entry and declares inserts into:

  • PUB.\"purchase-request\"
  • PUB.\"pr-detail\"

It then declares local updates that mark the consolidation as uploaded, mark related PR catalog records as TRANSFER, and insert transfer audit entries into tbl_pr_log.

The alternate implementation in imspr/novusoft/include/ppmp-consolidate/custom/transfer.php follows the same purchase-request and PR-detail transfer shape, but contains an active dj($details) before its declared external writes and JSON exit. That output is a response-integrity limitation for this variant.

[!WARNING] Completion is not externally verified. imspr/novusoft/include/view-ppmp/custom/transfering.php sets data['success'] = true after the declared database and snapshot operations, but does not expose a source-defined success result from either the external database or file_put_contents. Its exception wrapper and exception response assignments are commented out. The client therefore treats the response as successful and recurses—or displays Transfer Record Done for DONE—without proving that every external write or snapshot succeeded. The legacy .transfer-action handler is weaker still: its HTTP-success callback displays Transfer Successful! without checking data.success. Treat these messages and flags as client or local state signals, and independently verify the external and snapshot outcomes.

Updated