コード例 #1
1
 /**
  * Save properties specific to this order item.
  * @return int Item ID
  */
 public function save()
 {
     parent::save();
     if ($this->get_id()) {
         wc_update_order_item_meta($this->get_id(), '_tax_class', $this->get_tax_class());
         wc_update_order_item_meta($this->get_id(), '_tax_status', $this->get_tax_status());
         wc_update_order_item_meta($this->get_id(), '_line_total', $this->get_total());
         wc_update_order_item_meta($this->get_id(), '_line_tax', $this->get_total_tax());
         wc_update_order_item_meta($this->get_id(), '_line_tax_data', $this->get_taxes());
     }
     return $this->get_id();
 }
 /**
  * Saves an item's data to the database / item meta.
  * Ran after both create and update, so $item->get_id() will be set.
  *
  * @since 2.7.0
  * @param WC_Order_Item $item
  */
 public function save_item_data(&$item)
 {
     wc_update_order_item_meta($item->get_id(), 'method_id', $item->get_method_id('edit'));
     wc_update_order_item_meta($item->get_id(), 'cost', $item->get_total('edit'));
     wc_update_order_item_meta($item->get_id(), 'total_tax', $item->get_total_tax('edit'));
     wc_update_order_item_meta($item->get_id(), 'taxes', $item->get_taxes('edit'));
 }
コード例 #3
0
 /**
  * @param $links
  * @param $item_id
  */
 function add_downloadlinks($links, $item_id)
 {
     if (is_array($links)) {
         // add generated downloadlinks to item
         wc_update_order_item_meta($item_id, '_bx_downloadlinks', $links);
     }
 }
コード例 #4
0
 /**
  * Saves an item's data to the database / item meta.
  * Ran after both create and update, so $item->get_id() will be set.
  *
  * @since 2.7.0
  * @param WC_Order_Item $item
  */
 public function save_item_data(&$item)
 {
     wc_update_order_item_meta($item->get_id(), '_tax_class', $item->get_tax_class('edit'));
     wc_update_order_item_meta($item->get_id(), '_tax_status', $item->get_tax_status('edit'));
     wc_update_order_item_meta($item->get_id(), '_line_total', $item->get_total('edit'));
     wc_update_order_item_meta($item->get_id(), '_line_tax', $item->get_total_tax('edit'));
     wc_update_order_item_meta($item->get_id(), '_line_tax_data', $item->get_taxes('edit'));
 }
コード例 #5
0
 /**
  * Saves an item's data to the database / item meta.
  * Ran after both create and update, so $item->get_id() will be set.
  *
  * @since 2.7.0
  * @param WC_Order_Item $item
  */
 public function save_item_data(&$item)
 {
     wc_update_order_item_meta($item->get_id(), 'rate_id', $item->get_rate_id('edit'));
     wc_update_order_item_meta($item->get_id(), 'label', $item->get_label('edit'));
     wc_update_order_item_meta($item->get_id(), 'compound', $item->get_compound('edit'));
     wc_update_order_item_meta($item->get_id(), 'tax_amount', $item->get_tax_total('edit'));
     wc_update_order_item_meta($item->get_id(), 'shipping_tax_amount', $item->get_shipping_tax_total('edit'));
 }
コード例 #6
0
 /**
  * Save properties specific to this order item.
  * @return int Item ID
  */
 public function save()
 {
     parent::save();
     if ($this->get_id()) {
         wc_update_order_item_meta($this->get_id(), 'discount_amount', $this->get_discount());
         wc_update_order_item_meta($this->get_id(), 'discount_amount_tax', $this->get_discount_tax());
     }
     return $this->get_id();
 }
コード例 #7
0
 /**
  * Save properties specific to this order item.
  * @return int Item ID
  */
 public function save()
 {
     parent::save();
     if ($this->get_id()) {
         wc_update_order_item_meta($this->get_id(), 'method_id', $this->get_method_id());
         wc_update_order_item_meta($this->get_id(), 'cost', $this->get_total());
         wc_update_order_item_meta($this->get_id(), 'total_tax', $this->get_total_tax());
         wc_update_order_item_meta($this->get_id(), 'taxes', $this->get_taxes());
     }
     return $this->get_id();
 }
コード例 #8
0
 /**
  * Saves an item's data to the database / item meta.
  * Ran after both create and update, so $item->get_id() will be set.
  *
  * @since 2.7.0
  * @param WC_Order_Item $item
  */
 public function save_item_data(&$item)
 {
     wc_update_order_item_meta($item->get_id(), '_product_id', $item->get_product_id('edit'));
     wc_update_order_item_meta($item->get_id(), '_variation_id', $item->get_variation_id('edit'));
     wc_update_order_item_meta($item->get_id(), '_qty', $item->get_quantity('edit'));
     wc_update_order_item_meta($item->get_id(), '_tax_class', $item->get_tax_class('edit'));
     wc_update_order_item_meta($item->get_id(), '_line_subtotal', $item->get_subtotal('edit'));
     wc_update_order_item_meta($item->get_id(), '_line_subtotal_tax', $item->get_subtotal_tax('edit'));
     wc_update_order_item_meta($item->get_id(), '_line_total', $item->get_total('edit'));
     wc_update_order_item_meta($item->get_id(), '_line_tax', $item->get_total_tax('edit'));
     wc_update_order_item_meta($item->get_id(), '_line_tax_data', $item->get_taxes('edit'));
 }
コード例 #9
0
 /**
  * Save properties specific to this order item.
  * @return int Item ID
  */
 public function save()
 {
     parent::save();
     if ($this->get_id()) {
         wc_update_order_item_meta($this->get_id(), 'rate_id', $this->get_rate_id());
         wc_update_order_item_meta($this->get_id(), 'label', $this->get_label());
         wc_update_order_item_meta($this->get_id(), 'compound', $this->get_compound());
         wc_update_order_item_meta($this->get_id(), 'tax_amount', $this->get_tax_total());
         wc_update_order_item_meta($this->get_id(), 'shipping_tax_amount', $this->get_shipping_tax_total());
     }
     return $this->get_id();
 }
コード例 #10
0
 /**
  * Apply shipping tax, fix order_tax
  * -
  * - filter has already passed $this->data['shipping_tax'] test
  * @param $null
  * @param $order_id
  * @param $meta_key
  * @param $meta_value
  * @param $prev_value
  * @return null
  */
 public function update_post_metadata($null, $order_id, $meta_key, $meta_value, $prev_value)
 {
     // we want last update to _order_shipping after $order->calculate_taxes()
     // set flag true on first pass
     if ($meta_key == '_order_shipping_tax') {
         $this->flag = true;
     }
     if ($meta_key != '_order_shipping' || !$this->flag) {
         return $null;
     }
     // update order meta
     $shipping_tax_total = isset($this->data['shipping_tax']) ? $this->data['shipping_tax'] : 0;
     update_post_meta($order_id, '_order_shipping_tax', wc_format_decimal($shipping_tax_total));
     // check each shipping tax line
     // if order item meta already exists, update the shipping_tax_amount
     // if order item meta not present, add the new tax
     // ... nasty :(
     // first get an assoc array of $rate_id => $item_id
     $tax_items = array();
     $order_tax = 0;
     $order = wc_get_order($order_id);
     foreach ($order->get_tax_totals() as $code => $tax) {
         $tax_items[$tax->rate_id] = $tax->id;
         $order_tax += $tax->amount;
     }
     // fix total_tax calc
     update_post_meta($order_id, '_order_tax', $order_tax);
     // now loop through the shipping_lines
     if (isset($shipping['shipping_lines'])) {
         foreach ($this->data['shipping_lines'] as $shipping) {
             if (isset($shipping['tax'])) {
                 foreach ($shipping['tax'] as $rate_id => $tax) {
                     if (isset($tax['total'])) {
                         if (array_key_exists($rate_id, $tax_items)) {
                             wc_update_order_item_meta($tax_items[$rate_id], 'shipping_tax_amount', wc_format_decimal($tax['total']));
                         } else {
                             $order->add_tax($rate_id, 0, $tax['total']);
                         }
                     }
                 }
             }
         }
     }
     return $null;
 }
コード例 #11
0
 /**
  * Save properties specific to this order item.
  * @return int Item ID
  */
 public function save()
 {
     parent::save();
     if ($this->get_id()) {
         wc_update_order_item_meta($this->get_id(), '_product_id', $this->get_product_id());
         wc_update_order_item_meta($this->get_id(), '_variation_id', $this->get_variation_id());
         wc_update_order_item_meta($this->get_id(), '_qty', $this->get_quantity());
         wc_update_order_item_meta($this->get_id(), '_tax_class', $this->get_tax_class());
         wc_update_order_item_meta($this->get_id(), '_line_subtotal', $this->get_subtotal());
         wc_update_order_item_meta($this->get_id(), '_line_subtotal_tax', $this->get_subtotal_tax());
         wc_update_order_item_meta($this->get_id(), '_line_total', $this->get_total());
         wc_update_order_item_meta($this->get_id(), '_line_tax', $this->get_total_tax());
         wc_update_order_item_meta($this->get_id(), '_line_tax_data', $this->get_taxes());
     }
     return $this->get_id();
 }
