1, 'price' => $product->get_price(), ) ); if ( function_exists( 'wc_get_price_including_tax' ) ) { // WC 3.0+ $price = wc_get_price_including_tax( $product, $args ); } else { // WC < 3.0 $price = $product->get_price_including_tax( $args['qty'], $args['price'] ); } return $price; } /** * For a given product, and optionally price/qty, work out the sign-up fee with tax excluded, based on store settings. * * @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0 * @param WC_Product $product * @param array $args * @return float */ function wcs_get_price_excluding_tax( $product, $args = array() ) { $args = wp_parse_args( $args, array( 'qty' => 1, 'price' => $product->get_price(), ) ); if ( function_exists( 'wc_get_price_excluding_tax' ) ) { // WC 3.0+ $price = wc_get_price_excluding_tax( $product, $args ); } else { // WC < 3.0 $price = $product->get_price_excluding_tax( $args['qty'], $args['price'] ); } return $price; } /** * Returns a 'from' prefix if you want to show where prices start at. * * @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0 * @return string */ function wcs_get_price_html_from_text( $product = '' ) { if ( function_exists( 'wc_get_price_html_from_text' ) ) { // WC 3.0+ $price_html_from_text = wc_get_price_html_from_text(); } else { // WC < 3.0 $price_html_from_text = $product->get_price_html_from_text(); } return $price_html_from_text; } /** * Get an array of the prices, used to help determine min/max values. * * @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0 */ function wcs_get_variation_prices( $variation, $variable_product ) { return array( 'price' => apply_filters( 'woocommerce_variation_prices_price', WC_Subscriptions_Product::get_price( $variation ), $variation, $variable_product ), 'regular_price' => apply_filters( 'woocommerce_variation_prices_regular_price', WC_Subscriptions_Product::get_regular_price( $variation, 'edit' ), $variation, $variable_product ), 'sale_price' => apply_filters( 'woocommerce_variation_prices_sale_price', WC_Subscriptions_Product::get_sale_price( $variation, 'edit' ), $variation, $variable_product ), 'sign_up_fee' => apply_filters( 'woocommerce_variation_prices_sign_up_fee', WC_Subscriptions_Product::get_sign_up_fee( $variation ), $variation, $variable_product ), ); } /** * Get an array of the minimum and maximum priced variations based on subscription billing terms. * * @param array $child_variation_ids the IDs of product variation children ids * @return array Array containing the min and max variation prices and billing data * @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0 */ function wcs_get_min_max_variation_data( $variable_product, $child_variation_ids = array() ) { if ( empty( $child_variation_ids ) ) { $child_variation_ids = is_callable( array( $variable_product, 'get_visible_children' ) ) ? $variable_product->get_visible_children() : $variable_product->get_children( true ); } $variations_data = array(); foreach ( $child_variation_ids as $variation_id ) { if ( $variation = wc_get_product( $variation_id ) ) { $prices = wcs_get_variation_prices( $variation, $variable_product ); foreach ( $prices as $price_key => $amount ) { if ( '' !== $amount ) { if ( 'incl' === get_option( 'woocommerce_tax_display_shop' ) ) { $prices[ $price_key ] = wcs_get_price_including_tax( $variable_product, array( 'price' => $amount ) ); } else { $prices[ $price_key ] = wcs_get_price_excluding_tax( $variable_product, array( 'price' => $amount ) ); } } } $variations_data[ $variation_id ] = array( 'price' => $prices['price'], 'regular_price' => $prices['regular_price'], 'sale_price' => $prices['sale_price'], 'subscription' => array( 'sign_up_fee' => $prices['sign_up_fee'], 'period' => WC_Subscriptions_Product::get_period( $variation ), 'interval' => WC_Subscriptions_Product::get_interval( $variation ), 'trial_length' => WC_Subscriptions_Product::get_trial_length( $variation ), 'trial_period' => WC_Subscriptions_Product::get_trial_period( $variation ), 'length' => WC_Subscriptions_Product::get_length( $variation ), ), ); } } return wcs_calculate_min_max_variations( $variations_data ); } /** * Determine the minimum and maximum values for a set of structured subscription * price data in a form created by @see wcs_get_min_max_variation_data() * * @param array $variations_data the IDs of product variation children ids * @return array * @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0 */ function wcs_calculate_min_max_variations( $variations_data ) { $lowest_initial_amount = $highest_initial_amount = $lowest_price = $highest_price = ''; $shortest_initial_period = $longest_initial_period = $shortest_trial_period = $longest_trial_period = $shortest_trial_length = $longest_trial_length = ''; $longest_initial_interval = $shortest_initial_interval = $variable_subscription_period = $variable_subscription_period_interval = ''; $lowest_regular_price = $highest_regular_price = $lowest_sale_price = $highest_sale_price = $max_subscription_period = $max_subscription_period_interval = ''; $variable_subscription_sign_up_fee = $variable_subscription_trial_period = $variable_subscription_trial_length = $variable_subscription_length = $variable_subscription_sign_up_fee = $variable_subscription_trial_period = $variable_subscription_trial_length = $variable_subscription_length = ''; $min_variation_id = $max_variation_id = null; $variations_data_prices_list = array(); $variations_data_sign_up_fees_list = array(); $variations_data_periods_list = array(); $variations_data_intervals_list = array(); $variations_data_trial_lengths_list = array(); $variations_data_trial_periods_list = array(); $variations_data_lengths_list = array(); foreach ( $variations_data as $variation_id => $variation_data ) { $is_max = $is_min = false; if ( '' === $variation_data['price'] && empty( $variation_data['subscription']['sign_up_fee'] ) ) { continue; } $variations_data_prices_list = array_unique( array_merge( $variations_data_prices_list, array( $variation_data['price'] ) ) ); $variations_data_sign_up_fees_list = array_unique( array_merge( $variations_data_sign_up_fees_list, array( empty( $variation_data['subscription']['sign_up_fee'] ) ? 0 : $variation_data['subscription']['sign_up_fee'] ) ) ); $variations_data_periods_list = array_unique( array_merge( $variations_data_periods_list, array( $variation_data['subscription']['period'] ) ) ); $variations_data_intervals_list = array_unique( array_merge( $variations_data_intervals_list, array( $variation_data['subscription']['interval'] ) ) ); $variations_data_trial_lengths_list = array_unique( array_merge( $variations_data_trial_lengths_list, array( empty( $variation_data['subscription']['trial_length'] ) ? 0 : $variation_data['subscription']['trial_length'] ) ) ); $variations_data_trial_periods_list = array_unique( array_merge( $variations_data_trial_periods_list, array( $variation_data['subscription']['trial_period'] ) ) ); $variations_data_lengths_list = array_unique( array_merge( $variations_data_lengths_list, array( $variation_data['subscription']['length'] ) ) ); $has_free_trial = '' !== $variation_data['subscription']['trial_length'] && $variation_data['subscription']['trial_length'] > 0; // Determine some recurring price flags $is_lowest_price = $variation_data['price'] < $lowest_price || '' === $lowest_price; $is_longest_period = wcs_get_longest_period( $variable_subscription_period, $variation_data['subscription']['period'] ) === $variation_data['subscription']['period']; $is_longest_interval = $variation_data['subscription']['interval'] >= $variable_subscription_period_interval || '' === $variable_subscription_period_interval; // Find the amount the subscriber will have to pay up-front if ( $has_free_trial ) { $initial_amount = $variation_data['subscription']['sign_up_fee']; $initial_period = $variation_data['subscription']['trial_period']; $initial_interval = $variation_data['subscription']['trial_length']; } else { $initial_amount = (float) $variation_data['price'] + (float) $variation_data['subscription']['sign_up_fee']; $initial_period = $variation_data['subscription']['period']; $initial_interval = $variation_data['subscription']['interval']; } // We have a free trial & no sign-up fee, so need to choose the longest free trial (and maybe the shortest) if ( $has_free_trial && 0 == $variation_data['subscription']['sign_up_fee'] ) { // First variation if ( '' === $longest_trial_period ) { $is_min = true; // If two variations have the same free trial, choose the variation with the lowest recurring price for the longest period } elseif ( $variable_subscription_trial_period === $variation_data['subscription']['trial_period'] && $variation_data['subscription']['trial_length'] === $variable_subscription_trial_length ) { // If the variation has the lowest recurring price, it's the cheapest if ( $is_lowest_price ) { $is_min = true; // When current variation's free trial is the same as the lowest, it's the cheaper if it has a longer billing schedule } elseif ( $variation_data['price'] === $lowest_price ) { if ( $is_longest_period && $is_longest_interval ) { $is_min = true; // Longest with a new billing period } elseif ( $is_longest_period && $variation_data['subscription']['period'] !== $variable_subscription_trial_period ) { $is_min = true; } } // Otherwise the cheapest variation is the one with the longer trial } elseif ( $variable_subscription_trial_period === $variation_data['subscription']['trial_period'] ) { $is_min = $variation_data['subscription']['trial_length'] > $variable_subscription_trial_length; // Otherwise just a longer trial period (that isn't equal to the longest period) } elseif ( wcs_get_longest_period( $longest_trial_period, $variation_data['subscription']['trial_period'] ) === $variation_data['subscription']['trial_period'] ) { $is_min = true; } if ( $is_min ) { $longest_trial_period = $variation_data['subscription']['trial_period']; $longest_trial_length = $variation_data['subscription']['trial_length']; } // If the current cheapest variation is also free, then the shortest trial period is the most expensive if ( 0 == $lowest_price || '' === $lowest_price ) { if ( '' === $shortest_trial_period ) { $is_max = true; // Need to check trial length } elseif ( $shortest_trial_period === $variation_data['subscription']['trial_period'] ) { $is_max = $variation_data['subscription']['trial_length'] < $shortest_trial_length; // Need to find shortest period } elseif ( wcs_get_shortest_period( $shortest_trial_period, $variation_data['subscription']['trial_period'] ) === $variation_data['subscription']['trial_period'] ) { $is_max = true; } if ( $is_max ) { $shortest_trial_period = $variation_data['subscription']['trial_period']; $shortest_trial_length = $variation_data['subscription']['trial_length']; } } } else { $longest_initial_period = wcs_get_longest_period( $longest_initial_period, $initial_period ); $shortest_initial_period = wcs_get_shortest_period( $shortest_initial_period, $initial_period ); $is_lowest_initial_amount = $initial_amount < $lowest_initial_amount || '' === $lowest_initial_amount; $is_longest_initial_period = $initial_period === $longest_initial_period; $is_longest_initial_interval = $initial_interval >= $longest_initial_interval || '' === $longest_initial_interval; $is_highest_initial = $initial_amount > $highest_initial_amount || '' === $highest_initial_amount; $is_shortest_period = $initial_period === $shortest_initial_period || '' === $shortest_initial_period; $is_shortest_interval = $initial_interval < $shortest_initial_interval || '' === $shortest_initial_interval; // If we're not dealing with the lowest initial access amount, then ignore this variation if ( ! $is_lowest_initial_amount && $initial_amount !== $lowest_initial_amount ) { continue; } // If the variation has the lowest price, it's the cheapest if ( $is_lowest_initial_amount ) { $is_min = true; // When current variation's price is the same as the lowest, it's the cheapest only if it has a longer billing schedule } elseif ( $initial_amount === $lowest_initial_amount ) { // We need to check the recurring schedule when the sign-up fee & free trial periods are equal if ( $has_free_trial && $initial_period == $longest_initial_period && $initial_interval == $longest_initial_interval ) { // If the variation has the lowest recurring price, it's the cheapest if ( $is_lowest_price ) { $is_min = true; // When current variation's price is the same as the lowest, it's the cheapest only if it has a longer billing schedule } elseif ( $variation_data['price'] === $lowest_price ) { if ( $is_longest_period && $is_longest_interval ) { $is_min = true; // Longest with a new billing period } elseif ( $is_longest_period && $variation_data['subscription']['period'] !== $variable_subscription_period ) { $is_min = true; } } // Longest initial term is the cheapest } elseif ( $is_longest_initial_period && $is_longest_initial_interval ) { $is_min = true; // Longest with a new billing period } elseif ( $is_longest_initial_period && $initial_period !== $variable_subscription_period ) { $is_min = true; } } // If we have the highest price for the shortest period, we might have the maximum variation if ( $is_highest_initial && $is_shortest_period && $is_shortest_interval ) { $is_max = true; // But only if its for the shortest billing period } elseif ( $variation_data['price'] === $highest_price ) { if ( $is_shortest_period && $is_shortest_interval ) { $is_max = true; } elseif ( $is_shortest_period ) { $is_max = true; } } } // If it's the min subscription terms if ( $is_min ) { $min_variation_id = $variation_id; $lowest_price = $variation_data['price']; $lowest_regular_price = $variation_data['regular_price']; $lowest_sale_price = $variation_data['sale_price']; $lowest_regular_price = ( '' === $lowest_regular_price ) ? 0 : $lowest_regular_price; $lowest_sale_price = ( '' === $lowest_sale_price ) ? 0 : $lowest_sale_price; $lowest_initial_amount = $initial_amount; $longest_initial_period = $initial_period; $longest_initial_interval = $initial_interval; $variable_subscription_sign_up_fee = $variation_data['subscription']['sign_up_fee']; $variable_subscription_period = $variation_data['subscription']['period']; $variable_subscription_period_interval = $variation_data['subscription']['interval']; $variable_subscription_trial_length = $variation_data['subscription']['trial_length']; $variable_subscription_trial_period = $variation_data['subscription']['trial_period']; $variable_subscription_length = $variation_data['subscription']['length']; } if ( $is_max ) { $max_variation_id = $variation_id; $highest_price = $variation_data['price']; $highest_regular_price = $variation_data['regular_price']; $highest_sale_price = $variation_data['sale_price']; $highest_initial_amount = $initial_amount; $highest_regular_price = ( '' === $highest_regular_price ) ? 0 : $highest_regular_price; $highest_sale_price = ( '' === $highest_sale_price ) ? 0 : $highest_sale_price; $max_subscription_period = $variation_data['subscription']['period']; $max_subscription_period_interval = $variation_data['subscription']['interval']; } } if ( sizeof( array_unique( $variations_data_prices_list ) ) > 1 ) { $subscription_details_identical = false; } elseif ( sizeof( array_unique( $variations_data_sign_up_fees_list ) ) > 1 ) { $subscription_details_identical = false; } elseif ( sizeof( array_unique( $variations_data_periods_list ) ) > 1 ) { $subscription_details_identical = false; } elseif ( sizeof( array_unique( $variations_data_intervals_list ) ) > 1 ) { $subscription_details_identical = false; } elseif ( sizeof( array_unique( $variations_data_trial_lengths_list ) ) > 1 ) { $subscription_details_identical = false; } elseif ( sizeof( array_unique( $variations_data_trial_periods_list ) ) > 1 ) { $subscription_details_identical = false; } elseif ( sizeof( array_unique( $variations_data_lengths_list ) ) > 1 ) { $subscription_details_identical = false; } else { $subscription_details_identical = true; } return array( 'min' => array( 'variation_id' => $min_variation_id, 'price' => $lowest_price, 'regular_price' => $lowest_regular_price, 'sale_price' => $lowest_sale_price, 'period' => $variable_subscription_period, 'interval' => $variable_subscription_period_interval, ), 'max' => array( 'variation_id' => $max_variation_id, 'price' => $highest_price, 'regular_price' => $highest_regular_price, 'sale_price' => $highest_sale_price, 'period' => $max_subscription_period, 'interval' => $max_subscription_period_interval, ), 'subscription' => array( 'signup-fee' => $variable_subscription_sign_up_fee, 'trial_period' => $variable_subscription_trial_period, 'trial_length' => $variable_subscription_trial_length, 'length' => $variable_subscription_length, ), 'identical' => $subscription_details_identical, ); } /** * Generates a key for grouping subscription products with the same billing schedule. * * Used in a frontend cart and checkout context to group items by a recurring cart key for use in generating recurring carts. * Used by the orders//subscriptions REST API endpoint to group order items into subscriptions. * * @see https://woocommerce.com/document/subscriptions/develop/multiple-subscriptions/#section-3 * * @param WC_Product $product The product to generate the key for. * @param int $renewal_time The timestamp of the first renewal payment. * * @return string The subscription product grouping key. */ function wcs_get_subscription_grouping_key( $product, $renewal_time = 0 ) { $key = ''; $renewal_time = ! empty( $renewal_time ) ? $renewal_time : WC_Subscriptions_Product::get_first_renewal_payment_time( $product ); $interval = WC_Subscriptions_Product::get_interval( $product ); $period = WC_Subscriptions_Product::get_period( $product ); $length = WC_Subscriptions_Product::get_length( $product ); $trial_period = WC_Subscriptions_Product::get_trial_period( $product ); $trial_length = WC_Subscriptions_Product::get_trial_length( $product ); if ( $renewal_time > 0 ) { $key .= gmdate( 'Y_m_d_', $renewal_time ); } // First start with the billing interval and period. switch ( $interval ) { case 1: if ( 'day' === $period ) { $key .= 'daily'; } else { $key .= sprintf( '%sly', $period ); } break; case 2: $key .= sprintf( 'every_2nd_%s', $period ); break; case 3: $key .= sprintf( 'every_3rd_%s', $period ); // or sometimes two exceptions it would seem break; default: $key .= sprintf( 'every_%dth_%s', $interval, $period ); break; } if ( $length > 0 ) { $key .= '_for_'; $key .= sprintf( '%d_%s', $length, $period ); if ( $length > 1 ) { $key .= 's'; } } if ( $trial_length > 0 ) { $key .= sprintf( '_after_a_%d_%s_trial', $trial_length, $trial_period ); } return apply_filters( 'wcs_subscription_product_grouping_key', $key, $product, $renewal_time ); } Greg Connell Archives - Odessa Headlines https://odessaheadlines.com/tag/greg-connell/ Covering Ector County, Texas Wed, 11 Sep 2024 19:19:52 +0000 en-US hourly 1 https://wordpress.org/?v=7.1.4 https://odessaheadlines.com/wp-content/uploads/2021/03/cropped-MAR21-Odessa-Icon-150x150.png Greg Connell Archives - Odessa Headlines https://odessaheadlines.com/tag/greg-connell/ 32 32 Councilman Hanie Holds The Line https://odessaheadlines.com/2024/09/11/councilman-hanie-holds-the-line/ Wed, 11 Sep 2024 19:18:59 +0000 https://odessaheadlines.com/?p=2517 Despite a passionate plea from Councilman Chris Hanie to consider the plight of local taxpayers, the Odessa City Council voted Tuesday to raise water, sewer, and property taxes for most Odessans, by a vote of six to one. City Manager John Beckmeyer had previously promised that the City’s use of a new zero-based budget would […]

Councilman Hanie Holds The Line is a story from Odessa Headlines, a publication covering Ector County, Texas. Odessa Headlines’ vision is to provide quality in-depth original coverage and commentary of local issues – predominantly politics and public policy – while cross-sharing excellent coverage of state and national issues from our media partners across Texas.

]]>
Despite a passionate plea from Councilman Chris Hanie to consider the plight of local taxpayers, the Odessa City Council voted Tuesday to raise water, sewer, and property taxes for most Odessans, by a vote of six to one.

