Consolidation Flow
BMCT and PPMP use separate source-declared creation variants with parallel multi-record effects. The review preparation source and template separately declare their display inputs, while PPMP deletion is a distinct destructive reversal path.
Creation flow
flowchart TD
subgraph BMCT
b0["BMCT posted selectors"] --> b1["BMCT eligible aggregate"]
b1 --> b2["Insert tbl_bmct_consolidate"]
b2 --> b3["Mark BMCT items consolidated"]
b3 --> b4["BMCT parent-status branch"]
b4 --> b5["Write tbl_pr_log per BMCT parent"]
b5 --> b6["Source-declared JSON completion"]
end
subgraph Canonical_PPMP
p0["Canonical PPMP posted selectors"] --> p1["Canonical PPMP eligible aggregate"]
p1 --> p2["Insert tbl_ppmp_consolidate"]
p2 --> p3["Mark canonical PPMP items consolidated"]
p3 --> p4["Canonical PPMP parent-status branch"]
p4 --> p5["Write tbl_ppmp_log per PPMP parent"]
p5 --> p6["Source-declared JSON completion"]
end
condition["Optional parent-request ID parameter"]
b4 -.-> condition
p4 -.-> condition
For both the BMCT and canonical PPMP lanes, an absent optional parent-request ID causes the corresponding parent rows to be set to CONSOLIDATED; when the parameter is present, selected item rows are still marked consolidated but that parent update is skipped. The alternate view-ppmp declaration has no optional-parent branch and unconditionally updates parent rows; the allowed evidence does not prove which declaration, if either, is dispatched.
The BMCT lane is declared in imspr/novusoft/include/consolidation/custom/consolidate.php; the PPMP lane represents the canonical implementation in imspr/novusoft/include/ppmp-consolidate/custom/consolidate.php.
Neither creation source guards an empty or null aggregate before reading record fields or splitting the cid and mainid values. For a no-match or null-field result, the source does not prove that the consolidation insert, item or parent updates, per-parent logging, or JSON output will be reached.
The source differences are limited to their selection and storage contexts:
- BMCT reads the BMCT item and parent catalog tables using the posted item code, account, and department context; its aggregate also carries year, parent IDs, item IDs, account data, department, and procurement mode.
- PPMP reads the PPMP item and parent catalog tables using posted item code, account, department, year, and procurement-mode context; its aggregate carries the total, year, parent IDs, and item IDs.
Review handoffs and action gates
The review preparation source imspr/novusoft/include/consolidation/custom/view-consolidate.php declares $data['table'] from tableGenerator(null,$row,$label). The template imspr/novusoft/include/consolidation/view/view-consolidate.php consumes $table. The searched sources do not prove the assignment or binding between those variables.
The preparation source also declares $data['cosolidated_record'] after applying display fallbacks, including a generated TX- entry value when the stored entry is empty. The template consumes $cosolidated_record for the entry number, date, year, account, requestor, position, purpose, and remarks. Mode of Procurement is rendered separately from $mop; preparation declares $data['mop']. The binding between the preparation variables and the template variables is unresolved in the searched evidence.
The template’s visible actions are controlled by source predicates:
- Delete is rendered only when
$deleteis true. The preparation source derives that flag from session role IDs1,4, or5; the template emits thedelete_consbutton with the consolidation ID. - Transfer is considered only inside the
!$cosolidated_record->uploadedbranch. It is unavailable when the GPMS department is empty or item-code errors are present. Otherwise, the template emits atransfer-actionbutton with the consolidation ID. - These template gates establish visible presentation behavior only. They do not prove that the corresponding external handler is registered or that an action succeeds.
PPMP deletion reverses the consolidation
The separate deletion source is imspr/novusoft/include/ppmp-consolidate/custom/delete-cons.php. Its declared source order is:
1. Enable transaction mode | Calls dbTrans(true) before reading the posted deletion request.
2. Read the consolidation ID | Takes the value from `$postData['id']`; the source does not show server-side validation or ownership checking for it.
3. Soft-delete the consolidation | Updates matching tbl_ppmp_consolidate rows with deleted = 1.
4. Find affected parents | Queries distinct parent IDs through tbl_ppmp_catalog and tbl_ppmp_catalog_item, then immediately splits the returned ID string for subsequent steps.
5. Detach items | Clears consolidate_id and sets consolidated = 0 on matching tbl_ppmp_catalog_item rows.
6. Restore parent state | Sets affected tbl_ppmp_catalog rows to pr_status = UNAPPROVED and consolidated = FOR REAPPROVAL.
7. Write per-parent deletion logs | The source does not normalize or guard a null/empty parent result before the restoration and logging path. A per-parent log and the success flag set inside the loop are therefore not guaranteed when no parent ID is returned.
8. Disable transaction mode and exit | Calls dbTrans(false), then passes the response data to jsonexit.
The source sets $data['success'] to true inside the per-parent logging loop. Therefore, the JSON exit is a source-declared completion signal, not proof that every database update or log insert succeeded. The owned deletion source shows no explicit rollback path.
[!WARNING] The owned files are include-style top-level scripts, and no caller, registration, handler, or route binding is proven here; runtime reachability, actual execution, and successful completion remain unobserved. Creation selectors and the deletion ID originate from posted data, while the inspected sources show no explicit validation or ownership/tenant check. The review role test controls only whether the Delete button is rendered, not server-side authorization. Before relying on these workflows, verify their external binding and enforce validation and authorization at that boundary.
Updated