コード例 #12
0
 /**
  * Saves an item's data to the database / item meta.
  * Ran after both create and update, so $item->get_id() will be set.
  *
  * @since 2.7.0
  * @param WC_Order_Item $item
  */
 public function save_item_data(&$item)
 {
     wc_update_order_item_meta($item->get_id(), 'discount_amount', $item->get_discount('edit'));
     wc_update_order_item_meta($item->get_id(), 'discount_amount_tax', $item->get_discount_tax('edit'));
 }
 /**
  * Perform data update
  *
  * @return JSON object with information about number of posts remaining, current update status
  */
 public static function update_post_data()
 {
     global $wpdb;
     // Number of posts to process at once
     $posts_per_page = 10;
     // Index of last processed post
     $last_post = $_POST['last_post'];
     // Page counters
     $total_pages = $last_post == 0 ? 0 : $_POST['total_pages'];
     $current_page = $last_post == 0 ? 1 : $_POST['current_page'];
     // On first run, determine $total_count/$total_pages
     if ($last_post == 0) {
         $total_count = $wpdb->get_var("SELECT COUNT(ID) FROM {$wpdb->posts} WHERE post_type = 'wootax_order'");
         if ($total_count == 0) {
             update_option('wootax_version', WT_VERSION);
             self::dismiss_update_message();
             die(json_encode(array('status' => 'done', 'message' => 'No more posts to update. Redirecting...', 'redirect' => get_admin_url('plugins.php'))));
         }
         $total_pages = ceil($total_count / $posts_per_page);
     }
     // Select posts from index $last_post to $posts_per_page for processing
     $posts = $wpdb->get_results("SELECT p.ID AS WTID, pm.meta_value AS WCID FROM {$wpdb->posts} p LEFT JOIN {$wpdb->postmeta} pm ON pm.post_id = p.ID WHERE p.post_type = 'wootax_order' AND pm.meta_key = '_wootax_wc_order_id' ORDER BY p.ID ASC LIMIT {$last_post}, {$posts_per_page}");
     if (count($posts) == 0) {
         update_option('wootax_version', WT_VERSION);
         self::dismiss_update_message();
         self::remove_order_posts();
         die(json_encode(array('status' => 'done', 'message' => 'No more posts to update. Redirecting...', 'redirect' => get_admin_url('plugins.php'))));
     }
     // Loop through posts and update
     foreach ($posts as $post) {
         $wt_order_id = $post->WTID;
         $wc_order_id = $post->WCID;
         // Transfer meta that doesn't need to be changed
         $direct_meta_keys = array('tax_total', 'shipping_tax_total', 'captured', 'refunded', 'customer_id', 'tax_item_id', 'exemption_applied');
         foreach ($direct_meta_keys as $key) {
             update_post_meta($wc_order_id, '_wootax_' . $key, get_post_meta($wt_order_id, '_wootax_' . $key, true));
         }
         // WooTax order item meta and mapping array structure was changed drastically in 4.2; update accordingly
         $lookup_data = get_post_meta($wt_order_id, '_wootax_lookup_data', true);
         $cart_taxes = get_post_meta($wt_order_id, '_wootax_cart_taxes', true);
         $new_mapping_array = array();
         $new_tc_ids = array();
         $identifiers = array();
         if (is_array($lookup_data)) {
             $wc_order = new WC_Order($wc_order_id);
             $order_items = $wc_order->get_items();
             $order_fees = $wc_order->get_fees();
             foreach ($lookup_data as $location_key => $items) {
                 if (!isset($new_mapping_array[$location_key])) {
                     $new_mapping_array[$location_key] = array();
                 }
                 foreach ($items as $index => $item) {
                     if (!is_array($item)) {
                         continue;
                     }
                     $tax_amount = isset($cart_taxes[$location_key][$index]) ? $cart_taxes[$location_key][$index] : 0;
                     $item_ident = $item['ItemID'];
                     if ($item_ident == 99999) {
                         $shipping_item_id = -1;
                         // Shipping
                         if (version_compare(WOOCOMMERCE_VERSION, '2.2', '<')) {
                             $shipping_item_id = WT_SHIPPING_ITEM;
                             update_post_meta($wc_order_id, '_wootax_first_found', $location_key);
                             update_post_meta($wc_order_id, '_wootax_shipping_index', $index);
                         } else {
                             $shipping_methods = $wc_order->get_items('shipping');
                             foreach ($shipping_methods as $item_id => $method) {
                                 if ($shipping_item_id == -1) {
                                     $shipping_item_id = $item_id;
                                     wc_update_order_item_meta($item_id, '_wootax_index', $index);
                                     wc_update_order_item_meta($item_id, '_wootax_tax_amount', $tax_amount);
                                     wc_update_order_item_meta($item_id, '_wootax_location_id', $location_key);
                                 }
                             }
                         }
                         if ($shipping_item_id != -1) {
                             $new_mapping_array[$location_key][$item_ident] = $index;
                             $identifiers[WT_SHIPPING_ITEM] = $item_ident;
                         }
                     } else {
                         if (in_array(get_post_type($item_ident), array('product', 'product-variation'))) {
                             // Cart item
                             $cart_item_id = -1;
                             if (get_post_type($item_ident) == 'product') {
                                 $product_id = $item_ident;
                                 $variation_id = '';
                             } else {
                                 if (get_post_type($item_ident) == 'product-variation') {
                                     $variation_id = $item_ident;
                                     $product_id = wp_get_post_parent_id($variation_id);
                                 }
                             }
                             foreach ($order_items as $item_id => $item_data) {
                                 if (!empty($item_data['variation_id']) && $item_data['variation_id'] == $variation_id || $item_data['product_id'] == $product_id) {
                                     $cart_item_id = $item_id;
                                     break;
                                 }
                             }
                             if ($cart_item_id != -1) {
                                 wc_update_order_item_meta($cart_item_id, '_wootax_index', $index);
                                 wc_update_order_item_meta($cart_item_id, '_wootax_tax_amount', $tax_amount);
                                 wc_update_order_item_meta($cart_item_id, '_wootax_location_id', $location_key);
                                 $new_mapping_array[$location_key][$item_ident] = $index;
                                 $identifiers[$item_ident] = $item_ident;
                             }
                         } else {
                             // Fee
                             $fee_id = -1;
                             foreach ($order_fees as $item_id => $item_data) {
                                 if (sanitize_title($item_data['name']) == $item_ident) {
                                     $fee_id = $item_id;
                                 }
                             }
                             if ($fee_id != -1) {
                                 wc_update_order_item_meta($fee_id, '_wootax_index', $index);
                                 wc_update_order_item_meta($fee_id, '_wootax_tax_amount', $tax_amount);
                                 wc_update_order_item_meta($fee_id, '_wootax_location_id', $location_key);
                                 $new_mapping_array[$location_key][$item_ident] = $index;
                                 $identifiers[$item_ident] = $item_ident;
                             }
                         }
                     }
                 }
             }
         }
         // Update TaxCloud Ids
         $new_tc_ids[$location_key]['cart_id'] = $items['cart_id'];
         $new_tc_ids[$location_key]['order_id'] = $items['order_id'];
         update_post_meta($wc_order_id, '_wootax_taxcloud_ids', $new_tc_ids);
         // Update mapping array
         update_post_meta($wc_order_id, '_wootax_mapping_array', $new_mapping_array);
         // Update item identifiers
         update_post_meta($wc_order_id, '_wootax_identifiers', $identifiers);
     }
     // Notify client that processing has succeeded and continue processing
     if ($current_page < $total_pages) {
         $last_post += $posts_per_page;
         $current_page++;
     } else {
         $last_post += count($posts);
     }
     die(json_encode(array('status' => 'working', 'last_post' => $last_post, 'current_page' => $current_page, 'total_pages' => $total_pages)));
 }
コード例 #14
0
 /**
  * Function to Restore Smart Coupon Amount back, when an order which was created using this coupon, is refunded or cancelled, 
  *
  * @param int $order_id
  */
 public function sa_restore_smart_coupon_amount($order_id = 0)
 {
     if (empty($order_id)) {
         return;
     }
     $order = $this->get_order($order_id);
     $coupons = $order->get_items('coupon');
     if (!empty($coupons)) {
         foreach ($coupons as $item_id => $item) {
             if (empty($item['name'])) {
                 continue;
             }
             $coupon = new WC_Coupon($item['name']);
             if (empty($coupon->discount_type) || $coupon->discount_type != 'smart_coupon') {
                 continue;
             }
             $update = false;
             $coupon_amount = $coupon->coupon_amount;
             $usage_count = $coupon->usage_count;
             if (!empty($item['discount_amount'])) {
                 $coupon_amount += $item['discount_amount'];
                 $usage_count -= 1;
                 if ($usage_count < 0) {
                     $usage_count = 0;
                 }
                 $update = true;
             }
             if ($update) {
                 update_post_meta($coupon->id, 'coupon_amount', $coupon_amount);
                 update_post_meta($coupon->id, 'usage_count', $usage_count);
                 wc_update_order_item_meta($item_id, 'discount_amount', 0);
             }
         }
     }
 }
 /**
  * Triggered when adding an item in the backend.
  *
  * If deposits are forced, set all meta data.
  */
 public function ajax_add_order_item_meta($item_id, $item)
 {
     if (WC_Deposits_Product_Manager::deposits_forced($item['product_id'])) {
         $product = wc_get_product(absint($item['variation_id'] ? $item['variation_id'] : $item['product_id']));
         woocommerce_add_order_item_meta($item_id, '_is_deposit', 'yes');
         woocommerce_add_order_item_meta($item_id, '_deposit_full_amount', $item['line_total']);
         woocommerce_add_order_item_meta($item_id, '_deposit_full_amount_ex_tax', $item['line_total']);
         if ('plan' === WC_Deposits_Product_Manager::get_deposit_type($item['product_id'])) {
             $plan_id = current(WC_Deposits_Plans_Manager::get_plan_ids_for_product($item['product_id']));
             woocommerce_add_order_item_meta($item_id, '_payment_plan', $plan_id);
         } else {
             $plan_id = 0;
         }
         // Change line item costs
         $deposit_amount = WC_Deposits_Product_Manager::get_deposit_amount($product, $plan_id, 'order', $item['line_total']);
         wc_update_order_item_meta($item_id, '_line_total', $deposit_amount);
         wc_update_order_item_meta($item_id, '_line_subtotal', $deposit_amount);
     }
 }