City Manager John Beckmeyer had previously promised that the City’s use of a new zero-based budget would save money, yet the budget passed Tuesday night featured a 9.4% overall increase of nearly $12 million, bringing the total budget to $305,193,877.

A notable change in the budget was the addition of nearly $1 million to staff the City Manager’s office with seven public relations and communications personnel. This came alongside an almost doubling of the City Secretary’s budget and a 76% increase in the Planning and Development department’s budget. On the other hand, the budget also sharply reduced the number of police officers.

While the City Council emphasized a small two-cent reduction in the property tax rate, the data presented showed that most taxpayers will actually pay more in city taxes due to rising property values.

In addition to higher property taxes, the city also increased water and sewer rates by 3% and trash rates by 3.5%. These hikes were approved despite ongoing service failures, which have left residents without water for days and with overflowing dumpsters.

Despite the nearly 10% increase in the budget, Councilperson Denise Swanner praised city staff for their hard work and lauded the value of the new zero-based budgeting process. However, there were several budgetary issues pointed out by citizens at the meeting. For example, the water and sewer fund’s revenues were budgeted to decrease by 1.7%, even though the council voted to raise water and sewer rates by 3%. Questions were raised about how revenues could decrease while rates were increasing.

Councilman Chris Hanie had a different perspective. He urged his fellow council members to drop the property tax rate to the “no new revenue” rate or lower, and to maintain current water, sewer, and trash rates. Hanie pointed out that the city will still be sitting on a surplus of over $272 million, equivalent to almost a full year of expenses. In a comment to Odessa Headlines, Councilman Hanie said, “I was really disappointed that Mayor Joven and the rest of the council showed so little concern for the difficulties our taxpayers are facing. With inflation, everyone is struggling to make ends meet, and we could have easily found some savings in our budget or used some of the $123 million general fund balance the city currently holds. I really wanted to hold the line and help our taxpayers, but I couldn’t get any support from City Manager Beckmeyer, Mayor Joven, or the other council members.”

