*/ public static function code_labels() { return array( 'MB001' => __( 'Sold below product cost', 'marginbeacon' ), 'MB014' => __( 'Fully discounted / free-gift line with remaining cost', 'marginbeacon' ), 'MB_LINE_FULLY_DISCOUNTED' => __( 'Fully discounted / free-gift line with remaining cost', 'marginbeacon' ), 'MB013' => __( 'Free-shipping coupon — shipping cost out of scope', 'marginbeacon' ), 'MB015' => __( 'Excluded from margin — credit line', 'marginbeacon' ), 'MB_LINE_CREDIT_EXCLUDED' => __( 'Excluded from margin — credit line', 'marginbeacon' ), 'MB_COST_MISSING' => __( 'Product cost missing', 'marginbeacon' ), 'MB_COST_INVALID' => __( 'Product cost invalid', 'marginbeacon' ), 'MB_COST_PRESENCE_UNRESOLVED' => __( 'Zero cost versus missing cost could not be distinguished', 'marginbeacon' ), 'MB_COGS_TAX_BASIS_INVALID' => __( 'COGS tax basis invalid — costs must be tax-exclusive', 'marginbeacon' ), 'MB_TAX_BASIS_UNRESOLVED' => __( 'Tax basis could not be resolved for this price', 'marginbeacon' ), 'MB_SALE_ORIGIN_UNVERIFIED' => __( 'Sale price origin unverified', 'marginbeacon' ), 'MB_PRICE_UNRESOLVED' => __( 'Product price could not be resolved', 'marginbeacon' ), 'MB_CURRENCY_UNSUPPORTED' => __( 'Order currency differs from store base currency', 'marginbeacon' ), 'MB_RENEWAL_UNSUPPORTED' => __( 'Subscription renewal is not evaluated', 'marginbeacon' ), 'MB_MONEY_PRECISION_INVALID' => __( 'Money precision invalid', 'marginbeacon' ), 'MB_TOTALS_INVALID' => __( 'Order totals invalid', 'marginbeacon' ), 'MB_PRICING_UNSUPPORTED' => __( 'Pricing path unsupported', 'marginbeacon' ), 'MB_NO_PROMOTION_DETECTED' => __( 'No promotion detected', 'marginbeacon' ), 'MB_STATUS_INELIGIBLE' => __( 'Order status not eligible for evaluation', 'marginbeacon' ), ); } /** * Full reason line for order detail panel. * * @param array $row Order risk row. * @return string */ public static function from_row( array $row ) { $code = ! empty( $row['short_reason_code'] ) ? (string) $row['short_reason_code'] : ''; $dual = DualContextPresenter::from_row( $row ); $loss = (int) $dual['loss_making_lines']; $badge = isset( $row['risk_badge'] ) ? (string) $row['risk_badge'] : ''; $parts = array(); // Prefer synthesized below-cost economics when Critical/High with known revenue & COGS. $loss_text = self::loss_summary( $row, $loss ); if ( $loss_text ) { $parts[] = $loss_text; } elseif ( $code && isset( self::code_labels()[ $code ] ) ) { $parts[] = self::code_labels()[ $code ]; } elseif ( $code ) { $parts[] = $code; } if ( $code && $loss_text && 'MB001' !== $code && 'MB014' !== $code ) { array_unshift( $parts, self::code_labels()[ $code ] ?? $code ); } if ( empty( $parts ) && Severity::CRITICAL === $badge ) { $parts[] = __( 'Gross product margin below critical threshold', 'marginbeacon' ); } if ( empty( $parts ) && Severity::SAFE === $badge ) { $parts[] = __( 'Gross product margin within Safe band', 'marginbeacon' ); } $text = implode( ' · ', array_filter( $parts ) ); if ( $code && $text && false === strpos( $text, $code ) ) { $text .= ' (' . $code . ')'; } elseif ( $code && ! $text ) { $text = $code; } return $text; } /** * @param array $row Risk row. * @param int $loss Loss-making line count. * @return string */ private static function loss_summary( array $row, $loss ) { if ( null === $row['revenue'] || null === $row['cogs'] || '' === $row['revenue'] || '' === $row['cogs'] ) { return ''; } $badge = isset( $row['risk_badge'] ) ? (string) $row['risk_badge'] : ''; if ( ! in_array( $badge, array( Severity::CRITICAL, Severity::HIGH ), true ) ) { return ''; } $rev_str = trim( (string) $row['revenue'] ); $cog_str = trim( (string) $row['cogs'] ); $cmp = function_exists( 'bccomp' ) ? bccomp( $cog_str, $rev_str, 8 ) : ( preg_match( '/^[1-9]/', ltrim( $cog_str, '0' ) ) && preg_match( '/^[0]/', $rev_str ) ? 1 : 0 ); if ( $cmp <= 0 ) { // Still critical/high on thin margin — not a gross loss headline. if ( $loss > 0 ) { return sprintf( /* translators: %d: count */ _n( '%d item sold below cost', '%d items sold below cost', $loss, 'marginbeacon' ), $loss ); } return ''; } // Calculate gap using integer arithmetic (PRD 9.7). $gap_scaled = bcsub( $cog_str, $rev_str, 8 ); $gap_whole = rtrim( rtrim( $gap_scaled, '0' ), '.' ); if ( '' === $gap_whole ) { $gap_whole = '0'; } if ( function_exists( 'wc_price' ) ) { $formatted = wp_strip_all_tags( wc_price( $gap_whole ) ); } else { $parts = explode( '.', $gap_whole, 2 ); $digits = ltrim( $parts[0], '-' ); if ( '' === $digits ) { $digits = '0'; } $digits = str_pad( $digits, 1, '0', STR_PAD_LEFT ); $formatted = ( '-' === $parts[0][0] ? '-' : '' ) . number_format( (int) $digits, 0, ',', '.' ); } $base = sprintf( /* translators: %s: formatted money gap */ __( 'COGS exceeds revenue by %s', 'marginbeacon' ), $formatted ); if ( $loss > 0 ) { $base .= '; ' . sprintf( /* translators: %d: count */ _n( '%d item sold below cost', '%d items sold below cost', $loss, 'marginbeacon' ), $loss ); } return $base; } }