コード例 #16
0
/**
 * @deprecated
 */
function woocommerce_update_order_item_meta($item_id, $meta_key, $meta_value, $prev_value = '')
{
    return wc_update_order_item_meta($item_id, $meta_key, $meta_value, $prev_value);
}
コード例 #17
0
 /**
  * Calculate taxes for all line items and shipping, and store the totals and tax rows.
  *
  * Will use the base country unless customer addresses are set.
  *
  * @return bool success or fail.
  */
 public function calculate_taxes()
 {
     $tax_total = 0;
     $shipping_tax_total = 0;
     $taxes = array();
     $shipping_taxes = array();
     $tax_based_on = get_option('woocommerce_tax_based_on');
     // If is_vat_exempt is 'yes', or wc_tax_enabled is false, return and do nothing.
     if ('yes' === $this->is_vat_exempt || !wc_tax_enabled()) {
         return false;
     }
     if ('billing' === $tax_based_on) {
         $country = $this->billing_country;
         $state = $this->billing_state;
         $postcode = $this->billing_postcode;
         $city = $this->billing_city;
     } elseif ('shipping' === $tax_based_on) {
         $country = $this->shipping_country;
         $state = $this->shipping_state;
         $postcode = $this->shipping_postcode;
         $city = $this->shipping_city;
     }
     // Default to base
     if ('base' === $tax_based_on || empty($country)) {
         $default = wc_get_base_location();
         $country = $default['country'];
         $state = $default['state'];
         $postcode = '';
         $city = '';
     }
     // Get items
     foreach ($this->get_items(array('line_item', 'fee')) as $item_id => $item) {
         $product = $this->get_product_from_item($item);
         $line_total = isset($item['line_total']) ? $item['line_total'] : 0;
         $line_subtotal = isset($item['line_subtotal']) ? $item['line_subtotal'] : 0;
         $tax_class = $item['tax_class'];
         $item_tax_status = $product ? $product->get_tax_status() : 'taxable';
         if ('0' !== $tax_class && 'taxable' === $item_tax_status) {
             $tax_rates = WC_Tax::find_rates(array('country' => $country, 'state' => $state, 'postcode' => $postcode, 'city' => $city, 'tax_class' => $tax_class));
             $line_subtotal_taxes = WC_Tax::calc_tax($line_subtotal, $tax_rates, false);
             $line_taxes = WC_Tax::calc_tax($line_total, $tax_rates, false);
             $line_subtotal_tax = max(0, array_sum($line_subtotal_taxes));
             $line_tax = max(0, array_sum($line_taxes));
             $tax_total += $line_tax;
             wc_update_order_item_meta($item_id, '_line_subtotal_tax', wc_format_decimal($line_subtotal_tax));
             wc_update_order_item_meta($item_id, '_line_tax', wc_format_decimal($line_tax));
             wc_update_order_item_meta($item_id, '_line_tax_data', array('total' => $line_taxes, 'subtotal' => $line_subtotal_taxes));
             // Sum the item taxes
             foreach (array_keys($taxes + $line_taxes) as $key) {
                 $taxes[$key] = (isset($line_taxes[$key]) ? $line_taxes[$key] : 0) + (isset($taxes[$key]) ? $taxes[$key] : 0);
             }
         }
     }
     // Calc taxes for shipping
     foreach ($this->get_shipping_methods() as $item_id => $item) {
         $shipping_tax_class = get_option('woocommerce_shipping_tax_class');
         // Inherit tax class from items
         if ('' === $shipping_tax_class) {
             $tax_classes = WC_Tax::get_tax_classes();
             foreach ($tax_classes as $tax_class) {
                 $tax_class = sanitize_title($tax_class);
                 if (in_array($tax_class, $found_tax_classes)) {
                     $tax_rates = WC_Tax::find_shipping_rates(array('country' => $country, 'state' => $state, 'postcode' => $postcode, 'city' => $city, 'tax_class' => $tax_class));
                     break;
                 }
             }
         } else {
             $tax_rates = WC_Tax::find_shipping_rates(array('country' => $country, 'state' => $state, 'postcode' => $postcode, 'city' => $city, 'tax_class' => 'standard' === $shipping_tax_class ? '' : $shipping_tax_class));
         }
         $line_taxes = WC_Tax::calc_tax($item['cost'], $tax_rates, false);
         $line_tax = max(0, array_sum($line_taxes));
         $shipping_tax_total += $line_tax;
         wc_update_order_item_meta($item_id, '_line_tax', wc_format_decimal($line_tax));
         wc_update_order_item_meta($item_id, '_line_tax_data', array('total' => $line_taxes));
         // Sum the item taxes
         foreach (array_keys($shipping_taxes + $line_taxes) as $key) {
             $shipping_taxes[$key] = (isset($line_taxes[$key]) ? $line_taxes[$key] : 0) + (isset($shipping_taxes[$key]) ? $shipping_taxes[$key] : 0);
         }
     }
     // Save tax totals
     $this->set_total($shipping_tax_total, 'shipping_tax');
     $this->set_total($tax_total, 'tax');
     // Tax rows
     $this->remove_order_items('tax');
     // Now merge to keep tax rows
     foreach (array_keys($taxes + $shipping_taxes) as $tax_rate_id) {
         $this->add_tax($tax_rate_id, isset($taxes[$tax_rate_id]) ? $taxes[$tax_rate_id] : 0, isset($shipping_taxes[$tax_rate_id]) ? $shipping_taxes[$tax_rate_id] : 0);
     }
     return true;
 }
 /**
  * @param array $shipping_items Order items to save
  */
 public function admin_update_pickup_point($shipping_items)
 {
     $shipping_methods = $shipping_items['shipping_method'];
     if ($shipping_methods) {
         foreach ($shipping_methods as $item_id => $shipping_method) {
             if (strpos($shipping_method, Fraktguiden_Helper::ID) !== false) {
                 $pickup_point_id = $shipping_items['_fraktguiden_pickup_point_id'][$item_id];
                 $packages = $shipping_items['_fraktguiden_packages'][$item_id];
                 if ($packages) {
                     wc_update_order_item_meta($item_id, '_fraktguiden_packages', json_decode(stripslashes($packages), true));
                 }
                 if (!empty($pickup_point_id)) {
                     $pickup_point_postcode = $shipping_items['_fraktguiden_pickup_point_postcode'][$item_id];
                     $pickup_point_info = $shipping_items['_fraktguiden_pickup_point_info_cached'][$item_id];
                     wc_update_order_item_meta($item_id, '_fraktguiden_pickup_point_id', $pickup_point_id);
                     wc_update_order_item_meta($item_id, '_fraktguiden_pickup_point_postcode', $pickup_point_postcode);
                     wc_update_order_item_meta($item_id, '_fraktguiden_pickup_point_info_cached', $pickup_point_info);
                 } else {
                     wc_delete_order_item_meta($item_id, '_fraktguiden_pickup_point_postcode');
                     wc_delete_order_item_meta($item_id, '_fraktguiden_pickup_point_id');
                     wc_delete_order_item_meta($item_id, '_fraktguiden_pickup_point_info_cached');
                 }
             } else {
                 wc_delete_order_item_meta($item_id, '_fraktguiden_pickup_point_postcode');
                 wc_delete_order_item_meta($item_id, '_fraktguiden_pickup_point_id');
                 wc_delete_order_item_meta($item_id, '_fraktguiden_pickup_point_info_cached');
             }
         }
     }
 }
コード例 #19
0
ファイル: ce_shop.php プロジェクト: linniepinski/perssistant
 function handle_sell_order_update($order, $postData)
 {
     global $user_ID;
     if (count($postData) > 0) {
         if ($order->has_status('completed')) {
             _e("This order is completed, you can not edit it.", ET_DOMAIN);
         } elseif (!isset($_POST['ce_update_order_nonce']) || !wp_verify_nonce($_POST['ce_update_order_nonce'], 'ce_update_order_nonce')) {
             _e('Sorry, your nonce did not verify.', ET_DOMAIN);
         } else {
             foreach ($postData['status'] as $item_id => $status) {
                 $result = wc_update_order_item_meta($item_id, 'status', $status);
             }
         }
     }
 }