Councilman Hanie Holds The Line is a story from Odessa Headlines, a publication covering Ector County, Texas. Odessa Headlines’ vision is to provide quality in-depth original coverage and commentary of local issues – predominantly politics and public policy – while cross-sharing excellent coverage of state and national issues from our media partners across Texas.

]]>
What Happened And Why? https://odessaheadlines.com/2023/01/03/what-happened-and-why/ Tue, 03 Jan 2023 15:34:18 +0000 https://odessaheadlines.com/?p=1925 Social media and local media outlets have been buzzing over the termination of appointed positions within the City of Odessa. During the December 13, 2022, Odessa City Council Meeting the Council brought forth an agenda item regarding the employment of then City Manager Michael Marrero, and City Attorney Natasha Brooks.  Theories regarding the terminations and […]

What Happened And Why? is a story from Odessa Headlines, a publication covering Ector County, Texas. Odessa Headlines’ vision is to provide quality in-depth original coverage and commentary of local issues – predominantly politics and public policy – while cross-sharing excellent coverage of state and national issues from our media partners across Texas.

]]>
Social media and local media outlets have been buzzing over the termination of appointed positions within the City of Odessa. During the December 13, 2022, Odessa City Council Meeting the Council brought forth an agenda item regarding the employment of then City Manager Michael Marrero, and City Attorney Natasha Brooks.  Theories regarding the terminations and subsequent lawsuit filed by local divorce and family law attorney Gavin Norris abound.

