prepare( " SELECT p.ID as product_id, p.post_title as name, p.post_status as post_status, p.post_date as upload_date, pml.sku as sku, pml.stock_quantity as stock_qty, pml.stock_status as stock_status, pml.min_price as price, SUM(CASE WHEN os.order_id IS NOT NULL THEN opl.product_qty ELSE 0 END) as qty_sold, SUM(CASE WHEN os.order_id IS NOT NULL THEN opl.product_gross_revenue ELSE 0 END) as gross_revenue, SUM(CASE WHEN os.order_id IS NOT NULL THEN opl.coupon_amount ELSE 0 END) as discount, SUM(CASE WHEN os.order_id IS NOT NULL THEN opl.product_net_revenue ELSE 0 END) as net_revenue, COUNT(DISTINCT CASE WHEN os.order_id IS NOT NULL THEN opl.order_id ELSE NULL END) as orders_count FROM {$wpdb->posts} p LEFT JOIN {$wpdb->prefix}wc_product_meta_lookup pml ON p.ID = pml.product_id LEFT JOIN {$wpdb->prefix}wc_order_product_lookup opl ON p.ID = opl.product_id LEFT JOIN {$wpdb->prefix}wc_order_stats os ON os.order_id = opl.order_id AND os.status IN ($paid_statuses) AND os.date_created >= %s AND os.date_created <= %s WHERE p.post_type = 'product' AND p.post_status IN ('publish', 'draft') GROUP BY p.ID ORDER BY net_revenue DESC, name ASC ", $dates['start'], $dates['end'] ); // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter $products = $wpdb->get_results( $query, ARRAY_A ); $data[] = array( 'Product Name', 'Author Name', 'Translator Name', 'Publisher Name', 'Items Sold', 'Net Revenue', 'Category', ); foreach ( $products as $row ) { $pid = $row['product_id']; $author = self::get_product_terms_by_type( $pid, 'author' ); $translator = self::get_product_terms_by_type( $pid, 'translator' ); $publisher = self::get_product_terms_by_type( $pid, 'publisher' ); $categories = implode( ', ', wp_get_post_terms( $pid, 'product_cat', array( 'fields' => 'names' ) ) ); $qty_sold = (int) $row['qty_sold']; $net_revenue = (float) $row['net_revenue']; $data[] = array( $row['name'], $author, $translator, $publisher, $qty_sold, $net_revenue, $categories, ); } break; case 'categories': $result = ANFOWO_Category_Query::get_report( $period, $start_date, $end_date ); $data[] = array( 'Category Name', 'Items Sold', 'Net Revenue' ); foreach ( $result['table'] as $row ) { $data[] = array( $row['name'], $row['items_sold'], $row['revenue'] ); } break; case 'taxonomies': $taxonomy_type = isset( $_GET['taxonomy'] ) ? sanitize_text_field( wp_unslash( $_GET['taxonomy'] ) ) : 'all'; if ( $taxonomy_type === 'publishers' ) { // Publisher Report $dates = ANFOWO_Date_Resolver::resolve( $period, $start_date, $end_date ); $paid_statuses = ANFOWO_Database::get_paid_statuses_sql(); global $wpdb; // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared $query = $wpdb->prepare(" SELECT t.name as publisher_name, COUNT(DISTINCT tr_all.object_id) as num_books, COUNT(DISTINCT opl.order_id) as orders_count, SUM(CASE WHEN os.order_id IS NOT NULL THEN opl.product_qty ELSE 0 END) as items_sold, SUM(CASE WHEN os.order_id IS NOT NULL THEN opl.product_gross_revenue ELSE 0 END) as gross_revenue, SUM(CASE WHEN os.order_id IS NOT NULL THEN opl.product_net_revenue ELSE 0 END) as net_revenue FROM {$wpdb->terms} t JOIN {$wpdb->term_taxonomy} tt ON t.term_id = tt.term_id AND tt.taxonomy LIKE %s LEFT JOIN {$wpdb->term_relationships} tr_all ON tt.term_taxonomy_id = tr_all.term_taxonomy_id LEFT JOIN {$wpdb->prefix}wc_order_product_lookup opl ON tr_all.object_id = opl.product_id LEFT JOIN {$wpdb->prefix}wc_order_stats os ON os.order_id = opl.order_id AND os.status IN ($paid_statuses) AND os.date_created >= %s AND os.date_created <= %s GROUP BY t.term_id ORDER BY net_revenue DESC, publisher_name ASC ", '%' . $wpdb->esc_like( 'publisher' ) . '%', $dates['start'], $dates['end']); // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter $publishers = $wpdb->get_results($query, ARRAY_A); $data[] = array( 'Publisher', 'Number of Books', 'Orders', 'Items Sold', 'Revenue', 'Net Revenue' ); foreach ( $publishers as $row ) { $data[] = array( $row['publisher_name'], $row['num_books'], $row['orders_count'], $row['items_sold'], $row['gross_revenue'], $row['net_revenue'] ); } } elseif ( in_array( $taxonomy_type, array( 'authors', 'author', 'translator', 'translators' ), true ) ) { // Author/Translator Report $dates = ANFOWO_Date_Resolver::resolve( $period, $start_date, $end_date ); $paid_statuses = ANFOWO_Database::get_paid_statuses_sql(); global $wpdb; if ( in_array( $taxonomy_type, array( 'authors', 'author' ), true ) ) { $tax_like_sql = "(tt.taxonomy LIKE '%author%' OR tt.taxonomy LIKE '%writer%')"; } else { $tax_like_sql = "(tt.taxonomy LIKE '%translator%')"; } // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared $query = $wpdb->prepare(" SELECT p.ID as product_id, p.post_title as name, pml.sku as sku, t.name as term_name, COALESCE(SUM(CASE WHEN os.order_id IS NOT NULL THEN opl.product_qty ELSE 0 END), 0) as qty_sold, COALESCE(SUM(CASE WHEN os.order_id IS NOT NULL THEN opl.product_net_revenue ELSE 0 END), 0.00) as net_revenue FROM {$wpdb->terms} t JOIN {$wpdb->term_taxonomy} tt ON t.term_id = tt.term_id AND {$tax_like_sql} JOIN {$wpdb->term_relationships} tr ON tt.term_taxonomy_id = tr.term_taxonomy_id JOIN {$wpdb->posts} p ON tr.object_id = p.ID AND p.post_type = 'product' AND p.post_status IN ('publish', 'draft') LEFT JOIN {$wpdb->prefix}wc_product_meta_lookup pml ON p.ID = pml.product_id LEFT JOIN {$wpdb->prefix}wc_order_product_lookup opl ON p.ID = opl.product_id LEFT JOIN {$wpdb->prefix}wc_order_stats os ON os.order_id = opl.order_id AND os.status IN ($paid_statuses) AND os.date_created >= %s AND os.date_created <= %s GROUP BY t.term_id, p.ID ORDER BY net_revenue DESC, term_name ASC, name ASC ", $dates['start'], $dates['end']); // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter $items = $wpdb->get_results($query, ARRAY_A); // Fallback: If no items found with strict '%author%', check if taxonomy term exists with $taxonomy_type as taxonomy slug if ( empty( $items ) ) { // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared $query_fallback = $wpdb->prepare(" SELECT p.ID as product_id, p.post_title as name, pml.sku as sku, t.name as term_name, COALESCE(SUM(CASE WHEN os.order_id IS NOT NULL THEN opl.product_qty ELSE 0 END), 0) as qty_sold, COALESCE(SUM(CASE WHEN os.order_id IS NOT NULL THEN opl.product_net_revenue ELSE 0 END), 0.00) as net_revenue FROM {$wpdb->terms} t JOIN {$wpdb->term_taxonomy} tt ON t.term_id = tt.term_id AND tt.taxonomy = %s JOIN {$wpdb->term_relationships} tr ON tt.term_taxonomy_id = tr.term_taxonomy_id JOIN {$wpdb->posts} p ON tr.object_id = p.ID AND p.post_type = 'product' AND p.post_status IN ('publish', 'draft') LEFT JOIN {$wpdb->prefix}wc_product_meta_lookup pml ON p.ID = pml.product_id LEFT JOIN {$wpdb->prefix}wc_order_product_lookup opl ON p.ID = opl.product_id LEFT JOIN {$wpdb->prefix}wc_order_stats os ON os.order_id = opl.order_id AND os.status IN ($paid_statuses) AND os.date_created >= %s AND os.date_created <= %s GROUP BY t.term_id, p.ID ORDER BY net_revenue DESC, term_name ASC, name ASC ", $taxonomy_type, $dates['start'], $dates['end']); // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter $items = $wpdb->get_results($query_fallback, ARRAY_A); } $data[] = array( ( in_array( $taxonomy_type, array( 'authors', 'author' ), true ) ? 'Author' : 'Translator' ), 'Book Name', 'Category', 'ISBN', 'SKU', 'Total Sales', 'Revenue' ); foreach ( $items as $row ) { $pid = $row['product_id']; $isbn = self::get_product_isbn( $pid ); $categories = implode( ', ', wp_get_post_terms( $pid, 'product_cat', array( 'fields' => 'names' ) ) ); $data[] = array( $row['term_name'], $row['name'], $categories, $isbn, ! empty( $row['sku'] ) ? $row['sku'] : '-', $row['qty_sold'], $row['net_revenue'] ); } } else { $result = ANFOWO_Taxonomy_Query::get_report( $period, $start_date, $end_date, $taxonomy_type ); $data[] = array( 'Taxonomy Term', 'Items Sold', 'Net Revenue' ); foreach ( $result['table'] as $row ) { $data[] = array( $row['name'], $row['items_sold'], $row['revenue'] ); } } break; case 'taxes': $result = ANFOWO_Tax_Query::get_report( $period, $start_date, $end_date ); $data[] = array( 'Tax Rate Name', 'Tax Rate (%)', 'Orders Count', 'Total Tax Collected' ); foreach ( $result['table'] as $row ) { $data[] = array( $row['name'], $row['rate'], $row['orders_count'], $row['tax_amount'] ); } break; case 'customers': $dates = ANFOWO_Date_Resolver::resolve( $period, $start_date, $end_date ); $paid_statuses = ANFOWO_Database::get_paid_statuses_sql(); global $wpdb; // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared $query = $wpdb->prepare( " SELECT cl.customer_id, cl.user_id, cl.email as email, CONCAT(cl.first_name, ' ', cl.last_name) as name, cl.country as country, cl.state as state, COUNT(DISTINCT os.order_id) as orders_count, MAX(os.date_created) as last_order, SUM(os.net_total) as total_spent FROM {$wpdb->prefix}wc_customer_lookup cl JOIN {$wpdb->prefix}wc_order_stats os ON cl.customer_id = os.customer_id WHERE os.status IN ($paid_statuses) AND os.date_created >= %s AND os.date_created <= %s GROUP BY cl.customer_id ORDER BY total_spent DESC ", $dates['start'], $dates['end'] ); // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter $customers = $wpdb->get_results( $query, ARRAY_A ); $data[] = array( 'Customer Name', 'Phone', 'Email', 'Orders', 'Total Spent', 'Last Order', 'Average Order Value', 'Loyalty Badge', 'Total Stars', 'Country', 'District' ); foreach ( $customers as $row ) { $customer_id = $row['customer_id']; $user_id = $row['user_id']; $email = $row['email']; // Phone $phone = ''; if ( $user_id ) { $phone = get_user_meta( $user_id, 'billing_phone', true ); } if ( empty( $phone ) ) { // Try to get from last order $phone_query = $wpdb->prepare( " SELECT pm.meta_value FROM {$wpdb->postmeta} pm JOIN {$wpdb->prefix}wc_order_stats os ON os.order_id = pm.post_id WHERE os.customer_id = %d AND pm.meta_key = '_billing_phone' ORDER BY os.date_created DESC LIMIT 1 ", $customer_id ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter $phone = $wpdb->get_var( $phone_query ); } if ( empty( $phone ) ) { $phone = '-'; } // Average Order Value $orders = (int) $row['orders_count']; $total_spent = (float) $row['total_spent']; $aov = $orders > 0 ? ($total_spent / $orders) : 0.0; // Loyalty Badge based on completed orders count $badge = ANFOWO_Helper::get_customer_badge( $orders ); // Total Stars (Reviews rating sum) $stars_query = $wpdb->prepare( " SELECT SUM(CAST(cm.meta_value AS UNSIGNED)) FROM {$wpdb->comments} c JOIN {$wpdb->commentmeta} cm ON c.comment_ID = cm.comment_ID AND cm.meta_key = 'rating' WHERE c.comment_author_email = %s AND c.comment_approved = '1' ", $email ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter $total_stars = (int) $wpdb->get_var( $stars_query ); $name = trim( $row['name'] ); if ( empty( $name ) ) { $name = 'Guest'; } $resolved_addr = self::resolve_lk_district_city( $row['country'], $row['state'], '' ); $cust_district = $resolved_addr['district']; $data[] = array( $name, $phone, $email, $orders, $total_spent, $row['last_order'], $aov, $badge, $total_stars, $row['country'], $cust_district ); } break; case 'sales': $dates = ANFOWO_Date_Resolver::resolve( $period, $start_date, $end_date ); $paid_statuses = ANFOWO_Database::get_paid_statuses_sql(); global $wpdb; // Fetch all parent products and their sales details // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared $query = $wpdb->prepare( " SELECT p.ID as product_id, p.post_title as name, SUM(CASE WHEN os.order_id IS NOT NULL THEN opl.product_qty ELSE 0 END) as qty_sold, SUM(CASE WHEN os.order_id IS NOT NULL THEN opl.product_gross_revenue ELSE 0 END) as gross_revenue, SUM(CASE WHEN os.order_id IS NOT NULL THEN opl.coupon_amount ELSE 0 END) as discount, SUM(CASE WHEN os.order_id IS NOT NULL THEN opl.product_net_revenue ELSE 0 END) as net_revenue FROM {$wpdb->posts} p LEFT JOIN {$wpdb->prefix}wc_product_meta_lookup pml ON p.ID = pml.product_id LEFT JOIN {$wpdb->prefix}wc_order_product_lookup opl ON p.ID = opl.product_id LEFT JOIN {$wpdb->prefix}wc_order_stats os ON os.order_id = opl.order_id AND os.status IN ($paid_statuses) AND os.date_created >= %s AND os.date_created <= %s WHERE p.post_type = 'product' AND p.post_status = 'publish' GROUP BY p.ID ORDER BY net_revenue DESC, name ASC ", $dates['start'], $dates['end'] ); // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter $products = $wpdb->get_results( $query, ARRAY_A ); $data[] = array( 'Product', 'Publisher', 'Author', 'Translator', 'Category', 'Qty Sold', 'Gross Revenue', 'Discount', 'Net Revenue' ); foreach ( $products as $row ) { $pid = $row['product_id']; $publisher = self::get_product_terms_by_type( $pid, 'publisher' ); $author = self::get_product_terms_by_type( $pid, 'author' ); $translator = self::get_product_terms_by_type( $pid, 'translator' ); $categories = implode( ', ', wp_get_post_terms( $pid, 'product_cat', array( 'fields' => 'names' ) ) ); $product_obj = wc_get_product( $pid ); $regular_price = $product_obj ? (float) $product_obj->get_regular_price() : 0.0; if ( $regular_price <= 0 && $product_obj ) { $regular_price = (float) $product_obj->get_price(); } $qty_sold = (int) $row['qty_sold']; $net_revenue = (float) $row['net_revenue']; if ( $regular_price > 0 && $qty_sold > 0 ) { $gross_revenue = round( $regular_price * $qty_sold, 2 ); $discount = max( 0, round( $gross_revenue - $net_revenue, 2 ) ); } else { $gross_revenue = (float) $row['gross_revenue']; $discount = (float) $row['discount']; } $data[] = array( $row['name'], $publisher, $author, $translator, $categories, $qty_sold, $gross_revenue, $discount, $net_revenue ); } break; case 'orders': $dates = ANFOWO_Date_Resolver::resolve( $period, $start_date, $end_date ); $status = isset( $_GET['status'] ) ? sanitize_text_field( wp_unslash( $_GET['status'] ) ) : 'all'; global $wpdb; $where = "WHERE 1=1"; $where = ANFOWO_Database::append_date_where( $where, 'date_created', $dates['start'], $dates['end'] ); $order_ids_query = "SELECT order_id FROM {$wpdb->prefix}wc_order_stats $where ORDER BY date_created DESC"; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter $order_ids = $wpdb->get_col( $order_ids_query ); $orders = array(); foreach ( $order_ids as $order_id ) { $order = wc_get_order( $order_id ); if ( ! is_a( $order, 'WC_Order' ) ) { continue; } // Apply status filter if not 'all' if ( 'all' !== $status ) { $order_sc = ANFOWO_Helper::normalize_status_slug( $order->get_status() ); if ( $order_sc !== $status ) { continue; } } $orders[] = $order; } $data[] = array( 'Date', 'Order Number', 'Invoice number', 'Shipping Name', 'Shipping address', 'District', 'City', 'Receiver\'s Contact', 'COD', 'Postal Code', 'Email', 'Payer\'s Name', 'Billing Address', 'Books names & Qty', 'Payment Method', 'Payment Status', 'Delivery Method', 'Original Amount', 'Coupon', 'Discount Price', 'Shipping Fee', 'Total', ); foreach ( $orders as $order ) { if ( ! is_a( $order, 'WC_Order' ) ) { continue; } $order_id = $order->get_id(); $order_number = $order->get_order_number(); // Invoice No: Year-IN-order number pattern $order_date_obj = $order->get_date_created(); $year = $order_date_obj ? $order_date_obj->date( 'Y' ) : gmdate( 'Y' ); $invoice_no = $year . '-IN-' . $order_number; $order_date = $order_date_obj ? $order_date_obj->date_i18n( 'Y-m-d H:i:s' ) : ''; // Payer's Name (Billing Name) $billing_first = $order->get_billing_first_name(); $billing_last = $order->get_billing_last_name(); $payer_name = trim( $billing_first . ' ' . $billing_last ); if ( empty( $payer_name ) ) { $payer_name = 'Guest'; } // Shipping Name $shipping_first = method_exists( $order, 'get_shipping_first_name' ) ? $order->get_shipping_first_name() : ''; $shipping_last = method_exists( $order, 'get_shipping_last_name' ) ? $order->get_shipping_last_name() : ''; $shipping_name = trim( $shipping_first . ' ' . $shipping_last ); if ( empty( $shipping_name ) ) { $shipping_name = $payer_name; } $billing_phone = $order->get_billing_phone(); $email = $order->get_billing_email(); // Receiver's Contact (Primary & Alternate Contact Numbers) $shipping_phone = method_exists( $order, 'get_shipping_phone' ) ? $order->get_shipping_phone() : ''; if ( empty( $shipping_phone ) && method_exists( $order, 'get_meta' ) ) { $shipping_phone = $order->get_meta( '_shipping_phone' ); } if ( empty( $shipping_phone ) ) { $shipping_phone = $billing_phone; } $shipping_phone = trim( (string) $shipping_phone ); // Alternate Contact Number $alternate_phone = self::get_order_alternate_phone( $order, $shipping_phone ); $contacts = array(); if ( ! empty( $shipping_phone ) && '-' !== $shipping_phone ) { $contacts[] = $shipping_phone; } if ( ! empty( $alternate_phone ) && '-' !== $alternate_phone ) { $already_present = false; foreach ( $contacts as $c ) { if ( false !== strpos( $c, $alternate_phone ) || false !== strpos( $alternate_phone, $c ) ) { $already_present = true; break; } } if ( ! $already_present ) { $contacts[] = $alternate_phone; } } $receiver_contact = ! empty( $contacts ) ? implode( ', ', $contacts ) : '-'; $billing_address = trim( $order->get_billing_address_1() . ' ' . $order->get_billing_address_2() ); $billing_city_val = $order->get_billing_city(); $billing_state_val = $order->get_billing_state(); // Resolve WooCommerce state code if defined $states = function_exists( 'WC' ) ? WC()->countries->get_states( 'LK' ) : array(); if ( empty( $states ) ) { $states = array( 'LK-11' => 'Colombo', 'LK-12' => 'Gampaha', 'LK-13' => 'Kalutara', 'LK-21' => 'Kandy', 'LK-22' => 'Matale', 'LK-23' => 'Nuwara Eliya', 'LK-31' => 'Galle', 'LK-32' => 'Matara', 'LK-33' => 'Hambantota', 'LK-41' => 'Jaffna', 'LK-42' => 'Kilinochchi', 'LK-43' => 'Mannar', 'LK-44' => 'Vavuniya', 'LK-45' => 'Mullaitivu', 'LK-51' => 'Batticaloa', 'LK-52' => 'Ampara', 'LK-53' => 'Trincomalee', 'LK-61' => 'Kurunegala', 'LK-62' => 'Puttalam', 'LK-71' => 'Anuradhapura', 'LK-72' => 'Polonnaruwa', 'LK-81' => 'Badulla', 'LK-82' => 'Moneragala', 'LK-91' => 'Ratnapura', 'LK-92' => 'Kegalle' ); } $billing_state_name = isset( $states[ $billing_state_val ] ) ? $states[ $billing_state_val ] : $billing_state_val; // Fallback to shipping city if billing city is empty or identical to resolved state name if ( ( empty( $billing_city_val ) || strcasecmp( $billing_city_val, $billing_state_name ) === 0 ) && method_exists( $order, 'get_shipping_city' ) ) { $shipping_city_temp = $order->get_shipping_city(); $shipping_state_val = $order->get_shipping_state(); $shipping_state_name = isset( $states[ $shipping_state_val ] ) ? $states[ $shipping_state_val ] : $shipping_state_val; if ( ! empty( $shipping_city_temp ) && strcasecmp( $shipping_city_temp, $shipping_state_name ) !== 0 ) { $billing_city_val = $shipping_city_temp; } } $resolved_billing = self::resolve_lk_district_city( $order->get_billing_country(), $billing_state_val, $billing_city_val, $billing_address ); $billing_district = $resolved_billing['district']; $billing_city = $resolved_billing['city']; // Resolve Shipping Address $shipping_address = ''; $shipping_district = ''; $shipping_city = ''; if ( method_exists( $order, 'get_shipping_address_1' ) ) { $shipping_address = trim( $order->get_shipping_address_1() . ' ' . $order->get_shipping_address_2() ); $shipping_city_val = $order->get_shipping_city(); $shipping_state_val = $order->get_shipping_state(); $shipping_state_name = isset( $states[ $shipping_state_val ] ) ? $states[ $shipping_state_val ] : $shipping_state_val; // If shipping fields are empty, fallback to billing fields if ( empty( $shipping_address ) && empty( $shipping_city_val ) ) { $shipping_address = $billing_address; $shipping_district = $billing_district; $shipping_city = $billing_city; } else { // If shipping city is empty or same as resolved shipping state name, fallback to billing city if ( ( empty( $shipping_city_val ) || strcasecmp( $shipping_city_val, $shipping_state_name ) === 0 ) && ! empty( $billing_city_val ) ) { $shipping_city_val = $billing_city_val; } $resolved_shipping = self::resolve_lk_district_city( $order->get_shipping_country(), $shipping_state_val, $shipping_city_val, $shipping_address ); $shipping_district = $resolved_shipping['district']; $shipping_city = $resolved_shipping['city']; } } else { // Fallback to billing fields $shipping_address = $billing_address; $shipping_district = $billing_district; $shipping_city = $billing_city; } $postal_code = method_exists( $order, 'get_shipping_postcode' ) && $order->get_shipping_postcode() ? $order->get_shipping_postcode() : $order->get_billing_postcode(); // Books names & Qty formatting $product_details = array(); $total_qty = 0; foreach ( $order->get_items() as $item ) { if ( ! is_object( $item ) ) { continue; } $name = method_exists( $item, 'get_name' ) ? $item->get_name() : ''; $qty = method_exists( $item, 'get_quantity' ) ? $item->get_quantity() : 0; if ( ! empty( $name ) ) { $product_details[] = $name . ' (x' . $qty . ')'; } $total_qty += $qty; } $books_names_qty = implode( ', ', $product_details ); $order_amount = $order->get_subtotal(); // Calculate regular total to find item-level sale discounts $regular_total = 0; foreach ( $order->get_items() as $item ) { if ( ! is_object( $item ) || ! method_exists( $item, 'get_product' ) ) { continue; } $product = $item->get_product(); $qty = method_exists( $item, 'get_quantity' ) ? $item->get_quantity() : 0; if ( $product ) { $regular_price = (float) $product->get_regular_price(); if ( $regular_price <= 0 ) { $regular_price = (float) $product->get_price(); } $regular_total += $regular_price * $qty; } else { $regular_total += method_exists( $item, 'get_subtotal' ) ? (float) $item->get_subtotal() : 0; } } $coupon_discount = (float) $order->get_discount_total(); $sale_discount = 0.0; if ( $regular_total > $order_amount ) { $sale_discount = $regular_total - $order_amount; } // Total discount price is the sum of coupon discounts and item sale discounts $discount_price = round( $coupon_discount + $sale_discount, 2 ); $coupons = implode( ', ', $order->get_coupon_codes() ); $shipping_fee = $order->get_shipping_total(); $total = $order->get_total(); $payment_method = $order->get_payment_method_title(); $payment_method_id = $order->get_payment_method(); $status = $order->get_status(); // Cash on delivery check $is_cod = ( 'cod' === $payment_method_id || stripos( $payment_method, 'cash' ) !== false || stripos( $payment_method, 'cod' ) !== false ); $is_bank_transfer = ( 'bacs' === $payment_method_id || stripos( $payment_method, 'bank' ) !== false || stripos( $payment_method, 'transfer' ) !== false || stripos( $payment_method, 'deposit' ) !== false ); if ( $is_cod ) { $shipped_statuses = array( 'shipped', 'order-shipped', 'completed' ); if ( in_array( $status, $shipped_statuses, true ) || stripos( $status, 'ship' ) !== false ) { $payment_status = 'Paid'; } else { $payment_status = 'Pending'; } } elseif ( $is_bank_transfer ) { $paid_statuses = array( 'processing', 'completed' ); if ( in_array( $status, $paid_statuses, true ) ) { $payment_status = 'Paid'; } else { $payment_status = 'Unpaid'; } } else { $payment_status = $order->is_paid() ? 'Paid' : 'Unpaid'; } // COD column value logic: Output total amount for COD orders, 0 for paid/prepaid orders $cod_value = $is_cod ? $total : 0; $delivery_method = $order->get_shipping_method(); $data[] = array( $order_date, $order_number, $invoice_no, $shipping_name, $shipping_address, $shipping_district, $shipping_city, $receiver_contact, $cod_value, $postal_code, $email, $payer_name, $billing_address, $books_names_qty, $payment_method, $payment_status, $delivery_method, round( $regular_total, 2 ), $coupons, $discount_price, $shipping_fee, $total, ); } break; case 'stock': $dates = ANFOWO_Date_Resolver::resolve( $period, $start_date, $end_date ); $report_data = ANFOWO_Stock_Query::get_report( $dates ); $stock_status = isset( $_GET['stock_status'] ) ? sanitize_text_field( wp_unslash( $_GET['stock_status'] ) ) : 'all'; $publisher_filter = isset( $_GET['publisher'] ) ? sanitize_text_field( wp_unslash( $_GET['publisher'] ) ) : 'all'; $data[] = array( 'Product', 'SKU', 'Publisher', 'Author', 'Translator', 'Price', 'Opening Stock', 'Stock Added', 'Sold', 'Returned', 'Damaged', 'Current Stock', 'Stock Value', 'Stock Status', 'Last Updated', ); if ( ! empty( $report_data['table'] ) ) { foreach ( $report_data['table'] as $row ) { // Apply stock status filter if specified if ( 'all' !== $stock_status && ! empty( $stock_status ) && $row['status'] !== $stock_status ) { continue; } // Apply publisher filter if specified if ( 'all' !== $publisher_filter && ! empty( $publisher_filter ) ) { $row_pub = strtolower( $row['publisher'] ); $pub_list = array_map( 'trim', explode( ',', $row_pub ) ); $filter_lower = strtolower( $publisher_filter ); if ( ! in_array( $filter_lower, $pub_list, true ) && false === strpos( $row_pub, $filter_lower ) ) { continue; } } $pid = $row['id']; $publisher = ! empty( $row['publisher'] ) ? $row['publisher'] : self::get_product_terms_by_type( $pid, 'publisher' ); $author = self::get_product_terms_by_type( $pid, 'author' ); $translator = self::get_product_terms_by_type( $pid, 'translator' ); $damaged = 0; // Default $stock_added = 0; // Default $current_stock = $row['qty']; // $row['qty'] is the Ending Stock for the selected period $stock_value = $current_stock !== null ? ( $current_stock * (float) $row['price'] ) : 0.0; $opening_stock = $row['opening_qty'] !== null ? $row['opening_qty'] : 'Unlimited'; $status_label = __( 'In Stock', '360-analytics-for-woocommerce' ); if ( 'lowstock' === $row['status'] ) { $status_label = __( 'Low Stock', '360-analytics-for-woocommerce' ); } elseif ( 'outofstock' === $row['status'] ) { $status_label = __( 'Out of Stock', '360-analytics-for-woocommerce' ); } $data[] = array( $row['name'], $row['sku'], $publisher, $author, $translator, $row['price'], $opening_stock, $stock_added, $row['sold_qty'], $row['returned_qty'], $damaged, $current_stock !== null ? $current_stock : 'Unlimited', $stock_value, $status_label, $row['last_updated'], ); } } break; } $filename = '360-analytics-' . $report . '-' . $period . '.csv'; if ( 'orders' === $report && isset( $_GET['status'] ) && 'all' !== $_GET['status'] ) { $filename = '360-analytics-' . $report . '-' . sanitize_title( wp_unslash( $_GET['status'] ) ) . '-' . $period . '.csv'; } elseif ( 'stock' === $report ) { $parts = array( '360-analytics', 'stock' ); if ( isset( $_GET['stock_status'] ) && 'all' !== $_GET['stock_status'] && ! empty( $_GET['stock_status'] ) ) { $parts[] = sanitize_title( wp_unslash( $_GET['stock_status'] ) ); } if ( isset( $_GET['publisher'] ) && 'all' !== $_GET['publisher'] && ! empty( $_GET['publisher'] ) ) { $parts[] = sanitize_title( wp_unslash( $_GET['publisher'] ) ); } $parts[] = $period; $filename = implode( '-', $parts ) . '.csv'; } self::output_csv( $filename, $data ); } private static function resolve_lk_district_city( $billing_country, $billing_state, $billing_city, $address = '' ) { $district = $billing_state; $city = $billing_city; if ( 'LK' === $billing_country ) { // Resolve WooCommerce state code if defined $states = function_exists( 'WC' ) ? WC()->countries->get_states( 'LK' ) : array(); if ( empty( $states ) ) { $states = array( 'LK-11' => 'Colombo', 'LK-12' => 'Gampaha', 'LK-13' => 'Kalutara', 'LK-21' => 'Kandy', 'LK-22' => 'Matale', 'LK-23' => 'Nuwara Eliya', 'LK-31' => 'Galle', 'LK-32' => 'Matara', 'LK-33' => 'Hambantota', 'LK-41' => 'Jaffna', 'LK-42' => 'Kilinochchi', 'LK-43' => 'Mannar', 'LK-44' => 'Vavuniya', 'LK-45' => 'Mullaitivu', 'LK-51' => 'Batticaloa', 'LK-52' => 'Ampara', 'LK-53' => 'Trincomalee', 'LK-61' => 'Kurunegala', 'LK-62' => 'Puttalam', 'LK-71' => 'Anuradhapura', 'LK-72' => 'Polonnaruwa', 'LK-81' => 'Badulla', 'LK-82' => 'Moneragala', 'LK-91' => 'Ratnapura', 'LK-92' => 'Kegalle' ); } $state_name = isset( $states[ $billing_state ] ) ? $states[ $billing_state ] : $billing_state; // If state name starts with 'LK' (like LKKIRIBATHGODA), clean it if ( 0 === strpos( $state_name, 'LK' ) && strlen( $state_name ) > 2 ) { $state_name = ucwords( strtolower( substr( $state_name, 2 ) ) ); } // Mapping of common Sri Lankan cities/suburbs to their districts $city_to_district = array( // Colombo District 'akarawita' => 'Colombo', 'aluth mawatha road' => 'Colombo', 'ambalangoda' => 'Colombo', 'ambalangoda town' => 'Colombo', 'anderson plats' => 'Colombo', 'angampitiya' => 'Colombo', 'angulana' => 'Colombo', 'arawwala west' => 'Colombo', 'armour street' => 'Colombo', 'arukwathupura' => 'Colombo', 'athurugiriya' => 'Colombo', 'avissawella' => 'Colombo', 'bambalapitiya' => 'Colombo', 'baseline road' => 'Colombo', 'batawala' => 'Colombo', 'baththaramulla' => 'Colombo', 'battaramulla' => 'Colombo', 'beddagana' => 'Colombo', 'biyagama' => 'Colombo', 'bokundara' => 'Colombo', 'bope' => 'Colombo', 'boralesgamuwa' => 'Colombo', 'borella' => 'Colombo', 'cinnamon gardens' => 'Colombo', 'colombo' => 'Colombo', 'colombo 1' => 'Colombo', 'colombo 10' => 'Colombo', 'colombo 11' => 'Colombo', 'colombo 12' => 'Colombo', 'colombo 13' => 'Colombo', 'colombo 14' => 'Colombo', 'colombo 15' => 'Colombo', 'colombo 2' => 'Colombo', 'colombo 3' => 'Colombo', 'colombo 4' => 'Colombo', 'colombo 5' => 'Colombo', 'colombo 6' => 'Colombo', 'colombo 7' => 'Colombo', 'colombo 8' => 'Colombo', 'colombo 9' => 'Colombo', 'colombo general hospital' => 'Colombo', 'colombo kachcheri' => 'Colombo', 'colombo labour sec' => 'Colombo', 'colombo secretariant' => 'Colombo', 'colpetty' => 'Colombo', 'dampe' => 'Colombo', 'dedigamuwa' => 'Colombo', 'dehiwala' => 'Colombo', 'dehiwela' => 'Colombo','delkanda' => 'Colombo', 'deltara' => 'Colombo', 'dematagoda' => 'Colombo', 'egodauyana north' => 'Colombo', 'egodauyana south' => 'Colombo', 'fort' => 'Colombo', 'galawilawaththa' => 'Colombo', 'gem & jewelry' => 'Colombo', 'godagama junction' => 'Colombo', 'gorakapitiya' => 'Colombo', 'gothami road' => 'Colombo', 'grandpass' => 'Colombo', 'gurulana' => 'Colombo', 'habarakada' => 'Colombo', 'hanwella' => 'Colombo', 'havelock town' => 'Colombo', 'hiripitya' => 'Colombo', 'hokandara' => 'Colombo', 'homagama' => 'Colombo', 'homagama town' => 'Colombo', 'horagala' => 'Colombo', 'hulftsdorp' => 'Colombo', 'indibedda' => 'Colombo', 'isurupaya' => 'Colombo', 'jayawardhenegama' => 'Colombo', 'kaduwela' => 'Colombo', 'kahathuduwa' => 'Colombo', 'kalapaluwawa' => 'Colombo', 'kaldemulla' => 'Colombo', 'kaluaggala' => 'Colombo', 'kandanapitiya' => 'Colombo', 'kapugoda' => 'Colombo', 'katubedda' => 'Colombo', 'katuwawala' => 'Colombo', 'kehelwatta' => 'Colombo', 'keppetipola mawatha' => 'Colombo', 'kesbewa' => 'Colombo', 'kiriwattuduwa' => 'Colombo', 'kirulapone' => 'Colombo', 'kohuwala' => 'Colombo', 'kolombo' => 'Colombo', 'kolonnawa' => 'Colombo', 'kopiyawatta' => 'Colombo', 'koralawella' => 'Colombo', 'kosgama' => 'Colombo', 'kotahena' => 'Colombo', 'kottawa' => 'Colombo', 'kottawa north' => 'Colombo', 'laksapatiya' => 'Colombo', 'liyanwala' => 'Colombo', 'lunawa' => 'Colombo', 'madapatha' => 'Colombo', 'madiwela' => 'Colombo', 'magammana-dolekade' => 'Colombo', 'maharagama' => 'Colombo', 'maharagama town' => 'Colombo', 'makandana' => 'Colombo', 'malabe' => 'Colombo', 'malabe town' => 'Colombo', 'malagala' => 'Colombo', 'malapalla' => 'Colombo', 'maligakanda' => 'Colombo', 'maligawatta' => 'Colombo', 'maradana' => 'Colombo', 'mattegoda' => 'Colombo', 'meepe junction' => 'Colombo', 'melle street' => 'Colombo', 'miraniya street' => 'Colombo', 'mirihana' => 'Colombo', 'mirihana north' => 'Colombo', 'modara' => 'Colombo', 'moratumulla' => 'Colombo', 'moratuwa' => 'Colombo', 'moratuwa town' => 'Colombo', 'mount lavinia' => 'Colombo', 'mullegama' => 'Colombo', 'mutwal south' => 'Colombo', 'nagalagam street' => 'Colombo', 'napawela' => 'Colombo', 'narahenpita' => 'Colombo', 'national museum of colombo' => 'Colombo', 'nawala' => 'Colombo', 'nawala-koswatte' => 'Colombo', 'nawinna' => 'Colombo', 'nugegoda' => 'Colombo', 'nugegoda town' => 'Colombo', 'obeysekarapura' => 'Colombo', 'oruwala' => 'Colombo', 'padukka' => 'Colombo', 'pamunuwa-patiragoda' => 'Colombo', 'panagoda' => 'Colombo', 'panagoda army camp' => 'Colombo', 'panchikawatte' => 'Colombo', 'pannipitiya' => 'Colombo', 'parliament of sri lanka' => 'Colombo', 'pelenwatta' => 'Colombo', 'pepiliyana' => 'Colombo', 'pettah' => 'Colombo', 'pettah bus stand' => 'Colombo', 'piliyandala' => 'Colombo', 'piliyandala town' => 'Colombo', 'pinnawala-waga' => 'Colombo', 'pitipana homagama' => 'Colombo', 'polgasowita' => 'Colombo', 'polhengoda' => 'Colombo', 'poregedara' => 'Colombo', 'pugoda' => 'Colombo', 'rajagiriya' => 'Colombo', 'ranala' => 'Colombo', 'ratmalana' => 'Colombo', 'ratmalana north' => 'Colombo', 'rawathawatta' => 'Colombo', 'rifel street' => 'Colombo', 'rukmale-pannipitiya' => 'Colombo', 'sarasavipaya' => 'Colombo', 'sethsiripaya' => 'Colombo', 'siddamulla' => 'Colombo', 'sirimal uyana' => 'Colombo', 'siyambalagoda' => 'Colombo', 'slave island' => 'Colombo', 'sri jayawardenepura' => 'Colombo', 'sri perakumpura' => 'Colombo', 'st. anthony\'s' => 'Colombo', 'sudanapura' => 'Colombo', 'suwarapola' => 'Colombo', 'talangama north' => 'Colombo', 'talangama south' => 'Colombo', 'talawatugoda' => 'Colombo', 'torington square' => 'Colombo', 'tummodara' => 'Colombo', 'udahamulla' => 'Colombo', 'udugamkanda' => 'Colombo', 'university of colombo' => 'Colombo', 'vidyodaya university' => 'Colombo', 'waga' => 'Colombo', 'wanathamulla' => 'Colombo', 'wasala road' => 'Colombo', 'wellawatta' => 'Colombo', 'wellampitiya' => 'Colombo', 'willorawatta' => 'Colombo', 'wolfendal street' => 'Colombo', // Gampaha District 'akaragama' => 'Gampaha', 'ambagaspitiya' => 'Gampaha', 'ambepussa' => 'Gampaha', 'andiambalama' => 'Gampaha', 'attanagalla' => 'Gampaha', 'badalgama' => 'Gampaha', 'banduragoda' => 'Gampaha', 'batuwatta' => 'Gampaha', 'bemmulla' => 'Gampaha', 'biyagama ipz' => 'Gampaha', 'bokalagama' => 'Gampaha', 'bollete' => 'Gampaha', 'bopagama' => 'Gampaha', 'buthpitiya' => 'Gampaha', 'dagonna' => 'Gampaha', 'danowita' => 'Gampaha', 'debahera' => 'Gampaha', 'dekatana' => 'Gampaha', 'delgoda' => 'Gampaha', 'delwagura' => 'Gampaha', 'demalagama' => 'Gampaha', 'demanhandiya' => 'Gampaha', 'dewalapola' => 'Gampaha', 'divulapitiya' => 'Gampaha', 'divuldeniya' => 'Gampaha', 'dompe' => 'Gampaha', 'dunagaha' => 'Gampaha', 'ekala' => 'Gampaha', 'ellakkala' => 'Gampaha', 'essella' => 'Gampaha', 'galedanda' => 'Gampaha', 'gampaha' => 'Gampaha', 'gampaha town' => 'Gampaha', 'gampaha-town' => 'Gampaha', 'ganemulla' => 'Gampaha', 'giriulla' => 'Gampaha', 'gonawala' => 'Gampaha', 'halpe' => 'Gampaha', 'hapugastenna' => 'Gampaha', 'heiyanthuduwa' => 'Gampaha', 'hinatiyana madawala' => 'Gampaha', 'hiswella' => 'Gampaha', 'horampella' => 'Gampaha', 'hunumulla' => 'Gampaha', 'hunupola' => 'Gampaha', 'ihala madampella' => 'Gampaha', 'imbulgoda' => 'Gampaha', 'ja ela' => 'Gampaha', 'ja-ela' => 'Gampaha', 'kadawatha' => 'Gampaha', 'kadawatha town' => 'Gampaha', 'kahatowita' => 'Gampaha', 'kalagedihena' => 'Gampaha', 'kaleliya' => 'Gampaha', 'kandana' => 'Gampaha', 'katana' => 'Gampaha', 'katudeniya' => 'Gampaha', 'katunayake' => 'Gampaha', 'katunayake air force camp' => 'Gampaha', 'katuwellegama' => 'Gampaha', 'kelaniya' => 'Gampaha', 'kimbulapitiya' => 'Gampaha', 'kirindiwela' => 'Gampaha', 'kitalawalana' => 'Gampaha', 'kochchikade' => 'Gampaha', 'kotadeniyawa' => 'Gampaha', 'kotugoda' => 'Gampaha', 'kumbaloluwa' => 'Gampaha', 'loluwagoda' => 'Gampaha', 'mabodale' => 'Gampaha', 'mabola' => 'Gampaha', 'madelgamuwa' => 'Gampaha', 'makewita' => 'Gampaha', 'makola' => 'Gampaha', 'malwana' => 'Gampaha', 'mandawala' => 'Gampaha', 'marandagahamula' => 'Gampaha', 'mellawagedara' => 'Gampaha', 'minuwangoda' => 'Gampaha', 'mirigama' => 'Gampaha', 'miriswatta' => 'Gampaha', 'mithirigala' => 'Gampaha', 'muddaragama' => 'Gampaha', 'mudungoda' => 'Gampaha', 'mulleriyawa new town' => 'Gampaha', 'naranwala' => 'Gampaha', 'nawana' => 'Gampaha', 'nedungamuwa' => 'Gampaha', 'negombo' => 'Gampaha', 'negombo town' => 'Gampaha', 'nikadalupotha' => 'Gampaha', 'nikahetikanda' => 'Gampaha', 'nittambuwa' => 'Gampaha', 'niwandama' => 'Gampaha', 'opatha' => 'Gampaha', 'pamunugama' => 'Gampaha', 'pamunuwatta' => 'Gampaha', 'panawala' => 'Gampaha', 'pasyala' => 'Gampaha', 'peliyagoda' => 'Gampaha', 'pepiliyawala' => 'Gampaha', 'pethiyagoda' => 'Gampaha', 'polpithimukulana' => 'Gampaha', 'puwakpitiya' => 'Gampaha', 'radawadunna' => 'Gampaha', 'radawana' => 'Gampaha', 'raddolugama' => 'Gampaha', 'ragama' => 'Gampaha', 'ruggahawila' => 'Gampaha', 'seeduwa' => 'Gampaha', 'siyambalape' => 'Gampaha', 'talahena' => 'Gampaha', 'thambagalla' => 'Gampaha', 'thimbirigaskatuwa' => 'Gampaha', 'tittapattara' => 'Gampaha', 'udathuthiripitiya' => 'Gampaha', 'udugampola' => 'Gampaha', 'uggalboda' => 'Gampaha', 'urapola' => 'Gampaha', 'uswetakeiyawa' => 'Gampaha', 'veyangoda' => 'Gampaha', 'walgammulla' => 'Gampaha', 'walpita' => 'Gampaha', 'walpola' => 'Gampaha', 'wathurugama' => 'Gampaha', 'watinapaha' => 'Gampaha', 'wattala' => 'Gampaha', 'wattala town' => 'Gampaha', 'weboda' => 'Gampaha', 'wegowwa' => 'Gampaha', 'weweldeniya' => 'Gampaha', 'yakkala' => 'Gampaha', 'yatiyana' => 'Gampaha', // Kalutara District 'agalawatta' => 'Kalutara', 'alubomulla' => 'Kalutara', 'anguruwatota' => 'Kalutara', 'atale' => 'Kalutara', 'baduraliya' => 'Kalutara', 'bandaragama' => 'Kalutara', 'batugampola' => 'Kalutara', 'bellana' => 'Kalutara', 'beruwala' => 'Kalutara', 'bolossagama' => 'Kalutara', 'bombuwala' => 'Kalutara', 'boralugoda' => 'Kalutara', 'bulathsinhala' => 'Kalutara', 'calutara' => 'Kalutara', 'danawala thiniyawala' => 'Kalutara', 'delmella' => 'Kalutara', 'dharga town' => 'Kalutara', 'diwalakada' => 'Kalutara', 'dodangoda' => 'Kalutara', 'dombagoda' => 'Kalutara', 'ethkandura' => 'Kalutara', 'galpatha' => 'Kalutara', 'gamagoda' => 'Kalutara', 'gonagalpura' => 'Kalutara', 'gonapola junction' => 'Kalutara', 'govinna' => 'Kalutara', 'gurulubadda' => 'Kalutara', 'halkandawila' => 'Kalutara', 'haltota' => 'Kalutara', 'halvitigala colony' => 'Kalutara', 'halwala' => 'Kalutara', 'halwatura' => 'Kalutara', 'handapangoda' => 'Kalutara', 'hedigalla colony' => 'Kalutara', 'henegama' => 'Kalutara', 'hettimulla' => 'Kalutara', 'horana' => 'Kalutara', 'horana town' => 'Kalutara', 'ihalahewessa' => 'Kalutara', 'induruwa' => 'Kalutara', 'ingiriya' => 'Kalutara', 'ittapana' => 'Kalutara', 'kahawala' => 'Kalutara', 'kalawila kiranthidiya' => 'Kalutara', 'kalutara' => 'Kalutara', 'kananwila' => 'Kalutara', 'kandanagama' => 'Kalutara', 'kelinkanda' => 'Kalutara', 'kitulgoda' => 'Kalutara', 'koholana' => 'Kalutara', 'kuda uduwa' => 'Kalutara', 'labbala' => 'Kalutara', 'maggona' => 'Kalutara', 'mahagama' => 'Kalutara', 'mahakalupahana' => 'Kalutara', 'maharangalla' => 'Kalutara', 'malgalla talangalla' => 'Kalutara', 'matugama' => 'Kalutara', 'meegahatenna' => 'Kalutara', 'meegama' => 'Kalutara', 'meegoda' => 'Kalutara', 'millaniya' => 'Kalutara', 'millewa' => 'Kalutara', 'miwanapalana' => 'Kalutara', 'molkawa' => 'Kalutara', 'morapitiya' => 'Kalutara', 'morontuduwa' => 'Kalutara', 'nawattuduwa' => 'Kalutara', 'neboda' => 'Kalutara', 'padagoda' => 'Kalutara', 'pahalahewessa' => 'Kalutara', 'paiyagala' => 'Kalutara', 'panadura' => 'Kalutara', 'panadura town' => 'Kalutara', 'pannala' => 'Kalutara', 'paragastota' => 'Kalutara', 'paragoda' => 'Kalutara', 'paraigama' => 'Kalutara', 'pelanda' => 'Kalutara', 'pelawatta' => 'Kalutara', 'pimbura' => 'Kalutara', 'pitagaldeniya' => 'Kalutara', 'pokunuwita' => 'Kalutara', 'poruwedanda' => 'Kalutara', 'ratmale' => 'Kalutara', 'remunagoda' => 'Kalutara', 'talgaswela' => 'Kalutara', 'tebuwana' => 'Kalutara', 'uduwara' => 'Kalutara', 'utumgama' => 'Kalutara', 'veyangalla' => 'Kalutara', 'wadduwa' => 'Kalutara', 'walagedara' => 'Kalutara', 'walallawita' => 'Kalutara', 'waskaduwa' => 'Kalutara', 'welipenna' => 'Kalutara', 'weliveriya' => 'Kalutara', 'welmilla junction' => 'Kalutara', 'weragala' => 'Kalutara', 'yagirala' => 'Kalutara', 'yatadolawatta' => 'Kalutara', 'yatawara junction' => 'Kalutara', // Kandy District 'akurana' => 'Kandy', 'aludeniya' => 'Kandy', 'ambagahapelessa' => 'Kandy', 'ambagamuwa udabulathgama' => 'Kandy', 'ambatenna' => 'Kandy', 'ampitiya' => 'Kandy', 'ankumbura' => 'Kandy', 'atabage' => 'Kandy', 'balana' => 'Kandy', 'bambaragahaela' => 'Kandy', 'batagolladeniya' => 'Kandy', 'batugoda' => 'Kandy', 'batumulla' => 'Kandy', 'bawlana' => 'Kandy', 'bopana' => 'Kandy', 'danture' => 'Kandy', 'dedunupitiya' => 'Kandy', 'dekinda' => 'Kandy', 'deltota' => 'Kandy', 'divulankadawala' => 'Kandy', 'dolapihilla' => 'Kandy', 'dolosbage' => 'Kandy', 'dunuwila' => 'Kandy', 'etulgama' => 'Kandy', 'galaboda' => 'Kandy', 'galagedara' => 'Kandy', 'galaha' => 'Kandy', 'galhinna' => 'Kandy', 'gampola' => 'Kandy', 'gampola town' => 'Kandy', 'gelioya' => 'Kandy', 'godamunna' => 'Kandy', 'gomagoda' => 'Kandy', 'gonagantenna' => 'Kandy', 'gonawalapatana' => 'Kandy', 'gunnepana' => 'Kandy', 'gurudeniya' => 'Kandy', 'hakmana' => 'Kandy', 'handaganawa' => 'Kandy', 'handawalapitiya' => 'Kandy', 'handessa' => 'Kandy', 'harangalagama' => 'Kandy', 'hataraliyadda' => 'Kandy', 'hindagala' => 'Kandy', 'hondiyadeniya' => 'Kandy', 'hunnasgiriya' => 'Kandy', 'ihala kobbekaduwa' => 'Kandy', 'inguruwatta' => 'Kandy', 'jambugahapitiya' => 'Kandy', 'kadugannawa' => 'Kandy', 'kahataliyadda' => 'Kandy', 'kalugala' => 'Kandy', 'kandi' => 'Kandy', 'kandy' => 'Kandy', 'kapuliyadde' => 'Kandy', 'katugastota' => 'Kandy', 'katukitula' => 'Kandy', 'kelanigama' => 'Kandy', 'kengalla' => 'Kandy', 'ketaboola' => 'Kandy', 'ketakumbura' => 'Kandy', 'kobonila' => 'Kandy', 'kolabissa' => 'Kandy', 'kolongoda' => 'Kandy', 'kulugammana' => 'Kandy', 'kumbukkandura' => 'Kandy', 'kumburegama' => 'Kandy', 'kundasale' => 'Kandy', 'leemagahakotuwa' => 'Kandy', 'lunugama' => 'Kandy', 'lunuketiya maditta' => 'Kandy', 'madawala bazaar' => 'Kandy', 'madawalalanda' => 'Kandy', 'madugalla' => 'Kandy', 'madulkele' => 'Kandy', 'mahadoraliyadda' => 'Kandy', 'mahamedagama' => 'Kandy', 'mahanagapura' => 'Kandy', 'mahanuwara' => 'Kandy', 'mailapitiya' => 'Kandy', 'makkanigama' => 'Kandy', 'makuldeniya' => 'Kandy', 'mangalagama' => 'Kandy', 'mapakanda' => 'Kandy', 'marassana' => 'Kandy', 'mawatura' => 'Kandy', 'medamahanuwara' => 'Kandy', 'medawala harispattuwa' => 'Kandy', 'meetalawa' => 'Kandy', 'megoda kalugamuwa' => 'Kandy', 'menikdiwela' => 'Kandy', 'menikhinna' => 'Kandy', 'mimure' => 'Kandy', 'minigamuwa' => 'Kandy', 'minipe' => 'Kandy', 'moragahapallama' => 'Kandy', 'murutalawa' => 'Kandy', 'muruthagahamulla' => 'Kandy', 'nanuoya' => 'Kandy', 'naranpanawa' => 'Kandy', 'narawelpita' => 'Kandy', 'nawalapitiya' => 'Kandy', 'nawathispane' => 'Kandy', 'nillambe' => 'Kandy', 'nugaliyadda' => 'Kandy', 'ovilikanda' => 'Kandy', 'pallekotuwa' => 'Kandy', 'panwilatenna' => 'Kandy', 'paradeka' => 'Kandy', 'pasbage' => 'Kandy', 'pattitalawa' => 'Kandy', 'peradeniya' => 'Kandy', 'pilimatalawa' => 'Kandy', 'poholiyadda' => 'Kandy', 'pubbiliya' => 'Kandy', 'pupuressa' => 'Kandy', 'pussellawa' => 'Kandy', 'putuhapuwa' => 'Kandy', 'rajawella' => 'Kandy', 'rambukpitiya' => 'Kandy', 'rambukwella' => 'Kandy', 'rangala' => 'Kandy', 'rantembe' => 'Kandy', 'sangarajapura' => 'Kandy', 'senarathwela' => 'Kandy', 'talatuoya' => 'Kandy', 'teldeniya' => 'Kandy', 'tennekumbura' => 'Kandy', 'uda peradeniya' => 'Kandy', 'udahentenna' => 'Kandy', 'udatalawinna' => 'Kandy', 'udispattuwa' => 'Kandy', 'ududumbara' => 'Kandy', 'uduwahinna' => 'Kandy', 'uduwela' => 'Kandy', 'ulapane' => 'Kandy', 'unuwinna' => 'Kandy', 'velamboda' => 'Kandy', 'watagoda' => 'Kandy', 'watagoda harispattuwa' => 'Kandy', 'wattappola' => 'Kandy', 'weligampola' => 'Kandy', 'wendaruwa' => 'Kandy', 'weragantota' => 'Kandy', 'werapitya' => 'Kandy', 'werellagama' => 'Kandy', 'wettawa' => 'Kandy', 'yahalatenna' => 'Kandy', 'yatihalagala' => 'Kandy', // Matale District 'akuramboda' => 'Matale', 'alawatuwala' => 'Matale', 'alwatta' => 'Matale', 'ambana' => 'Matale', 'aralaganwila' => 'Matale', 'ataragallewa' => 'Matale', 'bambaragaswewa' => 'Matale', 'barawardhana oya' => 'Matale', 'beligamuwa' => 'Matale', 'damana' => 'Matale', 'dambulla' => 'Matale', 'dambulla town' => 'Matale', 'damminna' => 'Matale', 'dankanda' => 'Matale', 'delwite' => 'Matale', 'devagiriya' => 'Matale', 'dewahuwa' => 'Matale', 'divuldamana' => 'Matale', 'dullewa' => 'Matale', 'dunkolawatta' => 'Matale', 'elkaduwa' => 'Matale', 'erawula junction' => 'Matale', 'etanawala' => 'Matale', 'galewela' => 'Matale', 'galoya junction' => 'Matale', 'gammaduwa' => 'Matale', 'gangala puwakpitiya' => 'Matale', 'hasalaka' => 'Matale', 'hattota amuna' => 'Matale', 'ihala halmillewa' => 'Matale', 'illukkumbura' => 'Matale', 'imbulgolla' => 'Matale', 'inamaluwa' => 'Matale', 'iriyagolla' => 'Matale', 'kaikawala' => 'Matale', 'kalundawa' => 'Matale', 'kandalama' => 'Matale', 'kavudupelella' => 'Matale', 'kibissa' => 'Matale', 'kiwula' => 'Matale', 'kongahawela' => 'Matale', 'laggala pallegama' => 'Matale', 'leliambe' => 'Matale', 'lenadora' => 'Matale', 'madipola' => 'Matale', 'mahawela' => 'Matale', 'mananwatta' => 'Matale', 'maraka' => 'Matale', 'matale' => 'Matale', 'mathale' => 'Matale', 'melipitiya' => 'Matale', 'metihakka' => 'Matale', 'millawana' => 'Matale', 'muwandeniya' => 'Matale', 'nalanda' => 'Matale', 'naula' => 'Matale', 'opalgala' => 'Matale', 'pallepola' => 'Matale', 'pimburattewa' => 'Matale', 'pulastigama' => 'Matale', 'ranamuregama' => 'Matale', 'rattota' => 'Matale', 'selagama' => 'Matale', 'sigiriya' => 'Matale', 'sinhagama' => 'Matale', 'sungavila' => 'Matale', 'talagoda junction' => 'Matale', 'talakiriyagama' => 'Matale', 'tamankaduwa' => 'Matale', 'udasgiriya' => 'Matale', 'udatenna' => 'Matale', 'ukuwela' => 'Matale', 'wahacotte' => 'Matale', 'walawela' => 'Matale', 'wehigala' => 'Matale', 'welangahawatte' => 'Matale', 'wewalawewa' => 'Matale', 'yatawatta' => 'Matale', // Nuwara Eliya District 'agarapathana' => 'Nuwara Eliya', 'ambatalawa' => 'Nuwara Eliya', 'ambewela' => 'Nuwara Eliya', 'bogawantalawa' => 'Nuwara Eliya', 'bopattalawa' => 'Nuwara Eliya', 'dagampitiya' => 'Nuwara Eliya', 'dayagama bazaar' => 'Nuwara Eliya', 'dikoya' => 'Nuwara Eliya', 'doragala' => 'Nuwara Eliya', 'dunukedeniya' => 'Nuwara Eliya', 'egodawela' => 'Nuwara Eliya', 'ekiriya' => 'Nuwara Eliya', 'elamulla' => 'Nuwara Eliya', 'ginigathena' => 'Nuwara Eliya', 'gonakele' => 'Nuwara Eliya', 'haggala' => 'Nuwara Eliya', 'halgranoya' => 'Nuwara Eliya', 'hangarapitiya' => 'Nuwara Eliya', 'hanguranketha' => 'Nuwara Eliya', 'hapugasthalawa' => 'Nuwara Eliya', 'harasbedda' => 'Nuwara Eliya', 'hatton' => 'Nuwara Eliya', 'hatton town' => 'Nuwara Eliya', 'hewaheta' => 'Nuwara Eliya', 'hitigegama' => 'Nuwara Eliya', 'jangulla' => 'Nuwara Eliya', 'kalaganwatta' => 'Nuwara Eliya', 'kandapola' => 'Nuwara Eliya', 'karandagolla' => 'Nuwara Eliya', 'keerthi bandarapura' => 'Nuwara Eliya', 'kiribathkumbura' => 'Nuwara Eliya', 'kotiyagala' => 'Nuwara Eliya', 'kotmale' => 'Nuwara Eliya', 'kottellena' => 'Nuwara Eliya', 'kumbalgamuwa' => 'Nuwara Eliya', 'kumbukwela' => 'Nuwara Eliya', 'kurupanawela' => 'Nuwara Eliya', 'labukele' => 'Nuwara Eliya', 'laxapana' => 'Nuwara Eliya', 'lindula' => 'Nuwara Eliya', 'madulla' => 'Nuwara Eliya', 'mandaram nuwara' => 'Nuwara Eliya', 'marymount colony' => 'Nuwara Eliya', 'maskeliya' => 'Nuwara Eliya', 'maswela' => 'Nuwara Eliya', 'maturata' => 'Nuwara Eliya', 'mipanawa' => 'Nuwara Eliya', 'mipilimana' => 'Nuwara Eliya', 'morahenagama' => 'Nuwara Eliya', 'munwatta' => 'Nuwara Eliya', 'nayapana janapadaya' => 'Nuwara Eliya', 'nildandahinna' => 'Nuwara Eliya', 'nissanka uyana' => 'Nuwara Eliya', 'norwood' => 'Nuwara Eliya', 'nuwara eliya' => 'Nuwara Eliya', 'nuwara-eliya' => 'Nuwara Eliya', 'padiyapelella' => 'Nuwara Eliya', 'pallebowala' => 'Nuwara Eliya', 'panvila' => 'Nuwara Eliya', 'pitawala' => 'Nuwara Eliya', 'pundaluoya' => 'Nuwara Eliya', 'ramboda' => 'Nuwara Eliya', 'rikillagaskada' => 'Nuwara Eliya', 'rozella' => 'Nuwara Eliya', 'rupaha' => 'Nuwara Eliya', 'ruwaneliya' => 'Nuwara Eliya', 'santhipura' => 'Nuwara Eliya', 'talawakele' => 'Nuwara Eliya', 'tawalantenna' => 'Nuwara Eliya', 'teripeha' => 'Nuwara Eliya', 'udamadura' => 'Nuwara Eliya', 'udapussallawa' => 'Nuwara Eliya', 'uva deegalla' => 'Nuwara Eliya', 'uva uduwara' => 'Nuwara Eliya', 'uvaparanagama' => 'Nuwara Eliya', 'walapane' => 'Nuwara Eliya', 'watawala' => 'Nuwara Eliya', 'widulipura' => 'Nuwara Eliya', 'wijebahukanda' => 'Nuwara Eliya', // Galle District 'agaliya' => 'Galle', 'ahangama' => 'Galle', 'ahungalla' => 'Galle', 'akmeemana' => 'Galle', 'alawatugoda' => 'Galle', 'aluthwala' => 'Galle', 'ampegama' => 'Galle', 'amugoda' => 'Galle', 'anangoda' => 'Galle', 'angulugaha' => 'Galle', 'ankokkawala' => 'Galle', 'aselapura' => 'Galle', 'baddegama' => 'Galle', 'balapitiya' => 'Galle', 'banagala' => 'Galle', 'batapola' => 'Galle', 'bentota' => 'Galle', 'boossa' => 'Galle', 'dellawa' => 'Galle', 'dikkumbura' => 'Galle', 'dodanduwa' => 'Galle', 'ella tanabaddegama' => 'Galle', 'elpitiya' => 'Galle', 'galla' => 'Galle', 'galle' => 'Galle', 'ginimellagaha' => 'Galle', 'gintota' => 'Galle', 'godahena' => 'Galle', 'gonamulla junction' => 'Galle', 'gonapinuwala' => 'Galle', 'habaraduwa' => 'Galle', 'haburugala' => 'Galle', 'hikkaduwa' => 'Galle', 'hikkaduwa town' => 'Galle', 'hiniduma' => 'Galle', 'hiyare' => 'Galle', 'kahaduwa' => 'Galle', 'kahawa' => 'Galle', 'karagoda' => 'Galle', 'karandeniya' => 'Galle', 'kosgoda' => 'Galle', 'kottawagama' => 'Galle', 'kottegoda' => 'Galle', 'kuleegoda' => 'Galle', 'magedara' => 'Galle', 'mahawela sinhapura' => 'Galle', 'mapalagama' => 'Galle', 'mapalagama central' => 'Galle', 'mattaka' => 'Galle', 'meda-keembiya' => 'Galle', 'meetiyagoda' => 'Galle', 'nagoda' => 'Galle', 'nakiyadeniya' => 'Galle', 'nawandagala' => 'Galle', 'neluwa' => 'Galle', 'nindana' => 'Galle', 'pahala millawa' => 'Galle', 'panangala' => 'Galle', 'pannimulla panagoda' => 'Galle', 'parana thanayamgoda' => 'Galle', 'patana' => 'Galle', 'pitigala' => 'Galle', 'poddala' => 'Galle', 'polgampola' => 'Galle', 'porawagama' => 'Galle', 'rantotuwila' => 'Galle', 'talagampola' => 'Galle', 'talgaspe' => 'Galle', 'talpe' => 'Galle', 'tawalama' => 'Galle', 'tiranagama' => 'Galle', 'udalamatta' => 'Galle', 'udugama' => 'Galle', 'uluvitike' => 'Galle', 'unawatuna' => 'Galle', 'unawitiya' => 'Galle', 'uragaha' => 'Galle', 'uragasmanhandiya' => 'Galle', 'wakwella' => 'Galle', 'walahanduwa' => 'Galle', 'wanchawela' => 'Galle', 'wanduramba' => 'Galle', 'warukandeniya' => 'Galle', 'watugedara' => 'Galle', 'weihena' => 'Galle', 'welikanda' => 'Galle', 'wilanagama' => 'Galle', 'yakkalamulla' => 'Galle', 'yatalamatta' => 'Galle', // Matara District 'akuressa' => 'Matara', 'alapaladeniya' => 'Matara', 'aparekka' => 'Matara', 'athuraliya' => 'Matara', 'bengamuwa' => 'Matara', 'bopagoda' => 'Matara', 'dampahala' => 'Matara', 'deegala lenama' => 'Matara', 'deiyandara' => 'Matara', 'denagama' => 'Matara', 'denipitiya' => 'Matara', 'deniyaya' => 'Matara', 'derangala' => 'Matara', 'devinuwara' => 'Matara', 'dikwella' => 'Matara', 'diyagaha' => 'Matara', 'diyalape' => 'Matara', 'gandara' => 'Matara', 'godapitiya' => 'Matara', 'gomilamawarala' => 'Matara', 'hawpe' => 'Matara', 'horapawita' => 'Matara', 'kalubowitiyana' => 'Matara', 'kamburugamuwa' => 'Matara', 'kamburupitiya' => 'Matara', 'karagoda uyangoda' => 'Matara', 'karaputugala' => 'Matara', 'karatota' => 'Matara', 'kekanadura' => 'Matara', 'kiriweldola' => 'Matara', 'kiriwelkele' => 'Matara', 'kolawenigama' => 'Matara', 'kotapola' => 'Matara', 'lankagama' => 'Matara', 'makandura' => 'Matara', 'maliduwa' => 'Matara', 'maramba' => 'Matara', 'matara' => 'Matara', 'mathara' => 'Matara', 'mediripitiya' => 'Matara', 'miella' => 'Matara', 'mirissa' => 'Matara', 'morawaka' => 'Matara', 'mulatiyana junction' => 'Matara', 'nadugala' => 'Matara', 'naimana' => 'Matara', 'palatuwa' => 'Matara', 'parapamulla' => 'Matara', 'pasgoda' => 'Matara', 'penetiyana' => 'Matara', 'pitabeddara' => 'Matara', 'puhulwella' => 'Matara', 'radawela' => 'Matara', 'ransegoda' => 'Matara', 'rotumba' => 'Matara', 'sultanagoda' => 'Matara', 'telijjawila' => 'Matara', 'thihagoda' => 'Matara', 'urubokka' => 'Matara', 'urugamuwa' => 'Matara', 'urumutta' => 'Matara', 'viharahena' => 'Matara', 'walakanda' => 'Matara', 'walasgala' => 'Matara', 'waralla' => 'Matara', 'weligama' => 'Matara', 'weligama town' => 'Matara', 'wilpita' => 'Matara', 'yatiyana' => 'Matara', // Hambantota District 'ambalantota' => 'Hambantota', 'angunakolapelessa' => 'Hambantota', 'angunakolawewa' => 'Hambantota', 'bandagiriya colony' => 'Hambantota', 'barawakumbuka' => 'Hambantota', 'beliatta' => 'Hambantota', 'beragama' => 'Hambantota', 'beralihela' => 'Hambantota', 'bundala' => 'Hambantota', 'ellagala' => 'Hambantota', 'gangulandeniya' => 'Hambantota', 'getamanna' => 'Hambantota', 'goda koggalla' => 'Hambantota', 'gonagamuwa uduwila' => 'Hambantota', 'gonnoruwa' => 'Hambantota', 'hakuruwela' => 'Hambantota', 'hambanthota' => 'Hambantota', 'hambantota' => 'Hambantota', 'handugala' => 'Hambantota', 'hungama' => 'Hambantota', 'ihala beligalla' => 'Hambantota', 'iththa demaliya' => 'Hambantota', 'julampitiya' => 'Hambantota', 'kahandamodara' => 'Hambantota', 'kariyamaditta' => 'Hambantota', 'katuwana' => 'Hambantota', 'kawantissapura' => 'Hambantota', 'kirama' => 'Hambantota', 'kirinda' => 'Hambantota', 'lunama' => 'Hambantota', 'lunugamwehera' => 'Hambantota', 'magama' => 'Hambantota', 'mahagalwewa' => 'Hambantota', 'mamadala' => 'Hambantota', 'medamulana' => 'Hambantota', 'meegahajandura' => 'Hambantota', 'middeniya' => 'Hambantota', 'modarawana' => 'Hambantota', 'mulkirigala' => 'Hambantota', 'nakulugamuwa' => 'Hambantota', 'netolpitiya' => 'Hambantota', 'nihiluwa' => 'Hambantota', 'padawkema' => 'Hambantota', 'pahala andarawewa' => 'Hambantota', 'rammalawarapitiya' => 'Hambantota', 'ranakeliya' => 'Hambantota', 'ranmuduwewa' => 'Hambantota', 'ranna' => 'Hambantota', 'ratmalwala' => 'Hambantota', 'ruhunu ridiyagama' => 'Hambantota', 'sooriyawewa town' => 'Hambantota', 'tangalla' => 'Hambantota', 'tissamaharama' => 'Hambantota', 'uda gomadiya' => 'Hambantota', 'udamattala' => 'Hambantota', 'uswewa' => 'Hambantota', 'vitharandeniya' => 'Hambantota', 'walasmulla' => 'Hambantota', 'weeraketiya' => 'Hambantota', 'weerawila' => 'Hambantota', 'weerawila newtown' => 'Hambantota', 'wekandawela' => 'Hambantota', 'weligatta' => 'Hambantota', 'yatigala' => 'Hambantota', // Jaffna District 'allaipiddi' => 'Jaffna', 'allaveddi' => 'Jaffna', 'alvai' => 'Jaffna', 'anaikoddai' => 'Jaffna', 'analaitivu' => 'Jaffna', 'araly' => 'Jaffna', 'atchuveli' => 'Jaffna', 'chankanai' => 'Jaffna', 'chavakachcheri' => 'Jaffna', 'chullipuram' => 'Jaffna', 'chundikuli' => 'Jaffna', 'chunnakam' => 'Jaffna', 'delft' => 'Jaffna', 'delft west' => 'Jaffna', 'eluvaitivu' => 'Jaffna', 'erialai' => 'Jaffna', 'gurunagar' => 'Jaffna', 'ilavalai' => 'Jaffna', 'jaffna' => 'Jaffna', 'kaitadi' => 'Jaffna', 'kankesanthurai' => 'Jaffna', 'karainagar' => 'Jaffna', 'karaveddi' => 'Jaffna', 'kayts' => 'Jaffna', 'kodikamam' => 'Jaffna', 'kokuvil' => 'Jaffna', 'kondavil' => 'Jaffna', 'kopay' => 'Jaffna', 'kudatanai' => 'Jaffna', 'mahiyampathy' => 'Jaffna', 'mallakam' => 'Jaffna', 'mandaitivu' => 'Jaffna', 'manipay' => 'Jaffna', 'mathagal' => 'Jaffna', 'meesalai' => 'Jaffna', 'mirusuvil' => 'Jaffna', 'nagarkovil' => 'Jaffna', 'nagendramadam' => 'Jaffna', 'nainathivu' => 'Jaffna', 'nallur' => 'Jaffna', 'neervely' => 'Jaffna', 'pandaterippu' => 'Jaffna', 'point pedro' => 'Jaffna', 'puloly' => 'Jaffna', 'pungudutivu' => 'Jaffna', 'puttur' => 'Jaffna', 'sandilipay' => 'Jaffna', 'sangarathai' => 'Jaffna', 'sithankerny' => 'Jaffna', 'sivankovilady' => 'Jaffna', 'thellippallai' => 'Jaffna', 'thirunelvely' => 'Jaffna', 'thondamanaru' => 'Jaffna', 'urumpirai' => 'Jaffna', 'vaddukoddai' => 'Jaffna', 'valvettithurai' => 'Jaffna', 'vannarponnai' => 'Jaffna', 'varany' => 'Jaffna', 'vasavilan' => 'Jaffna', 'velanai' => 'Jaffna', 'yaffna' => 'Jaffna', // Kurunegala District 'alahengama' => 'Kurunegala', 'alahitiyawa' => 'Kurunegala', 'ambakote' => 'Kurunegala', 'ambanpola' => 'Kurunegala', 'andiyagala' => 'Kurunegala', 'anukkane' => 'Kurunegala', 'aragoda' => 'Kurunegala', 'ataragalla' => 'Kurunegala', 'awulegama' => 'Kurunegala', 'balalla' => 'Kurunegala', 'bamunukotuwa' => 'Kurunegala', 'bandara koswatta' => 'Kurunegala', 'bingiriya' => 'Kurunegala', 'bogamulla' => 'Kurunegala', 'boraluwewa' => 'Kurunegala', 'boyagane' => 'Kurunegala', 'bujjomuwa' => 'Kurunegala', 'buluwala' => 'Kurunegala', 'dadayamtalawa' => 'Kurunegala', 'dambadeniya' => 'Kurunegala', 'daraluwa' => 'Kurunegala', 'deegalla' => 'Kurunegala', 'demataluwa' => 'Kurunegala', 'demuwatha' => 'Kurunegala', 'diddeniya' => 'Kurunegala', 'digannewa' => 'Kurunegala', 'divullegoda' => 'Kurunegala', 'diyasenpura' => 'Kurunegala', 'dodangaslanda' => 'Kurunegala', 'doluwa' => 'Kurunegala', 'doragamuwa' => 'Kurunegala', 'doratiyawa' => 'Kurunegala', 'dunumadalawa' => 'Kurunegala', 'dunuwilapitiya' => 'Kurunegala', 'ehetuwewa' => 'Kurunegala', 'elibichchiya' => 'Kurunegala', 'embogama' => 'Kurunegala', 'etungahakotuwa' => 'Kurunegala', 'galadivulwewa' => 'Kurunegala', 'galgamuwa' => 'Kurunegala', 'gallellagama' => 'Kurunegala', 'gallewa' => 'Kurunegala', 'ganegoda' => 'Kurunegala', 'girathalana' => 'Kurunegala', 'gokaralla' => 'Kurunegala', 'gonawila' => 'Kurunegala', 'halmillawewa' => 'Kurunegala', 'handungamuwa' => 'Kurunegala', 'harankahawa' => 'Kurunegala', 'helamada' => 'Kurunegala', 'hengamuwa' => 'Kurunegala', 'hettipola' => 'Kurunegala', 'hewainna' => 'Kurunegala', 'hilogama' => 'Kurunegala', 'hindagolla' => 'Kurunegala', 'hiriyala lenawa' => 'Kurunegala', 'hiruwalpola' => 'Kurunegala', 'horambawa' => 'Kurunegala', 'hulogedara' => 'Kurunegala', 'hulugalla' => 'Kurunegala', 'ibbagamuwa' => 'Kurunegala', 'ihala gomugomuwa' => 'Kurunegala', 'ihala kadigamuwa' => 'Kurunegala', 'ihala katugampala' => 'Kurunegala', 'illagolla' => 'Kurunegala', 'ilukhena' => 'Kurunegala', 'indulgodakanda' => 'Kurunegala', 'ithanawatta' => 'Kurunegala', 'kadigawa' => 'Kurunegala', 'kalankuttiya' => 'Kurunegala', 'kalatuwawa' => 'Kurunegala', 'kalugamuwa' => 'Kurunegala', 'kanadeniyawala' => 'Kurunegala', 'kanattewewa' => 'Kurunegala', 'kandegedara' => 'Kurunegala', 'karagahagedara' => 'Kurunegala', 'karambe' => 'Kurunegala', 'katiyawa' => 'Kurunegala', 'katupota' => 'Kurunegala', 'kawudulla' => 'Kurunegala', 'kawuduluwewa stagell' => 'Kurunegala', 'kekunagolla' => 'Kurunegala', 'keppitiwalana' => 'Kurunegala', 'kimbulwanaoya' => 'Kurunegala', 'kirimetiyawa' => 'Kurunegala', 'kirindawa' => 'Kurunegala', 'kirindigalla' => 'Kurunegala', 'kithalawa' => 'Kurunegala', 'kitulwala' => 'Kurunegala', 'kobeigane' => 'Kurunegala', 'kohilagedara' => 'Kurunegala', 'konwewa' => 'Kurunegala', 'kosdeniya' => 'Kurunegala', 'kosgolla' => 'Kurunegala', 'kotagala' => 'Kurunegala', 'kotawehera' => 'Kurunegala', 'kudagalgamuwa' => 'Kurunegala', 'kudakatnoruwa' => 'Kurunegala', 'kuliyapitiya' => 'Kurunegala', 'kuliyapitiya town' => 'Kurunegala', 'kumaragama' => 'Kurunegala', 'kumbukgeta' => 'Kurunegala', 'kumbukwewa' => 'Kurunegala', 'kuratihena' => 'Kurunegala', 'kurunegala' => 'Kurunegala', 'kurunegala town' => 'Kurunegala', 'lihiriyagama' => 'Kurunegala', 'lonahettiya' => 'Kurunegala', 'madahapola' => 'Kurunegala', 'madakumburumulla' => 'Kurunegala', 'madalagama' => 'Kurunegala', 'madawala ulpotha' => 'Kurunegala', 'maduragoda' => 'Kurunegala', 'maeliya' => 'Kurunegala', 'magulagama' => 'Kurunegala', 'maha ambagaswewa' => 'Kurunegala', 'mahagalkadawala' => 'Kurunegala', 'mahagirilla' => 'Kurunegala', 'mahamukalanyaya' => 'Kurunegala', 'mahananneriya' => 'Kurunegala', 'mahapallegama' => 'Kurunegala', 'maharachchimulla' => 'Kurunegala', 'mahatalakolawewa' => 'Kurunegala', 'mahawewa' => 'Kurunegala', 'maho' => 'Kurunegala', 'makulewa' => 'Kurunegala', 'makulpotha' => 'Kurunegala', 'makulwewa' => 'Kurunegala', 'malagane' => 'Kurunegala', 'mandapola' => 'Kurunegala', 'maspotha' => 'Kurunegala', 'mawathagama' => 'Kurunegala', 'medirigiriya' => 'Kurunegala', 'medivawa' => 'Kurunegala', 'meegalawa' => 'Kurunegala', 'meegaswewa' => 'Kurunegala', 'meewellawa' => 'Kurunegala', 'melsiripura' => 'Kurunegala', 'metikumbura' => 'Kurunegala', 'metiyagane' => 'Kurunegala', 'minhettiya' => 'Kurunegala', 'minuwangete' => 'Kurunegala', 'mirihanagama' => 'Kurunegala', 'monnekulama' => 'Kurunegala', 'moragane' => 'Kurunegala', 'moragollagama' => 'Kurunegala', 'morathiha' => 'Kurunegala', 'munamaldeniya' => 'Kurunegala', 'muruthenge' => 'Kurunegala', 'mutugala' => 'Kurunegala', 'nabadewa' => 'Kurunegala', 'nagollagama' => 'Kurunegala', 'nagollagoda' => 'Kurunegala', 'nakkawatta' => 'Kurunegala', 'narammala' => 'Kurunegala', 'nawasenapura' => 'Kurunegala', 'nawatalwatta' => 'Kurunegala', 'nelliya' => 'Kurunegala', 'nikaweratiya' => 'Kurunegala', 'nugagolla' => 'Kurunegala', 'nugawela' => 'Kurunegala', 'padeniya' => 'Kurunegala', 'padiwela' => 'Kurunegala', 'pahalagiribawa' => 'Kurunegala', 'pahamune' => 'Kurunegala', 'palagala' => 'Kurunegala', 'palapathwela' => 'Kurunegala', 'palaviya' => 'Kurunegala', 'pallewela' => 'Kurunegala', 'palukadawala' => 'Kurunegala', 'panadaragama' => 'Kurunegala', 'panagamuwa' => 'Kurunegala', 'panaliya' => 'Kurunegala', 'panapitiya' => 'Kurunegala', 'panliyadda' => 'Kurunegala', 'pansiyagama' => 'Kurunegala', 'parape' => 'Kurunegala', 'pathanewatta' => 'Kurunegala', 'pattiya watta' => 'Kurunegala', 'perakanatta' => 'Kurunegala', 'periyakadneluwa' => 'Kurunegala', 'pihimbiya ratmale' => 'Kurunegala', 'pihimbuwa' => 'Kurunegala', 'pilessa' => 'Kurunegala', 'polgahawela' => 'Kurunegala', 'polgolla' => 'Kurunegala', 'polpithigama' => 'Kurunegala', 'pothuhera' => 'Kurunegala', 'pothupitiya' => 'Kurunegala', 'pujapitiya' => 'Kurunegala', 'rakwana' => 'Kurunegala', 'ranorawa' => 'Kurunegala', 'rathukohodigala' => 'Kurunegala', 'ridibendiella' => 'Kurunegala', 'ridigama' => 'Kurunegala', 'saliya asokapura' => 'Kurunegala', 'sandalankawa' => 'Kurunegala', 'sevanapitiya' => 'Kurunegala', 'sirambiadiya' => 'Kurunegala', 'sirisetagama' => 'Kurunegala', 'siyambalangamuwa' => 'Kurunegala', 'siyambalawewa' => 'Kurunegala', 'solepura' => 'Kurunegala', 'solewewa' => 'Kurunegala', 'sunandapura' => 'Kurunegala', 'talawattegedara' => 'Kurunegala', 'tambutta' => 'Kurunegala', 'tennepanguwa' => 'Kurunegala', 'thalahitimulla' => 'Kurunegala', 'thalakolawewa' => 'Kurunegala', 'thalwita' => 'Kurunegala', 'tharana udawela' => 'Kurunegala', 'thimbiriyawa' => 'Kurunegala', 'thorayaya' => 'Kurunegala', 'tisogama' => 'Kurunegala', 'tulhiriya' => 'Kurunegala', 'tuntota' => 'Kurunegala', 'tuttiripitigama' => 'Kurunegala', 'udagaldeniya' => 'Kurunegala', 'udahingulwala' => 'Kurunegala', 'udawatta' => 'Kurunegala', 'udubaddawa' => 'Kurunegala', 'udumulla' => 'Kurunegala', 'uhumiya' => 'Kurunegala', 'ulpotha pallekele' => 'Kurunegala', 'ulpothagama' => 'Kurunegala', 'usgala siyabmalangamuwa' => 'Kurunegala', 'vijithapura' => 'Kurunegala', 'wadakada' => 'Kurunegala', 'wadumunnegedara' => 'Kurunegala', 'walakumburumulla' => 'Kurunegala', 'wannigama' => 'Kurunegala', 'wannikudawewa' => 'Kurunegala', 'wannilhalagama' => 'Kurunegala', 'wannirasnayakapura' => 'Kurunegala', 'warawewa' => 'Kurunegala', 'wariyapola' => 'Kurunegala', 'watareka' => 'Kurunegala', 'wattegama' => 'Kurunegala', 'watuwatta' => 'Kurunegala', 'weerapokuna' => 'Kurunegala', 'welawa juncton' => 'Kurunegala', 'welipennagahamulla' => 'Kurunegala', 'wellagala' => 'Kurunegala', 'wellarawa' => 'Kurunegala', 'wellawa' => 'Kurunegala', 'welpalla' => 'Kurunegala', 'wennoruwa' => 'Kurunegala', 'weuda' => 'Kurunegala', 'wewagama' => 'Kurunegala', 'wilgamuwa' => 'Kurunegala', 'yakwila' => 'Kurunegala', 'yatigaloluwa' => 'Kurunegala', // Puttalam District 'adippala' => 'Puttalam', 'alutgama' => 'Puttalam', 'alutwewa' => 'Puttalam', 'ambakandawila' => 'Puttalam', 'anamaduwa' => 'Puttalam', 'andigama' => 'Puttalam', 'angunawila' => 'Puttalam', 'attawilluwa' => 'Puttalam', 'bangadeniya' => 'Puttalam', 'baranankattuwa' => 'Puttalam', 'battuluoya' => 'Puttalam', 'bujjampola' => 'Puttalam', 'chilaw' => 'Puttalam', 'chilaw town' => 'Puttalam', 'dalukana' => 'Puttalam', 'dankotuwa' => 'Puttalam', 'dewagala' => 'Puttalam', 'dummalasuriya' => 'Puttalam', 'dunkannawa' => 'Puttalam', 'eluwankulama' => 'Puttalam', 'ettale' => 'Puttalam', 'galamuna' => 'Puttalam', 'galmuruwa' => 'Puttalam', 'hansayapalama' => 'Puttalam', 'ihala kottaramulla' => 'Puttalam', 'ilippadeniya' => 'Puttalam', 'inginimitiya' => 'Puttalam', 'ismailpuram' => 'Puttalam', 'jayasiripura' => 'Puttalam', 'kakkapalliya' => 'Puttalam', 'kalkudah' => 'Puttalam', 'kalladiya' => 'Puttalam', 'kandakuliya' => 'Puttalam', 'karathivu' => 'Puttalam', 'karawitagara' => 'Puttalam', 'karuwalagaswewa' => 'Puttalam', 'katuneriya' => 'Puttalam', 'koswatta' => 'Puttalam', 'kottantivu' => 'Puttalam', 'kottapitiya' => 'Puttalam', 'kottukachchiya' => 'Puttalam', 'kumarakattuwa' => 'Puttalam', 'kurinjanpitiya' => 'Puttalam', 'kuruketiyawa' => 'Puttalam', 'lunuwila' => 'Puttalam', 'madampe' => 'Puttalam', 'madurankuliya' => 'Puttalam', 'mahakumbukkadawala' => 'Puttalam', 'mahauswewa' => 'Puttalam', 'mampitiya' => 'Puttalam', 'mampuri' => 'Puttalam', 'mangalaeliya' => 'Puttalam', 'marawila' => 'Puttalam', 'mudalakkuliya' => 'Puttalam', 'mugunuwatawana' => 'Puttalam', 'mukkutoduwawa' => 'Puttalam', 'mundel' => 'Puttalam', 'muttibendiwila' => 'Puttalam', 'nainamadama' => 'Puttalam', 'nalladarankattuwa' => 'Puttalam', 'nattandiya' => 'Puttalam', 'nawagattegama' => 'Puttalam', 'nelumwewa' => 'Puttalam', 'norachcholai' => 'Puttalam', 'pallama' => 'Puttalam', 'palliwasalturai' => 'Puttalam', 'panirendawa' => 'Puttalam', 'parakramasamudraya' => 'Puttalam', 'pothuwatawana' => 'Puttalam', 'puththalam' => 'Puttalam', 'puttalam' => 'Puttalam', 'puttalam cement factory' => 'Puttalam', 'rajakadaluwa' => 'Puttalam', 'saliyawewa junction' => 'Puttalam', 'serukele' => 'Puttalam', 'siyambalagashene' => 'Puttalam', 'tabbowa' => 'Puttalam', 'talawila church' => 'Puttalam', 'toduwawa' => 'Puttalam', 'udappuwa' => 'Puttalam', 'uridyawa' => 'Puttalam', 'vanathawilluwa' => 'Puttalam', 'waikkal' => 'Puttalam', 'watugahamulla' => 'Puttalam', 'wennappuwa' => 'Puttalam', 'wijeyakatupotha' => 'Puttalam', 'wilpotha' => 'Puttalam', 'yodaela' => 'Puttalam', 'yogiyana' => 'Puttalam', // Anuradhapura District 'angamuwa' => 'Anuradhapura', 'anuradhapura' => 'Anuradhapura', 'anuradhapura town' => 'Anuradhapura', 'awukana' => 'Anuradhapura', 'bogahawewa' => 'Anuradhapura', 'bulnewa' => 'Anuradhapura', 'dematawewa' => 'Anuradhapura', 'dimbulagala' => 'Anuradhapura', 'dutuwewa' => 'Anuradhapura', 'elayapattuwa' => 'Anuradhapura', 'ellewewa' => 'Anuradhapura', 'eppawala' => 'Anuradhapura', 'etawatunuwewa' => 'Anuradhapura', 'etaweeragollewa' => 'Anuradhapura', 'galapitagala' => 'Anuradhapura', 'galenbindunuwewa' => 'Anuradhapura', 'galkadawala' => 'Anuradhapura', 'galkiriyagama' => 'Anuradhapura', 'galkulama' => 'Anuradhapura', 'galnewa' => 'Anuradhapura', 'gambirigaswewa' => 'Anuradhapura', 'ganewalpola' => 'Anuradhapura', 'gemunupura' => 'Anuradhapura', 'getalawa' => 'Anuradhapura', 'gnanikulama' => 'Anuradhapura', 'gonahaddenawa' => 'Anuradhapura', 'habarana' => 'Anuradhapura', 'halmillawa dambulla' => 'Anuradhapura', 'halmillawetiya' => 'Anuradhapura', 'hidogama' => 'Anuradhapura', 'horawpatana' => 'Anuradhapura', 'horiwila' => 'Anuradhapura', 'hurigaswewa' => 'Anuradhapura', 'hurulunikawewa' => 'Anuradhapura', 'ihala puliyankulama' => 'Anuradhapura', 'ihalagama' => 'Anuradhapura', 'ipologama' => 'Anuradhapura', 'kagama' => 'Anuradhapura', 'kahatagasdigiliya' => 'Anuradhapura', 'kahatagollewa' => 'Anuradhapura', 'kalakarambewa' => 'Anuradhapura', 'kalaoya' => 'Anuradhapura', 'kalawedi ulpotha' => 'Anuradhapura', 'kallanchiya' => 'Anuradhapura', 'kalpitiya' => 'Anuradhapura', 'kalukele badanagala' => 'Anuradhapura', 'kapugallawa' => 'Anuradhapura', 'karagahawewa' => 'Anuradhapura', 'kashyapapura' => 'Anuradhapura', 'kebithigollewa' => 'Anuradhapura', 'kekirawa' => 'Anuradhapura', 'kendewa' => 'Anuradhapura', 'kiralogama' => 'Anuradhapura', 'kirigalwewa' => 'Anuradhapura', 'kirimundalama' => 'Anuradhapura', 'kitulhitiyawa' => 'Anuradhapura', 'kurundankulama' => 'Anuradhapura', 'labunoruwa' => 'Anuradhapura', 'madatugama' => 'Anuradhapura', 'maha elagamuwa' => 'Anuradhapura', 'mahabulankulama' => 'Anuradhapura', 'mahailluppallama' => 'Anuradhapura', 'mahakanadarawa' => 'Anuradhapura', 'mahapothana' => 'Anuradhapura', 'mahasenpura' => 'Anuradhapura', 'mahawilachchiya' => 'Anuradhapura', 'mailagaswewa' => 'Anuradhapura', 'malwanagama' => 'Anuradhapura', 'maneruwa' => 'Anuradhapura', 'maradankadawala' => 'Anuradhapura', 'maradankalla' => 'Anuradhapura', 'medawachchiya' => 'Anuradhapura', 'megodawewa' => 'Anuradhapura', 'mihintale' => 'Anuradhapura', 'morakewa' => 'Anuradhapura', 'mulkiriyawa' => 'Anuradhapura', 'muriyakadawala' => 'Anuradhapura', 'nachchaduwa' => 'Anuradhapura', 'namalpura' => 'Anuradhapura', 'negampaha' => 'Anuradhapura', 'nochchiyagama' => 'Anuradhapura', 'nuwaragala' => 'Anuradhapura', 'padavi maithripura' => 'Anuradhapura', 'padavi parakramapura' => 'Anuradhapura', 'padavi sripura' => 'Anuradhapura', 'padavi sritissapura' => 'Anuradhapura', 'padaviya' => 'Anuradhapura', 'padikaramaduwa' => 'Anuradhapura', 'pahala halmillewa' => 'Anuradhapura', 'pahala maragahawe' => 'Anuradhapura', 'pahalagama' => 'Anuradhapura', 'palugaswewa' => 'Anuradhapura', 'pandukabayapura' => 'Anuradhapura', 'pandulagama' => 'Anuradhapura', 'parakumpura' => 'Anuradhapura', 'parangiyawadiya' => 'Anuradhapura', 'parasangahawewa' => 'Anuradhapura', 'pelatiyawa' => 'Anuradhapura', 'pemaduwa' => 'Anuradhapura', 'perimiyankulama' => 'Anuradhapura', 'pihimbiyagolewa' => 'Anuradhapura', 'pubbogama' => 'Anuradhapura', 'punewa' => 'Anuradhapura', 'rajanganaya' => 'Anuradhapura', 'rambewa' => 'Anuradhapura', 'rampathwila' => 'Anuradhapura', 'rathmalgahawewa' => 'Anuradhapura', 'saliyapura' => 'Anuradhapura', 'seeppukulama' => 'Anuradhapura', 'senapura' => 'Anuradhapura', 'sivalakulama' => 'Anuradhapura', 'siyambalewa' => 'Anuradhapura', 'sravasthipura' => 'Anuradhapura', 'talawa' => 'Anuradhapura', 'tambuttegama' => 'Anuradhapura', 'tammennawa' => 'Anuradhapura', 'tantirimale' => 'Anuradhapura', 'telhiriyawa' => 'Anuradhapura', 'tirappane' => 'Anuradhapura', 'tittagonewa' => 'Anuradhapura', 'udunuwara colony' => 'Anuradhapura', 'upuldeniya' => 'Anuradhapura', 'uttimaduwa' => 'Anuradhapura', 'vellamanal' => 'Anuradhapura', 'viharapalugama' => 'Anuradhapura', 'wahalkada' => 'Anuradhapura', 'wahamalgollewa' => 'Anuradhapura', 'walagambahuwa' => 'Anuradhapura', 'walahaviddawewa' => 'Anuradhapura', 'welimuwapotana' => 'Anuradhapura', 'welioya project' => 'Anuradhapura', // Polonnaruwa District 'attanakadawala' => 'Polonnaruwa', 'bakamuna' => 'Polonnaruwa', 'diyabeduma' => 'Polonnaruwa', 'elahera' => 'Polonnaruwa', 'giritale' => 'Polonnaruwa', 'hingurakdamana' => 'Polonnaruwa', 'hingurakgoda' => 'Polonnaruwa', 'jayanthipura' => 'Polonnaruwa', 'kalingaela' => 'Polonnaruwa', 'lakshauyana' => 'Polonnaruwa', 'mankemi' => 'Polonnaruwa', 'minneriya' => 'Polonnaruwa', 'onegama' => 'Polonnaruwa', 'orubendi siyambalawa' => 'Polonnaruwa', 'palugasdamana' => 'Polonnaruwa', 'panichankemi' => 'Polonnaruwa', 'polonnaruwa' => 'Polonnaruwa', 'polonnaruwa town' => 'Polonnaruwa', 'talpotha' => 'Polonnaruwa', 'tambala' => 'Polonnaruwa', 'unagalavehera' => 'Polonnaruwa', 'wijayabapura' => 'Polonnaruwa', // Badulla District 'akkarasiyaya' => 'Badulla', 'aluketiyawa' => 'Badulla', 'aluttaramma' => 'Badulla', 'ambadandegama' => 'Badulla', 'ambagasdowa' => 'Badulla', 'arawa' => 'Badulla', 'arawakumbura' => 'Badulla', 'arawatta' => 'Badulla', 'atakiriya' => 'Badulla', 'badulla' => 'Badulla', 'badulla town' => 'Badulla', 'baduluoya' => 'Badulla', 'ballaketuwa' => 'Badulla', 'bambarapana' => 'Badulla', 'bandarawela' => 'Badulla', 'bandarawela town' => 'Badulla', 'beramada' => 'Badulla', 'bibilegama' => 'Badulla', 'boragas' => 'Badulla', 'boralanda' => 'Badulla', 'bowela' => 'Badulla', 'central camp' => 'Badulla', 'damanewela' => 'Badulla', 'dambana' => 'Badulla', 'dehiattakandiya' => 'Badulla', 'demodara' => 'Badulla', 'diganatenna' => 'Badulla', 'dikkapitiya' => 'Badulla', 'dimbulana' => 'Badulla', 'divulapelessa' => 'Badulla', 'diyatalawa' => 'Badulla', 'dulgolla' => 'Badulla', 'ekiriyankumbura' => 'Badulla', 'ella' => 'Badulla', 'ettampitiya' => 'Badulla', 'galauda' => 'Badulla', 'galporuyaya' => 'Badulla', 'gawarawela' => 'Badulla', 'girandurukotte' => 'Badulla', 'godunna' => 'Badulla', 'gurutalawa' => 'Badulla', 'haldummulla' => 'Badulla', 'hali ela' => 'Badulla', 'hangunnawa' => 'Badulla', 'haputale' => 'Badulla', 'hebarawa' => 'Badulla', 'heeloya' => 'Badulla', 'helahalpe' => 'Badulla', 'helapupula' => 'Badulla', 'hopton' => 'Badulla', 'idalgashinna' => 'Badulla', 'kahataruppa' => 'Badulla', 'kalugahakandura' => 'Badulla', 'kalupahana' => 'Badulla', 'kebillawela' => 'Badulla', 'kendagolla' => 'Badulla', 'keselpotha' => 'Badulla', 'ketawatta' => 'Badulla', 'kiriwanagama' => 'Badulla', 'koslanda' => 'Badulla', 'kuruwitenna' => 'Badulla', 'kuttiyagolla' => 'Badulla', 'landewela' => 'Badulla', 'liyangahawela' => 'Badulla', 'lunugala' => 'Badulla', 'lunuwatta' => 'Badulla', 'madulsima' => 'Badulla', 'mahiyanganaya' => 'Badulla', 'makulella' => 'Badulla', 'malgoda' => 'Badulla', 'mapakadawewa' => 'Badulla', 'maspanna' => 'Badulla', 'maussagolla' => 'Badulla', 'mawanagama' => 'Badulla', 'medawela udukinda' => 'Badulla', 'meegahakiula' => 'Badulla', 'metigahatenna' => 'Badulla', 'mirahawatta' => 'Badulla', 'miriyabedda' => 'Badulla', 'nawamedagama' => 'Badulla', 'nelumgama' => 'Badulla', 'nikapotha' => 'Badulla', 'nugatalawa' => 'Badulla', 'ohiya' => 'Badulla', 'pahalarathkinda' => 'Badulla', 'pallekiruwa' => 'Badulla', 'passara' => 'Badulla', 'pattiyagedara' => 'Badulla', 'pelagahatenna' => 'Badulla', 'perawella' => 'Badulla', 'pitamaruwa' => 'Badulla', 'pitapola' => 'Badulla', 'puhulpola' => 'Badulla', 'rajagalatenna' => 'Badulla', 'rathkarawwa' => 'Badulla', 'ridimaliyadda' => 'Badulla', 'silmiyapura' => 'Badulla', 'sirimalgoda' => 'Badulla', 'siripura' => 'Badulla', 'sorabora colony' => 'Badulla', 'soragune' => 'Badulla', 'soranathota' => 'Badulla', 'taldena' => 'Badulla', 'timbirigaspitiya' => 'Badulla', 'uduhawara' => 'Badulla', 'uraniya' => 'Badulla', 'uva karandagolla' => 'Badulla', 'uva mawelagama' => 'Badulla', 'uva tenna' => 'Badulla', 'uva tissapura' => 'Badulla', 'welimada' => 'Badulla', 'weranketagoda' => 'Badulla', 'wewatta' => 'Badulla', 'wineethagama' => 'Badulla', 'yalagamuwa' => 'Badulla', 'yalwela' => 'Badulla', // Moneragala District 'ayiwela' => 'Moneragala', 'badalkumbura' => 'Moneragala', 'baduluwela' => 'Moneragala', 'bakinigahawela' => 'Moneragala', 'balaharuwa' => 'Moneragala', 'bibile' => 'Moneragala', 'buddama' => 'Moneragala', 'buttala' => 'Moneragala', 'dambagalla' => 'Moneragala', 'diyakobala' => 'Moneragala', 'dombagahawela' => 'Moneragala', 'ethimalewewa' => 'Moneragala', 'ettiliwewa' => 'Moneragala', 'galabedda' => 'Moneragala', 'gamewela' => 'Moneragala', 'hambegamuwa' => 'Moneragala', 'hingurukaduwa' => 'Moneragala', 'hulandawa' => 'Moneragala', 'inginiyagala' => 'Moneragala', 'kandaudapanguwa' => 'Moneragala', 'kandawinna' => 'Moneragala', 'kataragama' => 'Moneragala', 'kotagama' => 'Moneragala', 'kotamuduna' => 'Moneragala', 'kotawehera mankada' => 'Moneragala', 'kudawewa' => 'Moneragala', 'kumbukkana' => 'Moneragala', 'marawa' => 'Moneragala', 'mariarawa' => 'Moneragala', 'medagana' => 'Moneragala', 'medawelagama' => 'Moneragala', 'miyanakandura' => 'Moneragala', 'monaragala' => 'Moneragala', 'moneragala' => 'Moneragala', 'moretuwegama' => 'Moneragala', 'nakkala' => 'Moneragala', 'namunukula' => 'Moneragala', 'nannapurawa' => 'Moneragala', 'nelliyadda' => 'Moneragala', 'nilgala' => 'Moneragala', 'obbegoda' => 'Moneragala', 'okkampitiya' => 'Moneragala', 'pangura' => 'Moneragala', 'pitakumbura' => 'Moneragala', 'randeniya' => 'Moneragala', 'ruwalwela' => 'Moneragala', 'sella kataragama' => 'Moneragala', 'siyambalagune' => 'Moneragala', 'siyambalanduwa' => 'Moneragala', 'suriara' => 'Moneragala', 'thanamalwila' => 'Moneragala', 'uva gangodagama' => 'Moneragala', 'uva kudaoya' => 'Moneragala', 'uva pelwatta' => 'Moneragala', 'warunagama' => 'Moneragala', 'wedikumbura' => 'Moneragala', 'weherayaya handapanagala' => 'Moneragala', 'wellawaya' => 'Moneragala', 'wellawaya town' => 'Moneragala', 'wilaoya' => 'Moneragala', 'yudaganawa' => 'Moneragala', // Ratnapura District 'akarella' => 'Ratnapura', 'amunumulla' => 'Ratnapura', 'atakalanpanna' => 'Ratnapura', 'ayagama' => 'Ratnapura', 'balangoda' => 'Ratnapura', 'batatota' => 'Ratnapura', 'beralapanathara' => 'Ratnapura', 'bogahakumbura' => 'Ratnapura', 'bolthumbe' => 'Ratnapura', 'bomluwageaina' => 'Ratnapura', 'bowalagama' => 'Ratnapura', 'bulutota' => 'Ratnapura', 'dambuluwana' => 'Ratnapura', 'daugala' => 'Ratnapura', 'dela' => 'Ratnapura', 'delwala' => 'Ratnapura', 'dodampe' => 'Ratnapura', 'doloswalakanda' => 'Ratnapura', 'dumbara manana' => 'Ratnapura', 'eheliyagoda' => 'Ratnapura', 'ekamutugama' => 'Ratnapura', 'elapatha' => 'Ratnapura', 'ellagawa' => 'Ratnapura', 'ellaulla' => 'Ratnapura', 'ellawala' => 'Ratnapura', 'embiliipitiya' => 'Ratnapura', 'embilipitiya' => 'Ratnapura', 'embilipitiya town' => 'Ratnapura', 'eratna' => 'Ratnapura', 'erepola' => 'Ratnapura', 'gabbela' => 'Ratnapura', 'gangeyaya' => 'Ratnapura', 'gawaragiriya' => 'Ratnapura', 'gillimale' => 'Ratnapura', 'godakawela' => 'Ratnapura', 'gurubewilagama' => 'Ratnapura', 'halwinna' => 'Ratnapura', 'handagiriya' => 'Ratnapura', 'hatangala' => 'Ratnapura', 'hatarabage' => 'Ratnapura', 'hewanakumbura' => 'Ratnapura', 'hidellana' => 'Ratnapura', 'hiramadagama' => 'Ratnapura', 'horewelagoda' => 'Ratnapura', 'imaduwa' => 'Ratnapura', 'imbulpe' => 'Ratnapura', 'ittakanda' => 'Ratnapura', 'kahangama' => 'Ratnapura', 'kahawatta' => 'Ratnapura', 'kalawana' => 'Ratnapura', 'kaltota' => 'Ratnapura', 'kalubululanda' => 'Ratnapura', 'kananke bazaar' => 'Ratnapura', 'kandepuhulpola' => 'Ratnapura', 'karandana' => 'Ratnapura', 'karangoda' => 'Ratnapura', 'kella junction' => 'Ratnapura', 'keppetipola' => 'Ratnapura', 'kiriella' => 'Ratnapura', 'kiriibbanwewa' => 'Ratnapura', 'kolambage ara' => 'Ratnapura', 'kolombugama' => 'Ratnapura', 'kolonna' => 'Ratnapura', 'kudawa' => 'Ratnapura', 'kuruwita' => 'Ratnapura', 'lellopitiya' => 'Ratnapura', 'mahagama colony' => 'Ratnapura', 'mahawalatenna' => 'Ratnapura', 'makandura' => 'Ratnapura', 'malwala junction' => 'Ratnapura', 'malwatta' => 'Ratnapura', 'matuwagalagama' => 'Ratnapura', 'medagalature' => 'Ratnapura', 'meddekanda' => 'Ratnapura', 'minipura dumbara' => 'Ratnapura', 'mitipola' => 'Ratnapura', 'moragala kirillapone' => 'Ratnapura', 'morahela' => 'Ratnapura', 'mulendiyawala' => 'Ratnapura', 'mulgama' => 'Ratnapura', 'nawalakanda' => 'Ratnapura', 'nawinnapinnakanda' => 'Ratnapura', 'niralagama' => 'Ratnapura', 'nivitigala' => 'Ratnapura', 'omalpe' => 'Ratnapura', 'opanayaka' => 'Ratnapura', 'padalangala' => 'Ratnapura', 'pallebedda' => 'Ratnapura', 'pallekanda' => 'Ratnapura', 'pambagolla' => 'Ratnapura', 'panamura' => 'Ratnapura', 'panapola' => 'Ratnapura', 'paragala' => 'Ratnapura', 'parakaduwa' => 'Ratnapura', 'pebotuwa' => 'Ratnapura', 'pelmadulla' => 'Ratnapura', 'pinnawala' => 'Ratnapura', 'pothdeniya' => 'Ratnapura', 'rajawaka' => 'Ratnapura', 'ranwala' => 'Ratnapura', 'rassagala' => 'Ratnapura', 'rathgama' => 'Ratnapura', 'rathnapura' => 'Ratnapura', 'ratna hangamuwa' => 'Ratnapura', 'ratnapura' => 'Ratnapura', 'sewanagala' => 'Ratnapura', 'sri palabaddala' => 'Ratnapura', 'sudagala' => 'Ratnapura', 'thalakolahinna' => 'Ratnapura', 'thanjantenna' => 'Ratnapura', 'theppanawa' => 'Ratnapura', 'thunkama' => 'Ratnapura', 'udakarawita' => 'Ratnapura', 'udaniriella' => 'Ratnapura', 'udawalawe' => 'Ratnapura', 'ullinduwawa' => 'Ratnapura', 'veddagala' => 'Ratnapura', 'vijeriya' => 'Ratnapura', 'waleboda' => 'Ratnapura', 'watapotha' => 'Ratnapura', 'waturawa' => 'Ratnapura', 'weligepola' => 'Ratnapura', 'welipathayaya' => 'Ratnapura', 'wikiliya' => 'Ratnapura', // Kegalle District 'alawala' => 'Kegalle', 'alawatura' => 'Kegalle', 'alawwa' => 'Kegalle', 'algama' => 'Kegalle', 'alutnuwara' => 'Kegalle', 'ambalakanda' => 'Kegalle', 'ambulugala' => 'Kegalle', 'amitirigala' => 'Kegalle', 'ampagala' => 'Kegalle', 'anhandiya' => 'Kegalle', 'anhettigama' => 'Kegalle', 'aranayaka' => 'Kegalle', 'aruggammana' => 'Kegalle', 'batuwita' => 'Kegalle', 'beligala' => 'Kegalle', 'belihuloya' => 'Kegalle', 'berannawa' => 'Kegalle', 'bopitiya' => 'Kegalle', 'boralankada' => 'Kegalle', 'bossella' => 'Kegalle', 'bulathkohupitiya' => 'Kegalle', 'damunupola' => 'Kegalle', 'debathgama' => 'Kegalle', 'dedugala' => 'Kegalle', 'deewala pallegama' => 'Kegalle', 'dehiowita' => 'Kegalle', 'deldeniya' => 'Kegalle', 'deloluwa' => 'Kegalle', 'deraniyagala' => 'Kegalle', 'dewalegama' => 'Kegalle', 'dewanagala' => 'Kegalle', 'dombemada' => 'Kegalle', 'dorawaka' => 'Kegalle', 'dunumala' => 'Kegalle', 'galapitamada' => 'Kegalle', 'galatara' => 'Kegalle', 'galigamuwa town' => 'Kegalle', 'gallella' => 'Kegalle', 'galpatha' => 'Kegalle', 'gantuna' => 'Kegalle', 'getahetta' => 'Kegalle', 'godagampola' => 'Kegalle', 'gonagala' => 'Kegalle', 'hakahinna' => 'Kegalle', 'hakbellawaka' => 'Kegalle', 'halloluwa' => 'Kegalle', 'hedunuwewa' => 'Kegalle', 'hemmatagama' => 'Kegalle', 'hewadiwela' => 'Kegalle', 'hingula' => 'Kegalle', 'hinguralakanda' => 'Kegalle', 'hingurana' => 'Kegalle', 'hiriwadunna' => 'Kegalle', 'ihala walpola' => 'Kegalle', 'ihalagama' => 'Kegalle', 'imbulana' => 'Kegalle', 'imbulgasdeniya' => 'Kegalle', 'kabagamuwa' => 'Kegalle', 'kahapathwala' => 'Kegalle', 'kandaketya' => 'Kegalle', 'kannattota' => 'Kegalle', 'karagahinna' => 'Kegalle', 'kegalla' => 'Kegalle', 'kegalle' => 'Kegalle', 'kegalle town' => 'Kegalle', 'kehelpannala' => 'Kegalle', 'ketawala leula' => 'Kegalle', 'kitulgala' => 'Kegalle', 'kondeniya' => 'Kegalle', 'kotiyakumbura' => 'Kegalle', 'lewangama' => 'Kegalle', 'mahabage' => 'Kegalle', 'makehelwala' => 'Kegalle', 'malalpola' => 'Kegalle', 'maldeniya' => 'Kegalle', 'maliboda' => 'Kegalle', 'maliyadda' => 'Kegalle', 'malmaduwa' => 'Kegalle', 'marapana' => 'Kegalle', 'mawanella' => 'Kegalle', 'meetanwala' => 'Kegalle', 'migastenna sabara' => 'Kegalle', 'miyanawita' => 'Kegalle', 'molagoda' => 'Kegalle', 'morontota' => 'Kegalle', 'narangala' => 'Kegalle', 'narangoda' => 'Kegalle', 'nattarampotha' => 'Kegalle', 'nelundeniya' => 'Kegalle', 'niyadurupola' => 'Kegalle', 'noori' => 'Kegalle', 'pannila' => 'Kegalle', 'pattampitiya' => 'Kegalle', 'pilawala' => 'Kegalle', 'pothukoladeniya' => 'Kegalle', 'puswelitenna' => 'Kegalle', 'rambukkana' => 'Kegalle', 'rilpola' => 'Kegalle', 'rukmale' => 'Kegalle', 'ruwanwella' => 'Kegalle', 'samanalawewa' => 'Kegalle', 'seaforth colony' => 'Kegalle', 'spring valley' => 'Kegalle', 'talgaspitiya' => 'Kegalle', 'teligama' => 'Kegalle', 'tholangamuwa' => 'Kegalle', 'thotawella' => 'Kegalle', 'udaha hawupe' => 'Kegalle', 'udapotha' => 'Kegalle', 'uduwa' => 'Kegalle', 'undugoda' => 'Kegalle', 'ussapitiya' => 'Kegalle', 'wahakula' => 'Kegalle', 'waharaka' => 'Kegalle', 'wanaluwewa' => 'Kegalle', 'warakapola' => 'Kegalle', 'watura' => 'Kegalle', 'weeoya' => 'Kegalle', 'wegalla' => 'Kegalle', 'weligalla' => 'Kegalle', 'welihelatenna' => 'Kegalle', 'wewelwatta' => 'Kegalle', 'yatagama' => 'Kegalle', 'yatapana' => 'Kegalle', 'yatiyantota' => 'Kegalle', 'yattogoda' => 'Kegalle', // Trincomalee District 'agbopura' => 'Trincomalee', 'buckmigama' => 'Trincomalee', 'china bay' => 'Trincomalee', 'dehiwatte' => 'Trincomalee', 'echchilampattai' => 'Trincomalee', 'galmetiyawa' => 'Trincomalee', 'gomarankadawala' => 'Trincomalee', 'kaddaiparichchan' => 'Trincomalee', 'kallar' => 'Trincomalee', 'kanniya' => 'Trincomalee', 'kantalai' => 'Trincomalee', 'kantalai sugar factory' => 'Trincomalee', 'kiliveddy' => 'Trincomalee', 'kinniya' => 'Trincomalee', 'kuchchaveli' => 'Trincomalee', 'kumburupiddy' => 'Trincomalee', 'kurinchakerny' => 'Trincomalee', 'lankapatuna' => 'Trincomalee', 'mahadivulwewa' => 'Trincomalee', 'maharugiramam' => 'Trincomalee', 'mallikativu' => 'Trincomalee', 'mawadichenai' => 'Trincomalee', 'mullipothana' => 'Trincomalee', 'mutur' => 'Trincomalee', 'neelapola' => 'Trincomalee', 'nilaveli' => 'Trincomalee', 'pankulam' => 'Trincomalee', 'pulmoddai' => 'Trincomalee', 'rottawewa' => 'Trincomalee', 'sampaltivu' => 'Trincomalee', 'sampoor' => 'Trincomalee', 'serunuwara' => 'Trincomalee', 'seruwila' => 'Trincomalee', 'sirajnagar' => 'Trincomalee', 'somapura' => 'Trincomalee', 'tampalakamam' => 'Trincomalee', 'thuraineelavanai' => 'Trincomalee', 'tiriyayi' => 'Trincomalee', 'toppur' => 'Trincomalee', 'trinco' => 'Trincomalee', 'trincomalee' => 'Trincomalee', 'wanela' => 'Trincomalee', // Batticaloa District 'addalaichenai' => 'Batticaloa', 'ampilanthurai' => 'Batticaloa', 'araipattai' => 'Batticaloa', 'ayithiyamalai' => 'Batticaloa', 'bakiella' => 'Batticaloa', 'batticalo' => 'Batticaloa', 'batticaloa' => 'Batticaloa', 'cheddipalayam' => 'Batticaloa', 'chenkaladi' => 'Batticaloa', 'eravur' => 'Batticaloa', 'kaluwanchikudi' => 'Batticaloa', 'kaluwankemy' => 'Batticaloa', 'kannankudah' => 'Batticaloa', 'karadiyanaru' => 'Batticaloa', 'kathiraveli' => 'Batticaloa', 'kattankudi' => 'Batticaloa', 'kiran' => 'Batticaloa', 'kirankulam' => 'Batticaloa', 'koddaikallar' => 'Batticaloa', 'kokkaddicholai' => 'Batticaloa', 'kurukkalmadam' => 'Batticaloa', 'madakalapuwa' => 'Batticaloa', 'mandur' => 'Batticaloa', 'miravodai' => 'Batticaloa', 'murakottanchanai' => 'Batticaloa', 'navagirinagar' => 'Batticaloa', 'navatkadu' => 'Batticaloa', 'oddamavadi' => 'Batticaloa', 'palamunai' => 'Batticaloa', 'pankudavely' => 'Batticaloa', 'periyaporativu' => 'Batticaloa', 'periyapullumalai' => 'Batticaloa', 'pillaiyaradi' => 'Batticaloa', 'punanai' => 'Batticaloa', 'thannamunai' => 'Batticaloa', 'thettativu' => 'Batticaloa', 'thikkodai' => 'Batticaloa', 'thirupalugamam' => 'Batticaloa', 'unnichchai' => 'Batticaloa', 'vakaneri' => 'Batticaloa', 'vakarai' => 'Batticaloa', 'valaichenai' => 'Batticaloa', 'vantharumoolai' => 'Batticaloa', 'vellavely' => 'Batticaloa', // Ampara District 'akkaraipattu' => 'Ampara', 'ambagahawatta' => 'Ampara', 'ampara' => 'Ampara', 'ampara town' => 'Ampara', 'bakmitiyawa' => 'Ampara', 'deegawapiya' => 'Ampara', 'devalahinda' => 'Ampara', 'digamadulla weeragoda' => 'Ampara', 'dorakumbura' => 'Ampara', 'gonagolla' => 'Ampara', 'hulannuge' => 'Ampara', 'irakkamam' => 'Ampara', 'kalmunai' => 'Ampara', 'kannakipuram' => 'Ampara', 'karativu' => 'Ampara', 'kekirihena' => 'Ampara', 'koknahara' => 'Ampara', 'kolamanthalawa' => 'Ampara', 'komari' => 'Ampara', 'lahugala' => 'Ampara', 'mahaoya' => 'Ampara', 'marathamune' => 'Ampara', 'namaloya' => 'Ampara', 'navithanveli' => 'Ampara', 'nintavur' => 'Ampara', 'oluvil' => 'Ampara', 'padiyatalawa' => 'Ampara', 'pahalalanda' => 'Ampara', 'panama' => 'Ampara', 'pannalagama' => 'Ampara', 'paragahakele' => 'Ampara', 'periyaneelavanai' => 'Ampara', 'polwaga janapadaya' => 'Ampara', 'pottuvil' => 'Ampara', 'sainthamaruthu' => 'Ampara', 'samanthurai' => 'Ampara', 'serankada' => 'Ampara', 'tempitiya' => 'Ampara', 'thambiluvil' => 'Ampara', 'tirukovil' => 'Ampara', 'uhana' => 'Ampara', 'wadinagala' => 'Ampara', 'wanagamuwa' => 'Ampara', // Kilinochchi District 'akkarayankulam' => 'Kilinochchi', 'aliyawalai' => 'Kilinochchi', 'ambalnagar' => 'Kilinochchi', 'cheddiyakurichchi' => 'Kilinochchi', 'chempiyanpattu' => 'Kilinochchi', 'chundikulam' => 'Kilinochchi', 'elephant pass' => 'Kilinochchi', 'eluthumadduval' => 'Kilinochchi', 'iranaitiv' => 'Kilinochchi', 'iyyakachchi' => 'Kilinochchi', 'kalmadunagar' => 'Kilinochchi', 'kandavalai' => 'Kilinochchi', 'karachchi' => 'Kilinochchi', 'karadipokku' => 'Kilinochchi', 'kavutharimunai' => 'Kilinochchi', 'kilay' => 'Kilinochchi', 'kilinochchi' => 'Kilinochchi', 'kilinochchila' => 'Kilinochchi', 'konavil' => 'Kilinochchi', 'kunchuparanthan' => 'Kilinochchi', 'muhamalai' => 'Kilinochchi', 'mulliyan' => 'Kilinochchi', 'murasumoddai' => 'Kilinochchi', 'pachchilaipalli' => 'Kilinochchi', 'pallai' => 'Kilinochchi', 'pallavarayankaddu' => 'Kilinochchi', 'paranthan' => 'Kilinochchi', 'poonakary' => 'Kilinochchi', 'puliyampokkanai' => 'Kilinochchi', 'punakari-nallur' => 'Kilinochchi', 'ramanathapuram' => 'Kilinochchi', 'sivanagar' => 'Kilinochchi', 'sivapuram' => 'Kilinochchi', 'skanthapuram' => 'Kilinochchi', 'soranpattu' => 'Kilinochchi', 'thalaiyadi' => 'Kilinochchi', 'tharmapuram' => 'Kilinochchi', 'thirunagar' => 'Kilinochchi', 'thiruvaiaru' => 'Kilinochchi', 'uruthirapuram' => 'Kilinochchi', 'vaddakachchi' => 'Kilinochchi', 'vannerikkulam' => 'Kilinochchi', 'veravil' => 'Kilinochchi', 'vinayagapuram' => 'Kilinochchi', // Mannar District 'aandankulam' => 'Mannar', 'adampan' => 'Mannar', 'arippu' => 'Mannar', 'athimottai' => 'Mannar', 'chilavathurai' => 'Mannar', 'erukkalampiddy' => 'Mannar', 'illuppaikadavai' => 'Mannar', 'karisal' => 'Mannar', 'kokkupadayan' => 'Mannar', 'madhu church' => 'Mannar', 'madhu road' => 'Mannar', 'mannar' => 'Mannar', 'mannarama' => 'Mannar', 'marichchikaddi' => 'Mannar', 'mullikulam' => 'Mannar', 'murunkan' => 'Mannar', 'nanattan' => 'Mannar', 'palampiddy' => 'Mannar', 'pallimunai' => 'Mannar', 'pandaraveli' => 'Mannar', 'pappamoddai' => 'Mannar', 'parappankandal' => 'Mannar', 'parappukadanthan' => 'Mannar', 'periyakunchikulam' => 'Mannar', 'periyamadhu' => 'Mannar', 'periyapandivirichchan' => 'Mannar', 'pesalai' => 'Mannar', 'potkerny' => 'Mannar', 'puthukudiyiruppu' => 'Mannar', 'puthuveli' => 'Mannar', 'sooriyakaddaikadhu' => 'Mannar', 'thalaimannar' => 'Mannar', 'thalaimannar pier' => 'Mannar', 'thalaimannar west' => 'Mannar', 'thalvupadu' => 'Mannar', 'tharapuram' => 'Mannar', 'thiruketheeswaram' => 'Mannar', 'uyilankulam' => 'Mannar', 'uyirtharasankulam' => 'Mannar', 'vaddakandal' => 'Mannar', 'vankalai' => 'Mannar', 'vellankulam' => 'Mannar', 'veppankulam' => 'Mannar', 'vidataltivu' => 'Mannar', // Vavuniya District 'alagalla' => 'Vavuniya', 'andiyapuliyankulam' => 'Vavuniya', 'asikulam' => 'Vavuniya', 'cheddikulam' => 'Vavuniya', 'chemamadukulam' => 'Vavuniya', 'iranai lluppaikulam' => 'Vavuniya', 'iratta periyakulama' => 'Vavuniya', 'kalmadhu' => 'Vavuniya', 'kanagarayankulam' => 'Vavuniya', 'kannaddi' => 'Vavuniya', 'kela bogaswewa' => 'Vavuniya', 'kovilkulam' => 'Vavuniya', 'madukanda' => 'Vavuniya', 'mahakachchakodiya' => 'Vavuniya', 'mamaduwa' => 'Vavuniya', 'maradammaduwa' => 'Vavuniya', 'maraiyadithakulam' => 'Vavuniya', 'maruthodai' => 'Vavuniya', 'mathavuvaithakulam' => 'Vavuniya', 'nainamadu' => 'Vavuniya', 'nedunkerny' => 'Vavuniya', 'nelukkulam' => 'Vavuniya', 'neriyakulam' => 'Vavuniya', 'nochchimoddai' => 'Vavuniya', 'omanthai' => 'Vavuniya', 'palamoddai' => 'Vavuniya', 'pampaimadu' => 'Vavuniya', 'pavakkulama unit 1' => 'Vavuniya', 'pavakkulama unit 2' => 'Vavuniya', 'periya ulukkulama' => 'Vavuniya', 'periyathambanai' => 'Vavuniya', 'poovarasankulam' => 'Vavuniya', 'puliyankulam' => 'Vavuniya', 'sathirikulankulam' => 'Vavuniya', 'sinnasippikulam' => 'Vavuniya', 'thandikulam' => 'Vavuniya', 'vaarikkuttiyoor' => 'Vavuniya', 'vavniya' => 'Vavuniya', 'vavuniya' => 'Vavuniya', // Mullaitivu District 'alampil' => 'Mullaitivu', 'ampalavanpokkanai' => 'Mullaitivu', 'ananthapuram' => 'Mullaitivu', 'ethawetunuwewa' => 'Mullaitivu', 'karuppaddamurippu' => 'Mullaitivu', 'kokkilai' => 'Mullaitivu', 'kokkuthuoduvai' => 'Mullaitivu', 'kumulamunai' => 'Mullaitivu', 'mankulam' => 'Mullaitivu', 'mullaitivu' => 'Mullaitivu', 'mullathivu' => 'Mullaitivu', 'mullativu' => 'Mullaitivu', 'mullivaikkal' => 'Mullaitivu', 'mulliyawalai' => 'Mullaitivu', 'murukandy' => 'Mullaitivu', 'muththaiyankaddukulam' => 'Mullaitivu', 'naddankandal' => 'Mullaitivu', 'oddusudan' => 'Mullaitivu', 'puthukkudiyiruppu' => 'Mullaitivu', 'puthuvedduvan' => 'Mullaitivu', 'thunukkai' => 'Mullaitivu', 'udayarkaddu' => 'Mullaitivu', 'vavunakkulam' => 'Mullaitivu', 'visvamadukulam' => 'Mullaitivu', 'welioya' => 'Mullaitivu', 'yogapuram' => 'Mullaitivu', ); $lower_state_name = strtolower( trim( $state_name ) ); // Check if the state field actually holds a city name instead of a district name // e.g. state field is "Kadugannawa" which maps to "Kandy" if ( isset( $city_to_district[ $lower_state_name ] ) && strcasecmp( $city_to_district[ $lower_state_name ], $state_name ) !== 0 ) { $district = $city_to_district[ $lower_state_name ]; $city = $state_name; } else { // State is a district name (or not mapped). Keep it. $district = $state_name; // Keep the customer-entered city as-is if ( ! empty( $billing_city ) ) { $city = ucwords( strtolower( trim( $billing_city ) ) ); } else { $city = ''; } } // If city is empty or same as the district/state, try to find a specific city in the address string if ( ( empty( $city ) || strcasecmp( $city, $district ) === 0 ) && ! empty( $address ) ) { $lower_address = strtolower( $address ); $city_keys = array_keys( $city_to_district ); // Sort keys by length descending so we match longer names first (e.g. "Mount Lavinia" before "Lavinia") usort( $city_keys, function( $a, $b ) { return strlen( $b ) - strlen( $a ); } ); foreach ( $city_keys as $potential_city ) { if ( false !== strpos( $lower_address, $potential_city ) ) { // Only resolve if it belongs to the correct resolved district if ( strcasecmp( $city_to_district[ $potential_city ], $district ) === 0 ) { $formatted_city = ucwords( $potential_city ); if ( strpos( $potential_city, '-' ) !== false ) { $formatted_city = str_replace( ' ', '-', ucwords( str_replace( '-', ' ', $potential_city ) ) ); } $city = $formatted_city; break; } } } } } else { // Non-Sri Lanka, resolve code normally $states = function_exists( 'WC' ) ? WC()->countries->get_states( $billing_country ) : array(); $district = isset( $states[ $billing_state ] ) ? $states[ $billing_state ] : $billing_state; } return array( 'district' => $district, 'city' => $city, ); } private static function get_product_isbn( $product_id ) { if ( ! $product_id ) { return ''; } // 1. Direct post meta lookup for WooCommerce GTIN/UPC/EAN/ISBN and custom ISBN keys $meta_keys = array( '_global_unique_id', 'global_unique_id', '_isbn', 'isbn', 'ISBN', '_ISBN', '_product_isbn', 'product_isbn', '_wc_isbn', 'wc_isbn', '_isbn_number', 'isbn_number', '_wpo_wcpdf_isbn', 'wpo_wcpdf_isbn', '_gtin', 'gtin', '_gtin_code', '_wpm_gtin_code', '_ean', 'ean', '_upc', 'upc', '_barcode', 'barcode', ); foreach ( $meta_keys as $key ) { $val = get_post_meta( $product_id, $key, true ); if ( ! empty( $val ) && ( is_string( $val ) || is_numeric( $val ) ) ) { return trim( (string) $val ); } } // 2. WooCommerce Product Object method & Attributes if ( function_exists( 'wc_get_product' ) ) { $product = wc_get_product( $product_id ); if ( $product ) { // WooCommerce core GTIN / ISBN method if ( method_exists( $product, 'get_global_unique_id' ) ) { $guid = $product->get_global_unique_id(); if ( ! empty( $guid ) ) { return trim( (string) $guid ); } } $isbn_attr = $product->get_attribute( 'isbn' ); if ( ! empty( $isbn_attr ) ) { return trim( $isbn_attr ); } $pa_isbn_attr = $product->get_attribute( 'pa_isbn' ); if ( ! empty( $pa_isbn_attr ) ) { return trim( $pa_isbn_attr ); } $isbn_caps = $product->get_attribute( 'ISBN' ); if ( ! empty( $isbn_caps ) ) { return trim( $isbn_caps ); } } } // 3. Custom Taxonomies (e.g., 'isbn', 'product_isbn', 'pa_isbn') $taxonomies = array( 'isbn', 'product_isbn', 'pa_isbn' ); foreach ( $taxonomies as $tax ) { if ( taxonomy_exists( $tax ) ) { $terms = wp_get_post_terms( $product_id, $tax, array( 'fields' => 'names' ) ); if ( ! empty( $terms ) && ! is_wp_error( $terms ) ) { return implode( ', ', $terms ); } } } // 4. Wildcard DB lookup for postmeta keys containing 'isbn', 'global_unique_id', or 'gtin' global $wpdb; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $db_isbn = $wpdb->get_var( $wpdb->prepare( "SELECT meta_value FROM {$wpdb->postmeta} WHERE post_id = %d AND (LOWER(meta_key) LIKE %s OR LOWER(meta_key) LIKE %s OR LOWER(meta_key) LIKE %s) AND meta_value != '' LIMIT 1", $product_id, '%' . $wpdb->esc_like( 'isbn' ) . '%', '%' . $wpdb->esc_like( 'global_unique_id' ) . '%', '%' . $wpdb->esc_like( 'gtin' ) . '%' ) ); if ( ! empty( $db_isbn ) ) { return trim( (string) $db_isbn ); } return ''; } /** * Resolve alternate contact number for an order using robust multi-source fallbacks. * * @param WC_Order $order WooCommerce order object. * @param string $primary_phone The primary phone/receiver's contact already resolved. * @return string */ private static function get_order_alternate_phone( $order, $primary_phone = '' ) { if ( ! is_a( $order, 'WC_Order' ) ) { return '-'; } $order_id = $order->get_id(); // 1. Direct meta keys lookup $meta_keys = array( '_billing_alternate_phone', 'billing_alternate_phone', '_billing_alternate_contact_number', 'billing_alternate_contact_number', '_billing_alternate_contact', 'billing_alternate_contact', '_billing_alt_phone', 'billing_alt_phone', '_billing_alt_contact', 'billing_alt_contact', '_billing_alt_contact_number', 'billing_alt_contact_number', '_billing_phone_2', 'billing_phone_2', '_billing_phone2', 'billing_phone2', '_billing_secondary_phone', 'billing_secondary_phone', '_billing_secondary_contact', 'billing_secondary_contact', '_billing_secondary_contact_number', 'billing_secondary_contact_number', '_billing_alternate_mobile', 'billing_alternate_mobile', '_billing_alternative_phone', 'billing_alternative_phone', '_billing_alternative_contact', 'billing_alternative_contact', '_billing_alternative_contact_number', 'billing_alternative_contact_number', '_shipping_alternate_phone', 'shipping_alternate_phone', '_shipping_alternate_contact_number', 'shipping_alternate_contact_number', '_shipping_alternate_contact', 'shipping_alternate_contact', '_shipping_alt_phone', 'shipping_alt_phone', '_shipping_alt_contact', 'shipping_alt_contact', '_shipping_alt_contact_number', 'shipping_alt_contact_number', '_shipping_phone_2', 'shipping_phone_2', '_shipping_phone2', 'shipping_phone2', '_shipping_secondary_phone', 'shipping_secondary_phone', '_shipping_secondary_contact', 'shipping_secondary_contact', '_shipping_secondary_contact_number', 'shipping_secondary_contact_number', '_shipping_alternate_mobile', 'shipping_alternate_mobile', '_shipping_alternative_phone', 'shipping_alternative_phone', '_shipping_alternative_contact', 'shipping_alternative_contact', '_shipping_alternative_contact_number', 'shipping_alternative_contact_number', '_alternate_contact_number', 'alternate_contact_number', '_alternate_phone', 'alternate_phone', '_alternate_contact', 'alternate_contact', '_alt_phone', 'alt_phone', '_alt_contact', 'alt_contact', '_alt_contact_number', 'alt_contact_number', '_phone_2', 'phone_2', '_phone2', 'phone2', '_secondary_phone', 'secondary_phone', '_secondary_contact', 'secondary_contact', '_secondary_contact_number', 'secondary_contact_number', '_alternate_mobile', 'alternate_mobile', '_alternative_phone', 'alternative_phone', '_alternative_contact', 'alternative_contact', '_alternative_contact_number', 'alternative_contact_number', '_extra_phone', 'extra_phone', '_other_phone', 'other_phone', '_backup_phone', 'backup_phone', ); foreach ( $meta_keys as $key ) { $val = method_exists( $order, 'get_meta' ) ? $order->get_meta( $key ) : ''; if ( empty( $val ) ) { $val = get_post_meta( $order_id, $key, true ); } if ( ! empty( $val ) && ( is_string( $val ) || is_numeric( $val ) ) ) { $clean = trim( (string) $val ); if ( ! empty( $clean ) ) { return $clean; } } } // 2. Scan Order MetaData objects if ( method_exists( $order, 'get_meta_data' ) ) { $meta_data = $order->get_meta_data(); if ( is_array( $meta_data ) ) { foreach ( $meta_data as $meta ) { if ( is_object( $meta ) && isset( $meta->key, $meta->value ) ) { $key_lower = strtolower( (string) $meta->key ); if ( strpos( $key_lower, 'alt_phone' ) !== false || strpos( $key_lower, 'alternate_phone' ) !== false || strpos( $key_lower, 'alt_contact' ) !== false || strpos( $key_lower, 'alternate_contact' ) !== false || strpos( $key_lower, 'alternative_phone' ) !== false || strpos( $key_lower, 'alternative_contact' ) !== false || strpos( $key_lower, 'secondary_phone' ) !== false || strpos( $key_lower, 'secondary_contact' ) !== false || strpos( $key_lower, 'phone_2' ) !== false || strpos( $key_lower, 'phone2' ) !== false || strpos( $key_lower, 'contact_2' ) !== false || strpos( $key_lower, 'contact2' ) !== false || strpos( $key_lower, 'mobile_2' ) !== false || strpos( $key_lower, 'mobile2' ) !== false ) { if ( is_string( $meta->value ) || is_numeric( $meta->value ) ) { $clean = trim( (string) $meta->value ); if ( ! empty( $clean ) ) { return $clean; } } } } } } } // 3. Direct DB search in postmeta global $wpdb; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $db_alt = $wpdb->get_var( $wpdb->prepare( "SELECT meta_value FROM {$wpdb->postmeta} WHERE post_id = %d AND ( LOWER(meta_key) LIKE %s OR LOWER(meta_key) LIKE %s OR LOWER(meta_key) LIKE %s OR LOWER(meta_key) LIKE %s OR LOWER(meta_key) LIKE %s OR LOWER(meta_key) LIKE %s ) AND meta_value != '' LIMIT 1", $order_id, '%' . $wpdb->esc_like( 'alternate_phone' ) . '%', '%' . $wpdb->esc_like( 'alternate_contact' ) . '%', '%' . $wpdb->esc_like( 'alt_phone' ) . '%', '%' . $wpdb->esc_like( 'alt_contact' ) . '%', '%' . $wpdb->esc_like( 'phone_2' ) . '%', '%' . $wpdb->esc_like( 'secondary_phone' ) . '%' ) ); if ( ! empty( $db_alt ) ) { return trim( (string) $db_alt ); } // 4. Customer user meta lookup if customer exists $customer_id = method_exists( $order, 'get_customer_id' ) ? $order->get_customer_id() : 0; if ( $customer_id > 0 ) { foreach ( $meta_keys as $key ) { $val = get_user_meta( $customer_id, $key, true ); if ( ! empty( $val ) && ( is_string( $val ) || is_numeric( $val ) ) ) { $clean = trim( (string) $val ); if ( ! empty( $clean ) ) { return $clean; } } } } // 5. Check if billing phone and shipping phone are both provided and different $billing_phone = method_exists( $order, 'get_billing_phone' ) ? trim( (string) $order->get_billing_phone() ) : ''; $shipping_phone = method_exists( $order, 'get_shipping_phone' ) ? trim( (string) $order->get_shipping_phone() ) : ''; if ( empty( $shipping_phone ) && method_exists( $order, 'get_meta' ) ) { $shipping_phone = trim( (string) $order->get_meta( '_shipping_phone' ) ); } $primary_clean = trim( (string) $primary_phone ); if ( '-' === $primary_clean ) { $primary_clean = ''; } if ( ! empty( $billing_phone ) && ! empty( $shipping_phone ) && $billing_phone !== $shipping_phone ) { if ( ! empty( $primary_clean ) ) { if ( $primary_clean === $shipping_phone ) { return $billing_phone; } elseif ( $primary_clean === $billing_phone ) { return $shipping_phone; } } else { return $billing_phone; } } return '-'; } private static function get_product_terms_by_type( $product_id, $type ) { global $wpdb; if ( $type === 'author' ) { $like = "tt.taxonomy LIKE '%author%' OR tt.taxonomy LIKE '%writer%'"; } elseif ( $type === 'publisher' ) { $like = "tt.taxonomy LIKE '%publisher%'"; } else { $like = "tt.taxonomy LIKE '%translator%'"; } // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared $query = $wpdb->prepare( "SELECT t.name FROM {$wpdb->term_relationships} tr JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id = tt.term_taxonomy_id JOIN {$wpdb->terms} t ON t.term_id = tt.term_id WHERE tr.object_id = %d AND ( $like )", $product_id ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.PreparedSQL.NotPrepared $terms = $wpdb->get_col( $query ); return empty( $terms ) ? '' : implode( ', ', $terms ); } private static function output_csv( $filename, $data ) { if ( ob_get_length() ) { ob_end_clean(); } header( 'Content-Type: text/csv; charset=utf-8' ); header( 'Content-Disposition: attachment; filename=' . $filename ); $output = fopen( 'php://output', 'w' ); // Add UTF-8 BOM for proper rendering of special characters (e.g. Sinhala) in Excel // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fputs fputs( $output, "\xEF\xBB\xBF" ); foreach ( $data as $row ) { $sanitized_row = array_map( function( $cell ) { if ( is_string( $cell ) && preg_match( '/^[=\+\-@\t\r]/', $cell ) ) { return "'" . $cell; } return $cell; }, (array) $row ); fputcsv( $output, $sanitized_row ); } // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose fclose( $output ); exit; } }