コード例 #20
0
 public function meta_box_save($post_id)
 {
     if (!isset($_POST['wc_bookings_details_meta_box_nonce']) || !wp_verify_nonce($_POST['wc_bookings_details_meta_box_nonce'], 'wc_bookings_details_meta_box')) {
         return $post_id;
     }
     if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
         return $post_id;
     }
     if (!in_array($_POST['post_type'], $this->post_types)) {
         return $post_id;
     }
     global $wpdb, $post;
     // Save simple fields
     $booking_order_id = absint($_POST['_booking_order_id']);
     $booking_status = wc_clean($_POST['_booking_status']);
     $customer_id = absint($_POST['_booking_customer_id']);
     $product_id = wc_clean($_POST['product_or_resource_id']);
     $parent_id = absint($_POST['_booking_parent_id']);
     $all_day = isset($_POST['_booking_all_day']) ? '1' : '0';
     // Update post_parent and status via query to prevent endless loops
     $wpdb->update($wpdb->posts, array('post_parent' => $booking_order_id), array('ID' => $post_id));
     $wpdb->update($wpdb->posts, array('post_status' => $booking_status), array('ID' => $post_id));
     // Trigger actions manually
     $old_status = $post->post_status;
     do_action('woocommerce_booking_' . $booking_status, $post_id);
     do_action('woocommerce_booking_' . $old_status . '_to_' . $booking_status, $post_id);
     clean_post_cache($post_id);
     // Note in the order
     if ($booking_order_id && function_exists('wc_get_order') && ($order = wc_get_order($booking_order_id))) {
         $order->add_order_note(sprintf(__('Booking #%d status changed manually from "%s" to "%s', 'woocommerce-bookings'), $post_id, $old_status, $booking_status));
     }
     // Save product and resource
     if (strstr($product_id, '=>')) {
         list($product_id, $resource_id) = explode('=>', $product_id);
     } else {
         $resource_id = 0;
     }
     update_post_meta($post_id, '_booking_resource_id', $resource_id);
     update_post_meta($post_id, '_booking_product_id', $product_id);
     // Update meta
     update_post_meta($post_id, '_booking_customer_id', $customer_id);
     update_post_meta($post_id, '_booking_parent_id', $parent_id);
     update_post_meta($post_id, '_booking_all_day', $all_day);
     // Persons
     $saved_persons = get_post_meta($post_id, '_booking_persons', true);
     $product = wc_get_product($product_id);
     $person_types = $product->get_person_types();
     if (!empty($person_types) && is_array($person_types)) {
         $booking_persons = array();
         foreach ($person_types as $person_type) {
             if (!empty($_POST['_booking_person_' . $person_type->ID])) {
                 $booking_persons[$person_type->ID] = absint($_POST['_booking_person_' . $person_type->ID]);
             }
         }
         update_post_meta($post_id, '_booking_persons', $booking_persons);
     } else {
         if (empty($person_types) && !empty($saved_persons) && is_array($saved_persons)) {
             $booking_persons = array();
             foreach (array_keys($saved_persons) as $person_id) {
                 $booking_persons[$person_id] = absint($_POST['_booking_person_' . $person_id]);
             }
             update_post_meta($post_id, '_booking_persons', $booking_persons);
         }
     }
     // Update date
     if (empty($_POST['booking_date'])) {
         $date = current_time('timestamp');
     } else {
         $date = strtotime($_POST['booking_date'] . ' ' . (int) $_POST['booking_date_hour'] . ':' . (int) $_POST['booking_date_minute'] . ':00');
     }
     $date = date_i18n('Y-m-d H:i:s', $date);
     $wpdb->query($wpdb->prepare("UPDATE {$wpdb->posts} SET post_date = %s, post_date_gmt = %s WHERE ID = %s", $date, get_gmt_from_date($date), $post_id));
     // Do date and time magic and save them in one field
     $start_date = explode('-', wc_clean($_POST['booking_start_date']));
     $end_date = explode('-', wc_clean($_POST['booking_end_date']));
     $start_time = explode(':', wc_clean($_POST['booking_start_time']));
     $end_time = explode(':', wc_clean($_POST['booking_end_time']));
     $start = mktime($start_time[0], $start_time[1], 0, $start_date[1], $start_date[2], $start_date[0]);
     $end = mktime($end_time[0], $end_time[1], 0, $end_date[1], $end_date[2], $end_date[0]);
     update_post_meta($post_id, '_booking_start', date('YmdHis', $start));
     update_post_meta($post_id, '_booking_end', date('YmdHis', $end));
     if ($order && $booking_order_id) {
         // Update order metas
         foreach ($order->get_items() as $item_id => $item) {
             if ('line_item' != $item['type'] || !in_array($product_id, $item['item_meta']['_product_id'])) {
                 continue;
             }
             $product = wc_get_product($product_id);
             $is_all_day = isset($_POST['_booking_all_day']) && $_POST['_booking_all_day'] == 'yes';
             // Update date
             if (metadata_exists('order_item', $item_id, __('Booking Date', 'woocommerce-bookings'))) {
                 $date = mktime(0, 0, 0, $start_date[1], $start_date[2], $start_date[0]);
                 wc_update_order_item_meta($item_id, __('Booking Date', 'woocommerce-bookings'), date_i18n(wc_date_format(), $date));
             }
             // Update time
             if (!$is_all_day) {
                 if (metadata_exists('order_item', $item_id, __('Booking Time', 'woocommerce-bookings'))) {
                     $time = mktime($start_time[0], $start_time[1], 0, $start_date[1], $start_date[2], $start_date[0]);
                     wc_update_order_item_meta($item_id, __('Booking Time', 'woocommerce-bookings'), date_i18n(wc_time_format(), $time));
                 }
             }
             // Update resource
             if (metadata_exists('order_item', $item_id, __('Booking Type', 'woocommerce-bookings'))) {
                 $resource = wc_booking_get_product_resource($product_id, $resource_id);
                 wc_update_order_item_meta($item_id, __('Booking Type', 'woocommerce-bookings'), $resource->get_title());
             }
             // Update persons
             if ($product->has_persons()) {
                 if ($product->has_person_types()) {
                     $person_types = $product->get_person_types();
                     foreach ($person_types as $type) {
                         if (isset($_POST['_booking_person_' . $type->ID])) {
                             $persons = $_POST['_booking_person_' . $type->ID];
                             wc_update_order_item_meta($item_id, $type->post_title, $persons);
                         }
                     }
                 } else {
                     // The product does not use person types, the ID will be always 0 and the title "Persons"
                     if (metadata_exists('order_item', $item_id, __('Persons', 'woocommerce-bookings'))) {
                         $persons = $_POST['_booking_person_0'];
                         wc_update_order_item_meta($item_id, __('Persons', 'woocommerce-bookings'), $persons);
                     }
                 }
             }
             // Update duration
             if (metadata_exists('order_item', $item_id, __('Duration', 'woocommerce-bookings'))) {
                 $start_diff = wc_clean($_POST['booking_start_date']);
                 $end_diff = wc_clean($_POST['booking_end_date']);
                 if (!$is_all_day) {
                     $start_diff .= ' ' . wc_clean($_POST['booking_start_time']);
                     $end_diff .= ' ' . wc_clean($_POST['booking_end_time']);
                 }
                 $start = new DateTime($start_diff);
                 $end = new DateTime($end_diff);
                 // Add one day because DateTime::diff does not include the last day
                 if ($is_all_day) {
                     $end->modify('+1 day');
                 }
                 $diffs = $end->diff($start);
                 $duration = array();
                 foreach ($diffs as $type => $diff) {
                     if ($diff != 0) {
                         switch ($type) {
                             case 'y':
                                 $duration[] = _n('%y year', '%y years', $diff, 'woocommerce-bookings');
                                 break;
                             case 'm':
                                 $duration[] = _n('%m month', '%m months', $diff, 'woocommerce-bookings');
                                 break;
                             case 'd':
                                 $duration[] = _n('%d day', '%d days', $diff, 'woocommerce-bookings');
                                 break;
                             case 'h':
                                 $duration[] = _n('%h hour', '%h hours', $diff, 'woocommerce-bookings');
                                 break;
                             case 'i':
                                 $duration[] = _n('%i minute', '%i minutes', $diff, 'woocommerce-bookings');
                                 break;
                         }
                     }
                 }
                 $duration = implode(', ', $duration);
                 $duration = $diffs->format($duration);
                 wc_update_order_item_meta($item_id, __('Duration', 'woocommerce-bookings'), $duration);
             }
         }
     }
     WC_Cache_Helper::get_transient_version('bookings', true);
     do_action('woocommerce_booking_process_meta', $post_id);
 }