Here’s what we know:

APPOINTMENT TERMINATIONS

The action taken by City Council terminated the appointment of the sitting city manager and city attorney, and by definition were not firings. While the end result of the City Council’s actions is that Marrero and Brooks are no longer on the city payroll, the distinction between the terminations and firing is important.

There are a very limited number of city positions the Odessa City Council has direct control over and these include City Manager, City Attorney, City Secretary, and Municipal Court judges. All other city positions report directly or indirectly to the City Manager. 

It is fair to compare these Council controlled positions to the cabinet positions that are appointed by the President. Typically, upon election new presidents terminate the appointments of cabinet members like Secretary of State, Secretary of Commerce, etc. because it is unlikely those that served under the former president will have the same priorities, objectives and mindset as the newly elected president. Because the City of Odessa has a strong City Manager/weak City Council structure it is imperative that Council appointees are aligned with the agenda of the City Council and are willing to effectively execute the programs, plans, and agenda of City Council. If not, the elected officials of the City Council will be hamstrung and unable to carry forward the will of the voters by whom they were elected.

With the overwhelming election of Mayor Joven and Councilmembers Matta and Swanner over rival incumbents in December of 2020 Odessa voters clearly indicated that change from the previous Council was desired. However, a voting block of four Councilmembers – White, Willis, Sprawls, and Thompson – worked in lockstep with the current city administration – most notably City Manager Marrero and City Attorney Brooks – to maintain the status quo.

