getOne( "SELECT `content_id` FROM `".BIT_DB_PREFIX."liberty_xref` WHERE `item` = 'SCREF' AND UPPER( `xkey` ) = UPPER( ? )", [ trim( $name ) ] ); $_stockSupplierCache[$key] = $contentId ? (int)$contentId : null; return $_stockSupplierCache[$key]; } function stockExpungeComponentByTitle( string $title ): bool { global $gBitDb; $contentId = $gBitDb->getOne( "SELECT lc.`content_id` FROM `".BIT_DB_PREFIX."liberty_content` lc WHERE lc.`content_type_guid` = '".'stockcomponent'."' AND lc.`title` = ?", [ $title ] ); if( !$contentId ) { return false; } $component = new StockComponent( (int)$contentId ); $component->expunge(); return true; } function stockImportSimpleComponent( array $data, int $rowNum ): array { global $gBitDb; $result = [ 'loaded' => 0, 'skipped' => 0, 'errors' => [] ]; $title = trim( $data[0] ?? '' ); if( empty( $title ) ) { $result['skipped']++; $result['errors'][] = "Row $rowNum: empty title, skipped."; return $result; } $exists = $gBitDb->getOne( "SELECT lc.`content_id` FROM `".BIT_DB_PREFIX."liberty_content` lc WHERE lc.`content_type_guid` = '".'stockcomponent'."' AND lc.`title` = ?", [ $title ] ); if( $exists ) { $result['skipped']++; $result['errors'][] = "Row $rowNum: '$title' already exists, skipped."; return $result; } $description = trim( $data[1] ?? '' ); $supplierName = trim( $data[2] ?? '' ); $supplierPn = trim( $data[3] ?? '' ); $supplierPrice = trim( $data[4] ?? '' ); $supplierUrl = trim( $data[5] ?? '' ); $qtyType = strtoupper( trim( $data[6] ?? '' ) ); $qtyValue = trim( $data[7] ?? '' ); $component = new StockComponent(); $pHash = [ 'title' => $title, 'edit' => $description, 'format_guid' => 'bithtml', ]; if( !$component->store( $pHash ) ) { $result['skipped']++; $result['errors'][] = "Row $rowNum: failed to create component '$title'."; return $result; } $contentId = $component->mContentId; if( !empty( $supplierName ) ) { $supplierContentId = stockImportFindSupplier( $supplierName ); if( !$supplierContentId ) { $result['errors'][] = "Row $rowNum: '$title' — supplier '$supplierName' not found in contacts, xrefs skipped."; } else { $xrefId = $gBitDb->GenID( 'liberty_xref_seq' ); $gBitDb->associateInsert( BIT_DB_PREFIX.'liberty_xref', [ 'xref_id' => $xrefId, 'content_id' => $contentId, 'item' => '#SUP', 'xorder' => 1, 'xref' => $supplierContentId, 'xkey' => substr( $supplierPn, 0, 32 ), 'xkey_ext' => substr( $supplierPrice, 0, 250 ), 'data' => $supplierUrl ?: null, 'last_update_date' => $gBitDb->NOW(), ] ); } } // Quantity type xref — sets the default qty type used by movement CSV imports // and the pack size shown in BOM displays (PRT/PCK xref xkey = pieces per pack) if( in_array( $qtyType, [ 'PRT', 'PCK', 'SHT', 'VOL' ] ) ) { $gBitDb->associateInsert( BIT_DB_PREFIX.'liberty_xref', [ 'xref_id' => $gBitDb->GenID( 'liberty_xref_seq' ), 'content_id' => $contentId, 'item' => $qtyType, 'xkey' => substr( $qtyValue, 0, 32 ), 'xorder' => 0, 'last_update_date' => $gBitDb->NOW(), ] ); } $result['loaded']++; return $result; }