コード例 #21
0
 /**
  * Save order items ajax sync
  *
  * @author   Andrea Grillo <*****@*****.**>
  * @since    1.6
  * @return void
  * @access public static
  */
 public static function save_order_items()
 {
     check_ajax_referer('order-item', 'security');
     if (!current_user_can('edit_shop_orders')) {
         die(-1);
     }
     if (isset($_POST['order_id']) && isset($_POST['items'])) {
         $parent_order_id = absint($_POST['order_id']);
         //Check if order have sub-order
         if (!wp_get_post_parent_id($parent_order_id)) {
             global $wpdb;
             // Parse the jQuery serialized items
             $_post = $_POST;
             parse_str($_post['items'], $_post['items']);
             $suborder_ids = self::get_suborder($parent_order_id);
             foreach ($suborder_ids as $suborder_id) {
                 $order_total = 0;
                 $suborder = wc_get_order($suborder_id);
                 $child_items = array_keys($suborder->get_items());
                 $_post['items']['order_item_id'] = $child_items;
                 foreach ($child_items as $child_item_id) {
                     $parent_item_id = self::get_parent_item_id($suborder, $child_item_id);
                     foreach ($_post['items'] as $meta_key => $meta_value) {
                         if (!in_array($meta_key, array('order_item_id', '_order_total')) && isset($_post['items'][$meta_key][$parent_item_id])) {
                             $_post['items'][$meta_key][$child_item_id] = $_post['items'][$meta_key][$parent_item_id];
                             unset($_post['items'][$meta_key][$parent_item_id]);
                         }
                     }
                     /* === Calc Order Totals === */
                     if (!empty($_post['items']['line_total'][$child_item_id])) {
                         $order_total += wc_format_decimal($_post['items']['line_total'][$child_item_id]);
                         if (isset($_post['items']['line_tax'][$child_item_id])) {
                             $line_taxes = $_post['items']['line_tax'][$child_item_id];
                             foreach ($line_taxes as $line_tax) {
                                 $order_total += wc_format_decimal($line_tax);
                             }
                         }
                     }
                     /* === Calc Refund Totals === */
                     if (!empty($_post['items']['refund_line_total'][$child_item_id])) {
                         $order_total += wc_format_decimal($_post['items']['refund_line_total'][$child_item_id]);
                     }
                     /* ======================== */
                 }
                 /* === Save Parent Meta === */
                 $meta_keys = isset($_post['items']['meta_key']) ? $_post['items']['meta_key'] : array();
                 $meta_values = isset($_post['items']['meta_value']) ? $_post['items']['meta_value'] : array();
                 foreach ($meta_keys as $meta_id => $meta_key) {
                     $meta_value = empty($meta_values[$meta_id]) && !is_numeric($meta_values[$meta_id]) ? '' : $meta_values[$meta_id];
                     $parent_order_item_id = self::get_parent_item_id(false, $meta_id);
                     $child_order_item_id = self::get_child_item_id($parent_order_item_id);
                     '_child__commission_id' != $meta_key && wc_update_order_item_meta($child_order_item_id, '_parent_' . $meta_key, '_commission_id' != $meta_key ? $meta_id : $meta_values[$meta_id]);
                 }
                 /* ======================== */
                 // Add order total
                 $_post['items']['_order_total'] = $order_total;
                 // Save order items
                 wc_save_order_items($suborder_id, $_post['items']);
             }
         } else {
             //is suborder
             //TODO: Suborder sub-routine
         }
     }
 }
 /**
  * Updates WooTax tax item to reflect changes in cart/shipping tax totals
  *
  * @since 4.2
  * @param (double) $cart_tax the total cart tax added by WooTax
  * @param (double) $shipping_tax the total shipping tax added by WooTax
  */
 private function update_tax_item($cart_tax, $shipping_tax)
 {
     global $wpdb;
     // Add a new tax item if necessary
     $tax_item_id = WT_Orders::get_meta($this->order_id, 'tax_item_id');
     if ($tax_item_id == 0 || $tax_item_id == NULL) {
         $wpdb->insert("{$wpdb->prefix}woocommerce_order_items", array('order_item_type' => 'tax', 'order_item_name' => apply_filters('wootax_rate_code', 'WOOTAX-RATE-DO-NOT-REMOVE'), 'order_id' => $this->order_id));
         // Store new tax item ID
         $tax_item_id = $wpdb->insert_id;
         WT_Orders::update_meta($this->order_id, 'tax_item_id', $tax_item_id);
     }
     // Update tax item meta
     wc_update_order_item_meta($tax_item_id, 'rate_id', WT_RATE_ID);
     wc_update_order_item_meta($tax_item_id, 'label', WC_WooTax::get_rate_label(WT_RATE_ID));
     wc_update_order_item_meta($tax_item_id, 'name', WC_WooTax::get_rate_label(WT_RATE_ID));
     wc_update_order_item_meta($tax_item_id, 'compound', true);
     wc_update_order_item_meta($tax_item_id, 'tax_amount', $cart_tax);
     wc_update_order_item_meta($tax_item_id, 'shipping_tax_amount', $shipping_tax);
     if (WT_SUBS_ACTIVE) {
         wc_update_order_item_meta($tax_item_id, 'cart_tax', $cart_tax);
         wc_update_order_item_meta($tax_item_id, 'shipping_tax', $shipping_tax);
     }
 }
コード例 #23
0
 /**
  * Save meta box data
  */
 public static function save($post_id, $post)
 {
     global $wpdb;
     // Save tax rows
     $total_tax = 0;
     $total_shipping_tax = 0;
     if (isset($_POST['order_taxes_id'])) {
         $get_values = array('order_taxes_id', 'order_taxes_rate_id', 'order_taxes_amount', 'order_taxes_shipping_amount');
         foreach ($get_values as $value) {
             ${$value} = isset($_POST[$value]) ? $_POST[$value] : array();
         }
         foreach ($order_taxes_id as $item_id => $value) {
             if ($item_id == 'new') {
                 foreach ($value as $new_key => $new_value) {
                     $rate_id = absint($order_taxes_rate_id[$item_id][$new_key]);
                     if ($rate_id) {
                         $rate = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->prefix}woocommerce_tax_rates WHERE tax_rate_id = %s", $rate_id));
                         $label = $rate->tax_rate_name ? $rate->tax_rate_name : WC()->countries->tax_or_vat();
                         $compound = $rate->tax_rate_compound ? 1 : 0;
                         $code = array();
                         $code[] = $rate->tax_rate_country;
                         $code[] = $rate->tax_rate_state;
                         $code[] = $rate->tax_rate_name ? $rate->tax_rate_name : 'TAX';
                         $code[] = absint($rate->tax_rate_priority);
                         $code = strtoupper(implode('-', array_filter($code)));
                     } else {
                         $code = '';
                         $label = WC()->countries->tax_or_vat();
                     }
                     // Add line item
                     $new_id = wc_add_order_item($post_id, array('order_item_name' => wc_clean($code), 'order_item_type' => 'tax'));
                     // Add line item meta
                     if ($new_id) {
                         wc_update_order_item_meta($new_id, 'rate_id', $rate_id);
                         wc_update_order_item_meta($new_id, 'label', $label);
                         wc_update_order_item_meta($new_id, 'compound', $compound);
                         if (isset($order_taxes_amount[$item_id][$new_key])) {
                             wc_update_order_item_meta($new_id, 'tax_amount', wc_format_decimal($order_taxes_amount[$item_id][$new_key]));
                             $total_tax += wc_format_decimal($order_taxes_amount[$item_id][$new_key]);
                         }
                         if (isset($order_taxes_shipping_amount[$item_id][$new_key])) {
                             wc_update_order_item_meta($new_id, 'shipping_tax_amount', wc_format_decimal($order_taxes_shipping_amount[$item_id][$new_key]));
                             $total_shipping_tax += wc_format_decimal($order_taxes_shipping_amount[$item_id][$new_key]);
                         }
                     }
                 }
             } else {
                 $item_id = absint($item_id);
                 $rate_id = absint($order_taxes_rate_id[$item_id]);
                 if ($rate_id) {
                     $rate = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->prefix}woocommerce_tax_rates WHERE tax_rate_id = %s", $rate_id));
                     $label = $rate->tax_rate_name ? $rate->tax_rate_name : WC()->countries->tax_or_vat();
                     $compound = $rate->tax_rate_compound ? 1 : 0;
                     $code = array();
                     $code[] = $rate->tax_rate_country;
                     $code[] = $rate->tax_rate_state;
                     $code[] = $rate->tax_rate_name ? $rate->tax_rate_name : 'TAX';
                     $code[] = absint($rate->tax_rate_priority);
                     $code = strtoupper(implode('-', array_filter($code)));
                 } else {
                     $code = '';
                     $label = WC()->countries->tax_or_vat();
                 }
                 $wpdb->update($wpdb->prefix . "woocommerce_order_items", array('order_item_name' => wc_clean($code)), array('order_item_id' => $item_id), array('%s'), array('%d'));
                 wc_update_order_item_meta($item_id, 'rate_id', $rate_id);
                 wc_update_order_item_meta($item_id, 'label', $label);
                 wc_update_order_item_meta($item_id, 'compound', $compound);
                 if (isset($order_taxes_amount[$item_id])) {
                     wc_update_order_item_meta($item_id, 'tax_amount', wc_format_decimal($order_taxes_amount[$item_id]));
                     $total_tax += wc_format_decimal($order_taxes_amount[$item_id]);
                 }
                 if (isset($order_taxes_shipping_amount[$item_id])) {
                     wc_update_order_item_meta($item_id, 'shipping_tax_amount', wc_format_decimal($order_taxes_shipping_amount[$item_id]));
                     $total_shipping_tax += wc_format_decimal($order_taxes_shipping_amount[$item_id]);
                 }
             }
         }
     }
     // Update totals
     update_post_meta($post_id, '_order_tax', wc_format_decimal($total_tax));
     update_post_meta($post_id, '_order_shipping_tax', wc_format_decimal($total_shipping_tax));
     update_post_meta($post_id, '_order_discount', wc_format_decimal($_POST['_order_discount']));
     update_post_meta($post_id, '_order_total', wc_format_decimal($_POST['_order_total']));
     // Shipping Rows
     $order_shipping = 0;
     if (isset($_POST['shipping_method_id'])) {
         $get_values = array('shipping_method_id', 'shipping_method_title', 'shipping_method', 'shipping_cost');
         foreach ($get_values as $value) {
             ${$value} = isset($_POST[$value]) ? $_POST[$value] : array();
         }
         foreach ($shipping_method_id as $item_id => $value) {
             if ($item_id == 'new') {
                 foreach ($value as $new_key => $new_value) {
                     $method_id = wc_clean($shipping_method[$item_id][$new_key]);
                     $method_title = wc_clean($shipping_method_title[$item_id][$new_key]);
                     $cost = wc_format_decimal($shipping_cost[$item_id][$new_key]);
                     $new_id = wc_add_order_item($post_id, array('order_item_name' => $method_title, 'order_item_type' => 'shipping'));
                     if ($new_id) {
                         wc_add_order_item_meta($new_id, 'method_id', $method_id);
                         wc_add_order_item_meta($new_id, 'cost', $cost);
                     }
                     $order_shipping += $cost;
                 }
             } else {
                 $item_id = absint($item_id);
                 $method_id = wc_clean($shipping_method[$item_id]);
                 $method_title = wc_clean($shipping_method_title[$item_id]);
                 $cost = wc_format_decimal($shipping_cost[$item_id]);
                 $wpdb->update($wpdb->prefix . "woocommerce_order_items", array('order_item_name' => $method_title), array('order_item_id' => $item_id), array('%s'), array('%d'));
                 wc_update_order_item_meta($item_id, 'method_id', $method_id);
                 wc_update_order_item_meta($item_id, 'cost', $cost);
                 $order_shipping += $cost;
             }
         }
     }
     // Delete rows
     if (isset($_POST['delete_order_item_id'])) {
         $delete_ids = $_POST['delete_order_item_id'];
         foreach ($delete_ids as $id) {
             wc_delete_order_item(absint($id));
         }
     }
     delete_post_meta($post_id, '_shipping_method');
     delete_post_meta($post_id, '_shipping_method_title');
     update_post_meta($post_id, '_order_shipping', $order_shipping);
 }
 /**
  * Updates "taxes" meta for shipping items to include any tax added by WooTax
  * Assumes that only one shipping method is used per order
  *
  * @since 4.2
  * @param $order_id the id of the WooCommerce order
  * @param $item_id the id of the item inserted into the database
  * @param $shipping_rate the actual shipping rate (object)
  */
 public static function add_shipping_tax($order_id, $item_id, $shipping_rate)
 {
     $taxes = array_map('wc_format_decimal', $shipping_rate->taxes);
     $taxes[WT_RATE_ID] = self::get_meta($order_id, 'shipping_tax_total');
     wc_update_order_item_meta($item_id, 'taxes', $taxes);
 }