Two primary agenda items illustrate the contention between the newly elected members and existing city administration: removing game rooms from Odessa and increasing first responder pay to competitive levels.

GAME ROOMS

During the 2020 election Joven, Matta, and Swanner vowed to rid Odessa of the illegal game rooms which seemed to occupy every empty building in the city. Police records show local game rooms had become hotbeds of illegal activity including illegal gambling through the payout of cash prizes in excess of the $5.00 “fuzzy animal” limit, drug dealing, and appeared to have ties to human trafficking and other crimes.

Post-election Joven, Matta, and Swanner joined in efforts to either seriously curtail game room activities and their proliferation or possibly rid the city entirely through the enactment of new city ordinances. Despite a recently decided case by the Texas Second Court of Appeals out of Ft. Worth, which held that game room gambling violated the Texas Constitution, both Marrero and Brooks worked to stymie the City Council’s ordinance efforts citing a number of unfounded reasons why the city couldn’t simply shut down or restrict game rooms. Attorney Brooks often fell back on provisions in the Texas Occupational Code which had been deemed by the Court not to apply to game room activities. Marrero’s motivation appeared to be the continued collection of game room license fees which had steadily risen to almost $750,000 per year with many of the city’s 32 game rooms paying in excess of $25,000 per year in fees.  To no avail Council repeatedly asked Marrero and Assistant City Manager Cindy Muncy for details on the payments received, where the fees were logged in the City’s accounts, and where the funds were spent inside the city.  Under current Texas law any game room fees collected could only be spent on game room regulation enforcement but no evidence was provided by Marrero or Muncy indicating how the collected fees were spent. 

