diff options
| author | Lester Caine <lester@lsces.co.uk> | 2026-06-01 12:34:02 +0100 |
|---|---|---|
| committer | Lester Caine <lester@lsces.co.uk> | 2026-06-01 12:34:02 +0100 |
| commit | 6b30ab3d3ec23bd3f6056f2d1685159487383378 (patch) | |
| tree | 8771041a52fadc545c1badbc38c910c56d84d2f3 | |
| parent | a16e3d92444befcbd857d3bf00381b559d494d20 (diff) | |
| download | stock-6b30ab3d3ec23bd3f6056f2d1685159487383378.tar.gz stock-6b30ab3d3ec23bd3f6056f2d1685159487383378.tar.bz2 stock-6b30ab3d3ec23bd3f6056f2d1685159487383378.zip | |
Stock/movement assembly linkage, view icons, and list_stock fixes
- add_requisition: store ASSEMBLY xref on new movements so they can be filtered by assembly
- StockMovement::getList: add assembly_content_id filter via ASSEMBLY xref join
- list_movements: pass assemblyContentId to Smarty
- view_assembly.tpl: add View Stock and View Movements icons filtered by assembly
- list_stock: guard CAST with SIMILAR TO on xkey join; fix %.3g scientific notation to %.0f
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
| -rw-r--r-- | add_requisition.php | 90 | ||||
| -rw-r--r-- | list_movements.php | 7 | ||||
| -rw-r--r-- | list_stock.php | 1 | ||||
| -rw-r--r-- | templates/list_stock.tpl | 10 | ||||
| -rwxr-xr-x | templates/view_assembly.tpl | 2 |
5 files changed, 104 insertions, 6 deletions
diff --git a/add_requisition.php b/add_requisition.php new file mode 100644 index 0000000..db9a9b7 --- /dev/null +++ b/add_requisition.php @@ -0,0 +1,90 @@ +<?php +/** + * @package stock + * @subpackage functions + */ + +namespace Bitweaver\Stock; + +use Bitweaver\KernelTools; + +require_once '../kernel/includes/setup_inc.php'; + +global $gBitSystem, $gBitSmarty, $gBitUser; + +$gBitSystem->verifyPermission( 'p_stock_create' ); + +if( !empty( $_REQUEST['fCancel'] ) ) { + header( 'Location: '.STOCK_PKG_URL.'list_stock.php' ); + die; +} + +if( !empty( $_REQUEST['fCreate'] ) ) { + $assemblyContentId = isset( $_REQUEST['assembly_content_id'] ) && is_numeric( $_REQUEST['assembly_content_id'] ) + ? (int)$_REQUEST['assembly_content_id'] : null; + $kitCount = isset( $_REQUEST['kit_count'] ) && is_numeric( $_REQUEST['kit_count'] ) && (float)$_REQUEST['kit_count'] > 0 + ? (float)$_REQUEST['kit_count'] : 1; + + $title = trim( $_REQUEST['title'] ?? '' ); + + if( !$assemblyContentId ) { + $errors[] = KernelTools::tra( 'Please select an assembly.' ); + } elseif( $title === '' ) { + $errors[] = KernelTools::tra( 'Please enter an RQ number.' ); + } else { + // Verify assembly exists without relying on content type registry + global $gBitDb; + $assemblyExists = $gBitDb->getOne( + "SELECT `content_id` FROM `".BIT_DB_PREFIX."liberty_content` + WHERE `content_id` = ? AND `content_type_guid` = 'stockassembly'", + [ $assemblyContentId ] + ); + if( !$assemblyExists ) { + $errors[] = KernelTools::tra( 'Assembly not found.' ); + } else { + $movement = new StockMovement(); + $paramHash = [ + 'title' => $title, + 'content_type_guid' => STOCKMOVEMENT_CONTENT_TYPE_GUID, + ]; + if( $movement->store( $paramHash ) ) { + $reqnHash = [ + 'content_id' => $movement->mContentId, + 'item' => 'REQN', + 'xkey' => $title, + 'fAddXref' => 1, + ]; + $movement->storeXref( $reqnHash ); + $assemblyHash = [ + 'content_id' => $movement->mContentId, + 'item' => 'ASSEMBLY', + 'xref' => $assemblyContentId, + 'fAddXref' => 1, + ]; + $movement->storeXref( $assemblyHash ); + $movement->explodeFromAssembly( $assemblyContentId, $kitCount ); + header( 'Location: '.STOCK_PKG_URL.'edit_movement.php?content_id='.$movement->mContentId ); + die; + } + $errors = $movement->mErrors; + } + } +} + +// Assembly list for selector +$assembly = new StockAssembly(); +$listHash = [ 'show_empty' => true, 'sort_mode' => 'title_asc', 'max_records' => 500 ]; +$assemblyList = $assembly->getList( $listHash ); + +// Pre-select if coming from list_stock +$preselect = isset( $_REQUEST['assembly_content_id'] ) && is_numeric( $_REQUEST['assembly_content_id'] ) + ? (int)$_REQUEST['assembly_content_id'] : null; +$kitCount = isset( $_REQUEST['kit_count'] ) && is_numeric( $_REQUEST['kit_count'] ) + ? (float)$_REQUEST['kit_count'] : 1; + +$gBitSmarty->assign( 'assemblyList', $assemblyList ); +$gBitSmarty->assign( 'preselect', $preselect ); +$gBitSmarty->assign( 'kitCount', $kitCount ); +$gBitSmarty->assign( 'errors', $errors ?? [] ); + +$gBitSystem->display( 'bitpackage:stock/add_requisition.tpl', KernelTools::tra( 'Create Requisition' ), [ 'display_mode' => 'edit' ] ); diff --git a/list_movements.php b/list_movements.php index 6da281b..10d2526 100644 --- a/list_movements.php +++ b/list_movements.php @@ -15,8 +15,9 @@ $movement = new StockMovement(); $listHash = $_REQUEST; $movementList = $movement->getList( $listHash ); -$gBitSmarty->assign( 'listInfo', $listHash['listInfo'] ); -$gBitSmarty->assign( 'movementList', $movementList ); -$gBitSmarty->assign( 'filterType', $_REQUEST['ref_type'] ?? '' ); +$gBitSmarty->assign( 'listInfo', $listHash['listInfo'] ); +$gBitSmarty->assign( 'movementList', $movementList ); +$gBitSmarty->assign( 'filterType', $_REQUEST['ref_type'] ?? '' ); +$gBitSmarty->assign( 'assemblyContentId', isset( $_REQUEST['assembly_content_id'] ) && is_numeric( $_REQUEST['assembly_content_id'] ) ? (int)$_REQUEST['assembly_content_id'] : null ); $gBitSystem->display( 'bitpackage:stock/list_movements.tpl', 'Movements', [ 'display_mode' => 'list' ] ); diff --git a/list_stock.php b/list_stock.php index 668a401..d55df91 100644 --- a/list_stock.php +++ b/list_stock.php @@ -61,6 +61,7 @@ $query = "SELECT lc.`content_id`, lc.`title`, lc.`data`, $joinSql INNER JOIN `{$X}liberty_xref` x ON x.`xref` = lc.`content_id` AND x.`item` IN ('SGL','PCK','SHT','VOL') + AND x.`xkey` SIMILAR TO '[0-9]+(\.[0-9]+)?' INNER JOIN `{$X}liberty_content` mc ON mc.`content_id` = x.`content_id` AND mc.`content_type_guid` = 'stockmovement' WHERE lc.`content_type_guid` = 'stockcomponent' diff --git a/templates/list_stock.tpl b/templates/list_stock.tpl index 343e426..faac32a 100644 --- a/templates/list_stock.tpl +++ b/templates/list_stock.tpl @@ -39,6 +39,10 @@ </label> </div> <button type="submit" class="btn btn-default btn-sm">{tr}Go{/tr}</button> + {if $showBom && $gBitUser->hasPermission('p_stock_create')} + <a class="btn btn-warning btn-sm" + href="{$smarty.const.STOCK_PKG_URL}add_requisition.php?assembly_content_id={$assemblyContentId}&kit_count={$kitCount}">{tr}Create Requisition{/tr}</a> + {/if} </div> {/form} @@ -66,12 +70,12 @@ <td rowspan="{$comp.stock|@count}">{$comp.data|escape}</td> <td rowspan="{$comp.stock|@count}">{$comp.part_number|escape}</td> {/if} - {if $showBom}<td class="text-right">{math equation="b*k" b=$row.bom_qty k=$kitCount format="%.3g"}</td>{/if} + {if $showBom}<td class="text-right">{math equation="b*k" b=$row.bom_qty k=$kitCount format="%.0f"}</td>{/if} <td>{$qtype|escape}</td> - <td class="text-right">{$row.level|string_format:"%.3g"}</td> + <td class="text-right">{$row.level|string_format:"%.0f"}</td> {if $showBom} {assign var=remaining value=$row.level-($row.bom_qty*$kitCount)} - <td class="text-right{if $remaining < 0} text-danger{/if}">{$remaining|string_format:"%.3g"}</td> + <td class="text-right{if $remaining < 0} text-danger{/if}">{$remaining|string_format:"%.0f"}</td> {/if} </tr> {/foreach} diff --git a/templates/view_assembly.tpl b/templates/view_assembly.tpl index da9979e..6a7ab9c 100755 --- a/templates/view_assembly.tpl +++ b/templates/view_assembly.tpl @@ -4,6 +4,8 @@ {include file="bitpackage:liberty/services_inc.tpl" serviceLocation='icon' serviceHash=$gContent->mInfo} <a title="{tr}Edit{/tr}" href="{$smarty.const.STOCK_PKG_URL}edit_assembly.php?content_id={$gContent->mContentId}">{booticon iname="fa-pen-to-square" iexplain="Edit Assembly"}</a> <a title="{tr}Component Order{/tr}" href="{$smarty.const.STOCK_PKG_URL}component_order.php?content_id={$gContent->mContentId}">{booticon iname="fa-sort" iexplain="Component Order"}</a> + <a title="{tr}View Stock{/tr}" href="{$smarty.const.STOCK_PKG_URL}list_stock.php?assembly_content_id={$gContent->mContentId}">{booticon iname="fa-boxes-stacked" iexplain="View Stock"}</a> + <a title="{tr}View Movements{/tr}" href="{$smarty.const.STOCK_PKG_URL}list_movements.php?assembly_content_id={$gContent->mContentId}">{booticon iname="fa-truck" iexplain="View Movements"}</a> {if $gContent->hasAdminPermission()} <a title="{tr}Delete Assembly{/tr}" href="{$smarty.const.STOCK_PKG_URL}edit_assembly.php?content_id={$gContent->mContentId}&delete=1">{booticon iname="fa-trash" iexplain="Delete Assembly"}</a> {/if} |