コード例 #25
0
 public static function aaj_ts_update_ticket($resp, $data)
 {
     $resp['s'] = false;
     $resp['e'] = array();
     $oiid = $data['oiid'];
     $oid = $data['order_id'];
     if (self::_is_order_item($oiid) && $oid > 0) {
         $order = new WC_Order($oid);
         $items = $order->get_items();
         if (isset($items[$oiid . ''])) {
             $item = $items[$oiid . ''];
             $meta = array();
             $event_id = $data['eid'];
             $event = apply_filters('qsot-get-event', false, $event_id);
             if (is_object($event) && is_array($item)) {
                 $where = array('ticket_type_id' => $item['product_id'], 'qty' => $item['qty'], 'order_id' => $oid, 'event_id' => $item['event_id'], 'state' => array(self::$o->{'z.states.c'}, self::$o->{'z.states.o'}));
                 $change_to = array('event_id' => $event_id);
                 $res = apply_filters('qsot-zoner-update-reservation', false, $where, $change_to);
                 if ($res) {
                     $meta['event_id'] = $event_id;
                     wc_update_order_item_meta($oiid, '_event_id', $event_id);
                 }
                 do_action('qsot-ticket-selection-update-ticket-after-meta-update', $oiid, $item, $meta, $order);
                 $resp['s'] = true;
                 $resp['updated'] = $meta;
                 $resp['data'] = $item;
                 $resp['data']['__order_item_id'] = $oiid;
                 $event->_edit_url = get_edit_post_link($event_id);
                 $event->post_title = apply_filters('the_title', $event->post_title);
                 $resp['event'] = $event;
             } else {
                 $resp['e'] = __('Could not find the new event.', 'opentickets-community-edition');
             }
         } else {
             $resp['e'] = __('Could not find that order item on the order.', 'opentickets-community-edition');
         }
     } else {
         $resp['e'] = __('The order item does not appear to be valid.', 'opentickets-community-edition');
     }
     return $resp;
 }
/**
 * Update recurring tax for subscriptions
 * Not executed if Subscriptions plugin is not active
 *
 * @since 4.4
 * @return void
 */