EMERGENCY WORKER PAY INCREASES

Citing the loss of over 180 critical staff from Odessa Fire/Rescue (OFR) ranks during the past two years, Councilmember Swanner was joined by Councilmember Matta to investigate what could be done to stem the flow of personnel losses. Swanner and Matta met with Fire Chief Alvarez and City Manager Marrero to determine what the Odessa City Council could do to help OFR, but quickly discovered a disconnect between what they were told by Chief Alvarez and the OFR rank and file that reached out to them to discuss Odessa OFR’s lack of competitive pay and morale problems.

Swanner and Matta were told by OFR personnel that a salary study had been completed by CPS HR Consulting in 2019/2020 which showed Odessa was behind the ball in firefighter salaries and that they had been told by Alvarez and Marrero that these issues had been brought before the 2020 Council but that the Council had declined in offering recommended pay increases. According to Council agendas no such requests were presented to the Odessa City Council during 2020 or 2021.

Relying on her own research, Swanner began to aggressively push for increased wages but was repeatedly rebuffed by Marrero and a voting block of four – Thompson, White, Willis, and Sprawls – who claimed the city couldn’t afford to increase emergency worker salaries and cited the need to complete a newly ordered salary study from Evergreen Solutions before moving forward with any raises.  Frustrated by the continued missed deadlines to complete the study and citing the need to move forward as OFR was losing additional personnel monthly and was currently seriously understaffed, Swanner and Matta placed increasing OFR salaries on Council’s agenda on several occasions.

