public function get_restock_plan(WP_REST_Request $request) { global $wpdb; $ingredients_table = $wpdb->prefix . 'petops_ingredients'; $ingredients = $wpdb->get_results( "SELECT * FROM {$ingredients_table} ORDER BY name ASC", ARRAY_A ); $plan = []; foreach ($ingredients as $item) { $qty_on_hand = floatval($item['qty_on_hand']); $reorder_level = floatval($item['reorder_level']); if ($qty_on_hand <= $reorder_level) { $suggested_qty = max($reorder_level - $qty_on_hand, 0); $plan[] = [ 'id' => intval($item['id']), 'name' => $item['name'], 'unit' => $item['unit'], 'vendor' => $item['vendor'], 'qty_on_hand' => round($qty_on_hand, 2), 'reorder_level' => round($reorder_level, 2), 'suggested_qty' => round($suggested_qty, 2), 'avg_cost' => round(floatval($item['avg_cost']), 2), 'estimated_restock_cost' => round($suggested_qty * floatval($item['avg_cost']), 2), ]; } } return rest_ensure_response($plan); } public function get_finished_goods(WP_REST_Request $request) { global $wpdb; $finished_goods_table = $wpdb->prefix . 'petops_finished_goods'; $recipes_table = $wpdb->prefix . 'petops_recipes'; $rows = $wpdb->get_results( "SELECT fg.*, r.name AS recipe_name FROM {$finished_goods_table} fg LEFT JOIN {$recipes_table} r ON fg.recipe_id = r.id ORDER BY fg.name ASC", ARRAY_A ); return rest_ensure_response($rows); } public function create_finished_good(WP_REST_Request $request) { global $wpdb; $finished_goods_table = $wpdb->prefix . 'petops_finished_goods'; $recipe_id = $request->get_param('recipe_id') ? intval($request->get_param('recipe_id')) : null; $product_type = sanitize_text_field($request->get_param('product_type')); $name = sanitize_text_field($request->get_param('name')); $qty_on_hand = intval($request->get_param('qty_on_hand')); $committed = intval($request->get_param('committed')); $cost_per_unit = floatval($request->get_param('cost_per_unit')); $price = floatval($request->get_param('price')); $market_price = floatval($request->get_param('market_price')); if (empty($name) || empty($product_type)) { return new WP_Error( 'petops_missing_finished_goods_fields', 'Name and product type are required.', ['status' => 400] ); } $inserted = $wpdb->insert( $finished_goods_table, [ 'recipe_id' => $recipe_id, 'product_type' => $product_type, 'name' => $name, 'qty_on_hand' => $qty_on_hand, 'committed' => $committed, 'cost_per_unit' => $cost_per_unit, 'price' => $price, 'market_price' => $market_price, ], ['%d', '%s', '%s', '%d', '%d', '%f', '%f', '%f'] ); if (!$inserted) { return new WP_Error( 'petops_finished_goods_insert_failed', 'Could not create finished good.', ['status' => 500] ); } return rest_ensure_response([ 'success' => true, 'id' => $wpdb->insert_id, ]); } public function adjust_finished_goods(WP_REST_Request $request) { global $wpdb; $finished_goods_table = $wpdb->prefix . 'petops_finished_goods'; $inventory_tx_table = $wpdb->prefix . 'petops_inventory_transactions'; $finished_good_id = intval($request->get_param('finished_good_id')); $change_amount = floatval($request->get_param('change_amount')); $reason = sanitize_text_field($request->get_param('reason')); $notes = sanitize_text_field($request->get_param('notes')); if ($finished_good_id <= 0) { return new WP_Error( 'petops_invalid_finished_good', 'Finished good is required.', ['status' => 400] ); } if ($change_amount == 0) { return new WP_Error( 'petops_invalid_finished_good_change', 'Change amount must be non-zero.', ['status' => 400] ); } $item = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$finished_goods_table} WHERE id = %d", $finished_good_id ), ARRAY_A ); if (!$item) { return new WP_Error( 'petops_finished_good_not_found', 'Finished good not found.', ['status' => 404] ); } $before_qty = intval($item['qty_on_hand']); $after_qty = $before_qty + $change_amount; $updated = $wpdb->update( $finished_goods_table, [ 'qty_on_hand' => $after_qty, ], [ 'id' => $finished_good_id, ], ['%d'], ['%d'] ); if ($updated === false) { return new WP_Error( 'petops_finished_goods_update_failed', 'Could not update finished goods inventory.', ['status' => 500] ); } $wpdb->insert( $inventory_tx_table, [ 'item_type' => 'finished_good', 'item_id' => $finished_good_id, 'change_amount' => $change_amount, 'reason' => $reason ? $reason : 'manual_adjustment', 'reference_id' => '', 'notes' => $notes, ], ['%s', '%d', '%f', '%s', '%s', '%s'] ); return rest_ensure_response([ 'success' => true, 'item' => $item['name'], 'before' => $before_qty, 'change' => $change_amount, 'after' => $after_qty, ]); } } https://gadawgfood.co/page-sitemap.xml 2026-01-23T18:59:58+00:00 https://gadawgfood.co/product-sitemap.xml 2026-03-04T11:04:38+00:00 https://gadawgfood.co/product_brand-sitemap.xml 2026-03-04T11:04:38+00:00 https://gadawgfood.co/product_cat-sitemap.xml 2026-03-04T11:04:38+00:00 https://gadawgfood.co/product_tag-sitemap.xml 2025-11-15T18:47:58+00:00 https://gadawgfood.co/product_shipping_class-sitemap.xml 2026-03-04T11:04:38+00:00