function wootax_update_recurring_tax()
{
    global $wpdb;
    // Exit if subs is not active
    if (!WT_SUBS_ACTIVE) {
        return;
    }
    // Find date/time 12 hours from now
    $twelve_hours = mktime(date('H') + 12);
    $date = new DateTime(date('c', $twelve_hours));
    $date = $date->format('Y-m-d H:i:s');
    // Set up logger
    $logger = false;
    if (WT_LOG_REQUESTS) {
        $logger = class_exists('WC_Logger') ? new WC_Logger() : WC()->logger();
        $logger->add('wootax', 'Starting recurring tax update. Subscriptions with payments due before ' . $date . ' are being considered.');
    }
    // Get all scheduled "scheduled_subscription_payment" actions with post_date <= $twelve_hours
    $scheduled = $wpdb->get_results($wpdb->prepare("SELECT ID, post_content FROM {$wpdb->posts} WHERE post_status = %s AND post_title = %s AND post_date <= %s", "pending", "scheduled_subscription_payment", $date));
    // Update recurring totals if necessary
    if (count($scheduled) > 0) {
        // This will hold any warning messages that need to be sent to the admin
        $warnings = array();
        foreach ($scheduled as $action) {
            $temp_warnings = array();
            $show_warnings = false;
            // Run json_decode on post_content to extract user_id and subscription_key
            $args = json_decode($action->post_content);
            // Parse subscription_key to get order_id/product_id (format: ORDERID_PRODUCTID)
            $subscription_key = $args->subscription_key;
            $key_parts = explode('_', $subscription_key);
            $order_id = (int) $key_parts[0];
            $product_id = (int) $key_parts[1];
            if (get_post_status($order_id) == false) {
                continue;
                // Skip if the order no longer exists
            }
            // Determine if changes to subscription amounts are allowed by the current gateway
            $chosen_gateway = WC_Subscriptions_Payment_Gateways::get_payment_gateway(get_post_meta($order_id, '_recurring_payment_method', true));
            $manual_renewal = WC_Subscriptions_Order::requires_manual_renewal($order_id);
            $changes_supported = $chosen_gateway === false || $manual_renewal == 'true' || $chosen_gateway->supports('subscription_amount_changes') ? true : false;
            // Load order
            $order = WT_Orders::get_order($order_id);
            // Collect data for Lookup request
            $item_data = $type_array = array();
            // Add subscription
            $product = WC_Subscriptions::get_product($product_id);
            // Get order item ID
            $item_id = $wpdb->get_var("SELECT i.order_item_id FROM {$wpdb->prefix}woocommerce_order_items i LEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta im ON im.order_item_id = i.order_item_id WHERE im.meta_key = '_product_id' AND im.meta_value = {$product_id} AND i.order_id = {$order_id}");
            // Get price
            $recurring_subtotal = $order->get_item_meta($item_id, '_recurring_line_subtotal');
            $regular_subtotal = $order->get_item_meta($item_id, '_line_subtotal');
            $price = $recurring_subtotal === '0' || !empty($recurring_subtotal) ? $recurring_subtotal : $regular_subtotal;
            // Special case: If _subscription_sign_up_fee is set and $price is equal to its value, fall back to product price
            if ($order->get_item_meta($item_id, '_subscription_sign_up_fee') == $price) {
                $price = $product->get_price();
            }
            $item_info = array('Index' => '', 'ItemID' => $item_id, 'Qty' => 1, 'Price' => $price, 'Type' => 'cart');
            $tic = get_post_meta($product_id, 'wootax_tic', true);
            if (!empty($tic) && $tic) {
                $item_info['TIC'] = $tic;
            }
            $item_data[] = $item_info;
            $type_array[$item_id] = 'cart';
            // Add recurring shipping items
            foreach ($order->order->get_items('recurring_shipping') as $item_id => $shipping) {
                $item_data[] = array('Index' => '', 'ItemID' => $item_id, 'TIC' => WT_SHIPPING_TIC, 'Qty' => 1, 'Price' => $shipping['cost'], 'Type' => 'shipping');
                $type_array[$item_id] = 'shipping';
            }
            // Reset "captured" meta so lookup always sent
            $captured = WT_Orders::get_meta($order_id, 'captured');
            WT_Orders::update_meta($order_id, 'captured', false);
            // Issue Lookup request
            $res = $order->do_lookup($item_data, $type_array, true);
            // Set "captured" back to original value
            WT_Orders::update_meta($order_id, 'captured', $captured);
            // If lookup is successful, use result to update recurring tax totals as described here: http://docs.woothemes.com/document/subscriptions/add-or-modify-a-subscription/#change-recurring-total
            if (is_array($res)) {
                // Find recurring tax item and determine original tax/shipping tax totals
                $wootax_item_id = $wpdb->get_var($wpdb->prepare("SELECT i.order_item_id FROM {$wpdb->prefix}woocommerce_order_items i LEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta im ON im.order_item_id = i.order_item_id WHERE im.meta_key = %s AND im.meta_value = %d AND i.order_id = %d AND i.order_item_type = %s", "rate_id", WT_RATE_ID, $order_id, "recurring_tax"));
                $old_tax = empty($wootax_item_id) ? 0 : $order->get_item_meta($wootax_item_id, 'tax_amount');
                $old_shipping_tax = empty($wootax_item_id) ? 0 : $order->get_item_meta($wootax_item_id, 'shipping_tax_amount');
                // Find new tax/shipping tax totals
                // Update _recurring_line_tax meta for each item
                $tax = $shipping_tax = 0;
                foreach ($res as $item) {
                    $item_id = $item->ItemID;
                    $item_tax = $item->TaxAmount;
                    if ($type_array[$item_id] == 'shipping') {
                        $shipping_tax += $item_tax;
                    } else {
                        $tax += $item_tax;
                    }
                    if ($changes_supported) {
                        wc_update_order_item_meta($item_id, '_recurring_line_tax', $item_tax);
                        wc_update_order_item_meta($item_id, '_recurring_line_subtotal_tax', $item_tax);
                    } else {
                        $temp_warnings[] = 'Recurring tax for item #' . $item_id . ' changed to ' . wc_round_tax_total($item_tax);
                    }
                }
                // Update recurring tax if necessary
                if ($old_tax != $tax || $old_shipping_tax != $shipping_tax) {
                    if ($changes_supported) {
                        if (!empty($wootax_item_id)) {
                            wc_update_order_item_meta($wootax_item_id, 'tax_amount', $tax);
                            wc_update_order_item_meta($wootax_item_id, 'cart_tax', $tax);
                            wc_update_order_item_meta($wootax_item_id, 'shipping_tax_amount', $shipping_tax);
                            wc_update_order_item_meta($wootax_item_id, 'shipping_tax', $shipping_tax);
                        }
                        // Determine rounded difference in old/new tax totals
                        $tax_diff = $tax + $shipping_tax - ($old_tax + $old_shipping_tax);
                        $rounded_tax_diff = wc_round_tax_total($tax_diff);
                        // Set new recurring total by adding difference between old and new tax to existing total
                        $new_recurring_total = get_post_meta($order_id, '_order_recurring_total', true) + $rounded_tax_diff;
                        update_post_meta($order_id, '_order_recurring_total', $new_recurring_total);
                        if ($logger) {
                            $logger->add('wootax', 'Set recurring total for order ' . $order_id . ' to: ' . $new_recurring_total);
                        }
                    } else {
                        $temp_warnings[] = 'Total recurring tax changed from ' . wc_round_tax_total($old_tax) . ' to ' . wc_round_tax_total($tax);
                        $temp_warnings[] = 'Total recurring shipping tax changed from ' . wc_round_tax_total($old_shipping_tax) . ' to ' . wc_round_tax_total($shipping_tax);
                        $show_warnings = true;
                    }
                }
                // Add to warnings array if necessary
                if ($show_warnings) {
                    $warnings[$order_id] = $temp_warnings;
                }
            }
        }
        // Send out a single warning email to the admin if necessary
        // Ex: Email sent if a change in tax rates is detected and the gateway used by an order doesn't allow modification of sub. details
        if (count($warnings) > 0) {
            $email = wootax_get_notification_email();
            if (!empty($email) && is_email($email)) {
                $subject = 'WooTax Warning: Recurring Tax Totals Need To Be Updated';
                $message = 'Hello,' . "\r\n\r\n" . 'During a routine check on ' . date('m/d/Y') . ', WooTax discovered ' . count($warnings) . ' subscription orders whose recurring tax totals need to be updated. Unfortunately, the payment gateway(s) used for these orders does not allow subscription details to be altered, so the required changes must be implemented manually. All changes are listed below for your convenience.' . "\r\n\r\n";
                foreach ($warnings as $order_id => $errors) {
                    $message .= 'Order ' . $order_id . ': ' . "\r\n\r\n";
                    foreach ($errors as $error) {
                        $message .= '- ' . $error . "\r\n";
                    }
                    $message .= "\r\n\r\n";
                }
                $message .= 'For assistance, please contact the WooTax support team at sales@wootax.com.';
                wp_mail($email, $subject, $message);
            }
        }
    } else {
        if ($logger) {
            $logger->add('wootax', 'Ending recurring tax update. No subscriptions due before ' . $date . '.');
        }
    }
}
 function filter_ajax_order_item($item, $item_id)
 {
     if (!get_post_meta($_POST['order_id'], '_order_currency')) {
         $order_currency = $this->get_cookie_order_currency();
     } else {
         $order_currency = get_post_meta($_POST['order_id'], '_order_currency', true);
     }
     $custom_price = get_post_meta($_POST['item_to_add'], '_price_' . $order_currency, true);
     if ($custom_price) {
         $item['line_subtotal'] = $custom_price;
         $item['line_total'] = $custom_price;
     } else {
         $item['line_subtotal'] = $this->apply_rounding_rules($this->convert_price_amount($item['line_subtotal'], $order_currency), $order_currency);
         $item['line_total'] = $this->apply_rounding_rules($this->convert_price_amount($item['line_total'], $order_currency), $order_currency);
     }
     wc_update_order_item_meta($item_id, '_line_subtotal', $item['line_subtotal']);
     $item['line_subtotal_tax'] = $this->convert_price_amount($item['line_subtotal_tax'], $order_currency);
     wc_update_order_item_meta($item_id, '_line_subtotal_tax', $item['line_subtotal_tax']);
     wc_update_order_item_meta($item_id, '_line_total', $item['line_total']);
     $item['line_tax'] = $this->convert_price_amount($item['line_tax'], $order_currency);
     wc_update_order_item_meta($item_id, '_line_tax', $item['line_tax']);
     return $item;
 }
コード例 #28
0
/**
 * Save order items
 *
 * @since 2.2
 * @param int $order_id Order ID
 * @param array $items Order items to save
 */