Swanner proposed using unspent American Rescue Act (ARPA)/COVID relief funds issued by the federal government during the COVID crisis to pay for the raises but was told by Thompson, Marrero and Brooks ARPA funds couldn’t be used for emergency worker salaries despite the ARPA guidelines clearly stating that funds can be used for such wages and the fact that many communities across Texas such as Houston had successfully used ARPA funds for emergency worker salaries.  

It was only with the seating of new council members Hanie and Connell that raises were approved for all emergency workers at the December 13, 2022 City Council meeting.

HR MATTERS

The December 13, 2022 City Council agenda listed the following agenda items:

As noted on the agenda, the City Council planned on an open session to discuss the appointment terminations; however, as this agenda item was announced Marrero immediately announced that under the terms of his and Brooks’ contracts that they would be exercising their contractual right to hold any discussions in executive session behind closed doors. The Council adjourned to executive session as demanded by Marrero and Brooks and returned shortly to take action on the listed agenda items.

Upon the Council’s return several agitators in attendance began to shout and overtalk Mayor Joven and the meeting threatened to get out of hand.  After repeatedly threatening to wield his gavel to return order to the meeting, Council was finally able to move forward with the posted agenda.

After the meeting concluded Mayor Joven gave a short statement to local press stating that it was the Council’s belief, as evidenced by the actions they had just taken, that Odessa needed to move in a new direction with new administrative leadership and this was the cause for the termination of appointments.