function wc_save_order_items($order_id, $items)
{
    global $wpdb;
    // Order items + fees
    $subtotal = 0;
    $total = 0;
    $subtotal_tax = 0;
    $total_tax = 0;
    $taxes = array('items' => array(), 'shipping' => array());
    if (isset($items['order_item_id'])) {
        $line_total = $line_subtotal = $line_tax = $line_subtotal_tax = array();
        foreach ($items['order_item_id'] as $item_id) {
            $item_id = absint($item_id);
            if (isset($items['order_item_name'][$item_id])) {
                $wpdb->update($wpdb->prefix . 'woocommerce_order_items', array('order_item_name' => wc_clean($items['order_item_name'][$item_id])), array('order_item_id' => $item_id), array('%s'), array('%d'));
            }
            if (isset($items['order_item_qty'][$item_id])) {
                wc_update_order_item_meta($item_id, '_qty', wc_stock_amount($items['order_item_qty'][$item_id]));
            }
            if (isset($items['order_item_tax_class'][$item_id])) {
                wc_update_order_item_meta($item_id, '_tax_class', wc_clean($items['order_item_tax_class'][$item_id]));
            }
            // Get values. Subtotals might not exist, in which case copy value from total field
            $line_total[$item_id] = isset($items['line_total'][$item_id]) ? $items['line_total'][$item_id] : 0;
            $line_subtotal[$item_id] = isset($items['line_subtotal'][$item_id]) ? $items['line_subtotal'][$item_id] : $line_total[$item_id];
            $line_tax[$item_id] = isset($items['line_tax'][$item_id]) ? $items['line_tax'][$item_id] : array();
            $line_subtotal_tax[$item_id] = isset($items['line_subtotal_tax'][$item_id]) ? $items['line_subtotal_tax'][$item_id] : $line_tax[$item_id];
            // Format taxes
            $line_taxes = array_map('wc_format_decimal', $line_tax[$item_id]);
            $line_subtotal_taxes = array_map('wc_format_decimal', $line_subtotal_tax[$item_id]);
            // Update values
            wc_update_order_item_meta($item_id, '_line_subtotal', wc_format_decimal($line_subtotal[$item_id]));
            wc_update_order_item_meta($item_id, '_line_total', wc_format_decimal($line_total[$item_id]));
            wc_update_order_item_meta($item_id, '_line_subtotal_tax', array_sum($line_subtotal_taxes));
            wc_update_order_item_meta($item_id, '_line_tax', array_sum($line_taxes));
            // Save line tax data - Since 2.2
            wc_update_order_item_meta($item_id, '_line_tax_data', array('total' => $line_taxes, 'subtotal' => $line_subtotal_taxes));
            $taxes['items'][] = $line_taxes;
            // Total up
            $subtotal += wc_format_decimal($line_subtotal[$item_id]);
            $total += wc_format_decimal($line_total[$item_id]);
            $subtotal_tax += array_sum($line_subtotal_taxes);
            $total_tax += array_sum($line_taxes);
            // Clear meta cache
            wp_cache_delete($item_id, 'order_item_meta');
        }
    }
    // Save meta
    $meta_keys = isset($items['meta_key']) ? $items['meta_key'] : array();
    $meta_values = isset($items['meta_value']) ? $items['meta_value'] : array();
    foreach ($meta_keys as $id => $meta_key) {
        $meta_value = empty($meta_values[$id]) && !is_numeric($meta_values[$id]) ? '' : $meta_values[$id];
        $wpdb->update($wpdb->prefix . 'woocommerce_order_itemmeta', array('meta_key' => wp_unslash($meta_key), 'meta_value' => wp_unslash($meta_value)), array('meta_id' => $id), array('%s', '%s'), array('%d'));
    }
    // Shipping Rows
    $order_shipping = 0;
    if (isset($items['shipping_method_id'])) {
        foreach ($items['shipping_method_id'] as $item_id) {
            $item_id = absint($item_id);
            $method_id = isset($items['shipping_method'][$item_id]) ? wc_clean($items['shipping_method'][$item_id]) : '';
            $method_title = isset($items['shipping_method_title'][$item_id]) ? wc_clean($items['shipping_method_title'][$item_id]) : '';
            $cost = isset($items['shipping_cost'][$item_id]) ? wc_format_decimal($items['shipping_cost'][$item_id]) : '';
            $ship_taxes = isset($items['shipping_taxes'][$item_id]) ? array_map('wc_format_decimal', $items['shipping_taxes'][$item_id]) : array();
            $wpdb->update($wpdb->prefix . 'woocommerce_order_items', array('order_item_name' => $method_title), array('order_item_id' => $item_id), array('%s'), array('%d'));
            wc_update_order_item_meta($item_id, 'method_id', $method_id);
            wc_update_order_item_meta($item_id, 'cost', $cost);
            wc_update_order_item_meta($item_id, 'taxes', $ship_taxes);
            $taxes['shipping'][] = $ship_taxes;
            $order_shipping += $cost;
        }
    }
    // Taxes
    $order_taxes = isset($items['order_taxes']) ? $items['order_taxes'] : array();
    $taxes_items = array();
    $taxes_shipping = array();
    $total_tax = 0;
    $total_shipping_tax = 0;
    // Sum items taxes
    foreach ($taxes['items'] as $rates) {
        foreach ($rates as $id => $value) {
            if (isset($taxes_items[$id])) {
                $taxes_items[$id] += $value;
            } else {
                $taxes_items[$id] = $value;
            }
        }
    }
    // Sum shipping taxes
    foreach ($taxes['shipping'] as $rates) {
        foreach ($rates as $id => $value) {
            if (isset($taxes_shipping[$id])) {
                $taxes_shipping[$id] += $value;
            } else {
                $taxes_shipping[$id] = $value;
            }
        }
    }
    // Update order taxes
    foreach ($order_taxes as $item_id => $rate_id) {
        if (isset($taxes_items[$rate_id])) {
            $_total = wc_format_decimal($taxes_items[$rate_id]);
            wc_update_order_item_meta($item_id, 'tax_amount', $_total);
            $total_tax += $_total;
        }
        if (isset($taxes_shipping[$rate_id])) {
            $_total = wc_format_decimal($taxes_shipping[$rate_id]);
            wc_update_order_item_meta($item_id, 'shipping_tax_amount', $_total);
            $total_shipping_tax += $_total;
        }
    }
    // Update order shipping total
    update_post_meta($order_id, '_order_shipping', $order_shipping);
    // Update cart discount from item totals
    update_post_meta($order_id, '_cart_discount', $subtotal - $total);
    update_post_meta($order_id, '_cart_discount_tax', $subtotal_tax - $total_tax);
    // Update totals
    update_post_meta($order_id, '_order_total', wc_format_decimal($items['_order_total']));
    // Update tax
    update_post_meta($order_id, '_order_tax', wc_format_decimal($total_tax));
    update_post_meta($order_id, '_order_shipping_tax', wc_format_decimal($total_shipping_tax));
    // Remove old values
    delete_post_meta($order_id, '_shipping_method');
    delete_post_meta($order_id, '_shipping_method_title');
    // Set the currency
    add_post_meta($order_id, '_order_currency', get_woocommerce_currency(), true);
    // Update version after saving
    update_post_meta($order_id, '_order_version', WC_VERSION);
    // inform other plugins that the items have been saved
    do_action('woocommerce_saved_order_items', $order_id, $items);
}
コード例 #29
0
 /**
  * Calculate taxes for all line items and shipping, and store the totals and tax rows.
  *
  * Will use the base country unless customer addresses are set.
  *
  * @return bool success or fail
  */
 public function calculate_taxes()
 {
     $tax_total = 0;
     $taxes = array();
     $tax_based_on = get_option('woocommerce_tax_based_on');
     if ('billing' === $tax_based_on) {
         $country = $this->billing_country;
         $state = $this->billing_state;
         $postcode = $this->billing_postcode;
         $city = $this->billing_city;
     } elseif ('shipping' === $tax_based_on) {
         $country = $this->shipping_country;
         $state = $this->shipping_state;
         $postcode = $this->shipping_postcode;
         $city = $this->shipping_city;
     }
     // Default to base
     if ('base' === $tax_based_on || empty($country)) {
         $default = wc_get_base_location();
         $country = $default['country'];
         $state = $default['state'];
         $postcode = '';
         $city = '';
     }
     // Get items
     foreach ($this->get_items(array('line_item', 'fee')) as $item_id => $item) {
         $product = $this->get_product_from_item($item);
         $line_total = isset($item['line_total']) ? $item['line_total'] : 0;
         $line_subtotal = isset($item['line_subtotal']) ? $item['line_subtotal'] : 0;
         $tax_class = $item['tax_class'];
         $item_tax_status = $product ? $product->get_tax_status() : 'taxable';
         if ('0' !== $tax_class && 'taxable' === $item_tax_status) {
             $tax_rates = WC_Tax::find_rates(array('country' => $country, 'state' => $state, 'postcode' => $postcode, 'city' => $city, 'tax_class' => $tax_class));
             $line_subtotal_taxes = WC_Tax::calc_tax($line_subtotal, $tax_rates, false);
             $line_taxes = WC_Tax::calc_tax($line_total, $tax_rates, false);
             $line_subtotal_tax = max(0, array_sum($line_subtotal_taxes));
             $line_tax = max(0, array_sum($line_taxes));
             $tax_total += $line_tax;
             wc_update_order_item_meta($item_id, '_line_subtotal_tax', wc_format_decimal($line_subtotal_tax));
             wc_update_order_item_meta($item_id, '_line_tax', wc_format_decimal($line_tax));
             wc_update_order_item_meta($item_id, '_line_tax_data', array('total' => $line_taxes, 'subtotal' => $line_subtotal_taxes));
             // Sum the item taxes
             foreach (array_keys($taxes + $line_taxes) as $key) {
                 $taxes[$key] = (isset($line_taxes[$key]) ? $line_taxes[$key] : 0) + (isset($taxes[$key]) ? $taxes[$key] : 0);
             }
         }
     }
     // Now calculate shipping tax
     $matched_tax_rates = array();
     $tax_rates = WC_Tax::find_rates(array('country' => $country, 'state' => $state, 'postcode' => $postcode, 'city' => $city, 'tax_class' => ''));
     if (!empty($tax_rates)) {
         foreach ($tax_rates as $key => $rate) {
             if (isset($rate['shipping']) && 'yes' === $rate['shipping']) {
                 $matched_tax_rates[$key] = $rate;
             }
         }
     }
     $shipping_taxes = WC_Tax::calc_shipping_tax($this->order_shipping, $matched_tax_rates);
     $shipping_tax_total = WC_Tax::round(array_sum($shipping_taxes));
     // Save tax totals
     $this->set_total($shipping_tax_total, 'shipping_tax');
     $this->set_total($tax_total, 'tax');
     // Tax rows
     $this->remove_order_items('tax');
     // Now merge to keep tax rows
     foreach (array_keys($taxes + $shipping_taxes) as $tax_rate_id) {
         $this->add_tax($tax_rate_id, isset($taxes[$tax_rate_id]) ? $taxes[$tax_rate_id] : 0, isset($shipping_taxes[$tax_rate_id]) ? $shipping_taxes[$tax_rate_id] : 0);
     }
     return true;
 }
コード例 #30
0
 public function recalculate_profit_callback()
 {
     $redirect = wp_get_referer() ? wp_get_referer() : admin_url('admin.php?page=wc-reports&tab=profit');
     if (!isset($_REQUEST['token']) || !wp_verify_nonce($_REQUEST['token'], 'funkwoocost-recalculate-profit')) {
         wp_redirect(add_query_arg(array('status' => 'failed'), $redirect));
         die;
     }
     global $wpdb;
     $order_items = $wpdb->get_results("\n            SELECT order_items.order_item_id,\n                   meta_product_id.meta_value AS product_id,\n                   meta_variation_id.meta_value AS variation_id\n            FROM {$wpdb->prefix}woocommerce_order_items AS order_items\n            LEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS meta_product_id ON order_items.order_item_id=meta_product_id.order_item_id AND meta_product_id.meta_key='_product_id'\n            LEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS meta_variation_id ON order_items.order_item_id=meta_variation_id.order_item_id AND meta_variation_id.meta_key='_variation_id'\n            WHERE order_items.order_item_type='line_item'\n        ");
     // echo "<pre>";
     // print_r($order_items);
     // echo "</pre>";
     // exit();
     if (!empty($order_items)) {
         foreach ($order_items as $order_item) {
             $cost_of_good = !empty($order_item->variation_id) ? get_post_meta($order_item->variation_id, '_funkwoocost', true) : get_post_meta($order_item->product_id, '_funkwoocost', true);
             // echo $cost_of_good; exit();
             $order_item_qty = wc_get_order_item_meta($order_item->order_item_id, '_qty', true);
             wc_update_order_item_meta($order_item->order_item_id, '_line_funkwoocost_order', wc_format_decimal($cost_of_good * $order_item_qty));
         }
     }
     // clear transient
     delete_transient(strtolower('WooCost_Report_Profit_By_Date'));
     wp_redirect(add_query_arg(array('status' => 'success'), $redirect));
     die;
 }