Many media and social reporters have continued to question why Mayor Joven or other City Council members haven’t offered additional comment on the terminations, but employment laws, the contracts of Marrero and Brooks, and the Norris lawsuit have prohibited further comment.

Changes within government administrations are not uncommon as many Councils have found it necessary to replace key positions to advance their vision for the city to which they were elected to serve.  Locally, in the past few years both the Alpine and Pecos City Councils have completed the replacement of their City Manager and City Attorney and both cities seem to now be moving forward smoothly.  

Since election, Joven, Swanner, and Matta have expressed their desire to focus the City of Odessa government on providing quality infrastructure such as roads, water, and sewer, and to ensure that public safety departments are adequately staffed and funded to provide for public safety.  During their campaigns newly elected council members Connell and Hanie voiced support for these efforts and, based on their most recent actions, Council seems serious about fulfilling these initiatives.

Odessa Headlines will continue to follow this story.

What Happened And Why? is a story from Odessa Headlines, a publication covering Ector County, Texas. Odessa Headlines’ vision is to provide quality in-depth original coverage and commentary of local issues – predominantly politics and public policy – while cross-sharing excellent coverage of state and national issues from our media partners across Texas.

]]>
Odessa City Council to See Major Changes with Upcoming Election https://odessaheadlines.com/2022/08/23/odessa-city-council-to-see-major-changes-with-upcoming-election/ Tue, 23 Aug 2022 15:08:43 +0000 https://odessaheadlines.com/?p=1708 With the closing of the filing period for Odessa City Council candidates on Monday, candidates for two different districts are guaranteed to replace their outgoing city council incumbents, having entered their races unopposed, leaving only one contested race on the ballot in November. Outgoing District 4 Councilman Tom Sprawls will be succeeded by Greg Connell, […]

Odessa City Council to See Major Changes with Upcoming Election is a story from Odessa Headlines, a publication covering Ector County, Texas. Odessa Headlines’ vision is to provide quality in-depth original coverage and commentary of local issues – predominantly politics and public policy – while cross-sharing excellent coverage of state and national issues from our media partners across Texas.

]]>
With the closing of the filing period for Odessa City Council candidates on Monday, candidates for two different districts are guaranteed to replace their outgoing city council incumbents, having entered their races unopposed, leaving only one contested race on the ballot in November.

Outgoing District 4 Councilman Tom Sprawls will be succeeded by Greg Connell, who will win the race by default since no other candidates filed.

Connell, age 67, carries support from local Republican leaders for the spot – is a veteran and self-described conservative Republican whose campaign platform includes pro-family and pro-law enforcement themes. Connell is also a veteran of the United States Marine Corps.

Outgoing Councilwoman in District 3 Detra White will be succeeded by Gilbert Vasquez, who also won his election unopposed, with no other candidates filing for the spot.

The only contested race will be for District 5, the seat currently held by outgoing Councilwoman Mari Willis.

Shaye Lane, a local associate pastor, will face Christopher Hanie, who works for a local industrial service company for the spot.

Ector County Republican Party Chair Tisha Crow told Odessa Headlines while she believes contested elections are best to allow voters to have options, she was happy for Connell to win with strong unopposed support and said voters will have some good candidates to choose from in the district 5 race.

“Councilman-elect Connell’s victory is a historic win for Republicans in Odessa,” Crow stated, for the first time I can recall, Odessa will be represented by a new city council majority comprised of conservative God-fearing Republican patriots, and I am excited to see this new era of conservative leadership.”

Voters in district 5 will select their new council-member in the upcoming November 8, General Election.

Once elected, the new council members will assume office on a tentative date of November 22.

Odessa City Council to See Major Changes with Upcoming Election is a story from Odessa Headlines, a publication covering Ector County, Texas. Odessa Headlines’ vision is to provide quality in-depth original coverage and commentary of local issues – predominantly politics and public policy – while cross-sharing excellent coverage of state and national issues from our media partners across Texas.

]]>