Created
July 12, 2018 20:16
-
-
Save ashfame/a8c01108fee24a9654bebe388ee3fb7d to your computer and use it in GitHub Desktop.
Feed the export from SubscribePro to it and it will generate a CSV that's Recharge compliant
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// For reuse, just look inside get_mapped_value() that's where all the specific data handling is, which is what you will need to change | |
// To understand, how this works, head to run() | |
// ini_set( 'memory_limit', '2000M' ); | |
class Recharge_Compliant_CSV_From_SubscribePro_Export { | |
private $source_csv_filename; | |
private $output_csv_filename; | |
private $products; | |
public function __construct() { | |
global $argv; | |
if ( ! isset( $argv[1] ) ) { | |
die( 'Incorrect invocation! Use: ' . PHP_EOL . '$ ' . $argv[0] . ' file.csv' .PHP_EOL ); | |
} | |
$this->source_csv_filename = $argv[1]; // csv file | |
$this->output_csv_filename = str_replace( '.csv', '', $this->source_csv_filename ) . '-recharge-compliant-' . time() . '.csv'; | |
// make sure CSV file exists | |
if ( ! file_exists( $this->source_csv_filename ) ) { | |
die( "Specified CSV file does not exist - " . $this->source_csv_filename . PHP_EOL ); | |
} | |
$this->define_mapping_values(); | |
$this->run(); | |
} | |
public function define_mapping_values() { | |
$this->products = array( | |
'BARL-250-B1' => array( | |
'shopify_product_name' => 'USDA Organic Barleygrass Juice', | |
'shopify_variant_name' => '', | |
'shopify_product_id' => '1376502087722', | |
'shopify_variant_id' => '12718037696554' | |
), | |
'BLUE-250-B1' => array( | |
'shopify_product_name' => 'Wild Blueberry', | |
'shopify_variant_name' => '', | |
'shopify_product_id' => '1376513458218', | |
'shopify_variant_id' => '12718034714666' | |
), | |
'EP-REISH-50' => array( | |
'shopify_product_name' => 'USDA Organic Reishi', | |
'shopify_variant_name' => '50g', | |
'shopify_product_id' => '1376513753130', | |
'shopify_variant_id' => '12553323905066' | |
), | |
'EP-REISH-250' => array( | |
'shopify_product_name' => 'USDA Organic Reishi', | |
'shopify_variant_name' => '250g', | |
'shopify_product_id' => '1376513753130', | |
'shopify_variant_id' => '12553390555178' | |
), | |
'EP-CHAG-50' => array( | |
'shopify_product_name' => 'USDA Organic Chaga', | |
'shopify_variant_name' => '50g', | |
'shopify_product_id' => '1376512507946', | |
'shopify_variant_id' => '12553435578410' | |
), | |
'EP-CHAG-250' => array( | |
'shopify_product_name' => 'USDA Organic Chaga', | |
'shopify_variant_name' => '250g', | |
'shopify_product_id' => '1376512507946', | |
'shopify_variant_id' => '12553491480618' | |
) | |
); | |
} | |
public function csv_to_array($filename='', $delimiter=',') { | |
if(!file_exists($filename) || !is_readable($filename)) | |
return FALSE; | |
$header = NULL; | |
$data = array(); | |
if (($handle = fopen($filename, 'r')) !== FALSE) | |
{ | |
while (($row = fgetcsv($handle, 0, $delimiter)) !== FALSE) | |
{ | |
if(!$header) | |
$header = $row; | |
else | |
$data[] = array_combine($header, $row); | |
} | |
fclose($handle); | |
} | |
return $data; | |
} | |
public function get_product_details_from_row( $row ) { | |
if ( ! isset( $this->products[ $row['product_sku' ] ] ) ) { | |
print_r( $row ); | |
print_r( $this->products ); | |
die( 'Undefined Product SKU [' . $row['product_sku'] . '] encountered. Please fix data before continuing' . PHP_EOL ); | |
} | |
return $this->products[ $row[ 'product_sku' ] ]; | |
} | |
public function get_interval_details_from_row( $row ) { | |
list( $frequency, $type ) = explode( ' ', trim( $row['interval'] ) ); | |
// possible values accounted for - Month(s) Week(s) Day(s) | |
$type = strtolower( $type ); // Month / month | |
$type = rtrim( $type, 's' ); // weeks -> week | |
return array( | |
'charge_interval_unit_type' => $type, | |
'charge_interval_frequency' => $frequency, | |
'shipping_interval_unit_type' => $type, | |
'shipping_interval_frequency' => $frequency | |
); | |
} | |
/** | |
* Docs say | |
* If the customer has an inactive subscription you should enter cancelled in this column. Otherwise, leave it blank. | |
*/ | |
public function get_status_from_row( $row ) { | |
$status = strtolower( $row['status'] ); | |
if ( $status == 'active' ) { | |
return ''; | |
} else if ( $status == 'cancelled' ) { // not sure what SubscribePro returns cancelled or inactive, accordingly adapt | |
return 'cancelled'; | |
} else { | |
die( 'Undefined Subscription status [' . $status . '] encountered. Please fix data before continuing' . PHP_EOL ); | |
} | |
} | |
public function get_customer_created_at_date( $row ) { | |
$date = DateTime::createFromFormat( 'Y-m-d H:i:s', $row['created'], new DateTimeZone( 'UTC' ) ); | |
return $date->format( 'm/d/Y' ); | |
} | |
public function get_next_charge_date( $row ) { | |
$date = DateTime::createFromFormat( 'Y-m-d', $row['next_order_date'], new DateTimeZone( 'UTC' ) ); | |
$now = new DateTime( 'now', new DateTimeZone( 'UTC' ) ); | |
if ( $date <= $now ) { | |
echo '🔥'; | |
} | |
return $date->format( 'm/d/Y' ); | |
} | |
public function get_mapped_value( $name, $row ) { | |
switch ( $name ) { | |
case 'subscription_id': | |
return '113413'; | |
break; | |
case 'product_details': | |
return $this->get_product_details_from_row( $row ); | |
break; | |
case 'interval_details': | |
return $this->get_interval_details_from_row( $row ); | |
break; | |
case 'recurring_price': | |
return $row['recurring_price']; | |
break; | |
case 'quantity': | |
return $row['qty']; | |
break; | |
case 'shipping_email': | |
return $row['customer.email']; | |
break; | |
case 'status': | |
return $this->get_status_from_row( $row ); | |
case 'customer_stripe_id': | |
return $row['payment_profile.payment_token']; | |
break; | |
case 'shipping_first_name': | |
return $row['shipping_address.first_name']; | |
break; | |
case 'shipping_last_name': | |
return $row['shipping_address.last_name']; | |
break; | |
case 'shipping_phone': | |
return $row['shipping_address.phone']; | |
break; | |
case 'shipping_address_1': | |
return $row['shipping_address.street1']; | |
break; | |
case 'shipping_address_2': | |
return $row['shipping_address.street2']; | |
break; | |
case 'shipping_city': | |
return $row['shipping_address.city']; | |
break; | |
case 'shipping_province': | |
return $row['shipping_address.region']; | |
break; | |
case 'shipping_zip': | |
return $row['shipping_address.post_code']; | |
break; | |
case 'shipping_country': | |
return $row['shipping_address.country']; | |
break; | |
case 'shipping_company': | |
return $row['shipping_address.company']; | |
break; | |
case 'billing_first_name': | |
return $row['billing_address.first_name']; | |
break; | |
case 'billing_last_name': | |
return $row['billing_address.last_name']; | |
break; | |
case 'billing_phone': | |
return $row['billing_address.phone']; | |
break; | |
case 'billing_address_1': | |
return $row['billing_address.street1']; | |
break; | |
case 'billing_address_2': | |
return $row['billing_address.street2']; | |
break; | |
case 'billing_city': | |
return $row['billing_address.city']; | |
break; | |
case 'billing_province_state': | |
return $row['billing_address.region']; | |
break; | |
case 'billing_postalcode': | |
return $row['billing_address.post_code']; | |
break; | |
case 'billing_country': | |
return $row['billing_address.country']; | |
break; | |
case 'date customer created_at': | |
return $this->get_customer_created_at_date( $row ); | |
break; | |
case 'next_charge_date': | |
return $this->get_next_charge_date( $row ); | |
break; | |
default: | |
return ''; | |
} | |
} | |
public function transform_row( $row ) { | |
$data = array(); | |
// define as per the order of columns you desire in the output CSV | |
$data['subscription_id'] = $this->get_mapped_value( 'subscription_id', $row ); | |
$data = array_merge( $data, $this->get_mapped_value( 'product_details', $row ) ); | |
$data['quantity'] = $this->get_mapped_value( 'quantity', $row ); | |
$data['recurring_price'] = $this->get_mapped_value( 'recurring_price', $row ); | |
$data = array_merge( $data, $this->get_mapped_value( 'interval_details', $row ) ); | |
$data['status'] = $this->get_mapped_value( 'status', $row ); | |
$data['charge_on_day_of_month'] = ''; // Need an empty column for now | |
// Figure how to get this data without needing to do it by hand / Maybe its optional? | |
$data['last_charge_date'] = ''; | |
$data['next_charge_date'] = $this->get_mapped_value( 'next_charge_date', $row ); | |
$data['customer_stripe_id'] = $this->get_mapped_value( 'customer_stripe_id', $row ); | |
$data['date customer created_at'] = $this->get_mapped_value( 'date customer created_at', $row ); | |
$data['shipping_email'] = $this->get_mapped_value( 'shipping_email', $row ); | |
$data['shipping_first_name'] = $this->get_mapped_value( 'shipping_first_name', $row ); | |
$data['shipping_last_name'] = $this->get_mapped_value( 'shipping_last_name', $row ); | |
$data['shipping_phone'] = $this->get_mapped_value( 'shipping_phone', $row ); | |
$data['shipping_address_1'] = $this->get_mapped_value( 'shipping_address_1', $row ); | |
$data['shipping_address_2'] = $this->get_mapped_value( 'shipping_address_2', $row ); | |
$data['shipping_city'] = $this->get_mapped_value( 'shipping_city', $row ); | |
$data['shipping_province'] = $this->get_mapped_value( 'shipping_province', $row ); | |
$data['shipping_zip'] = $this->get_mapped_value( 'shipping_zip', $row ); | |
$data['shipping_country'] = $this->get_mapped_value( 'shipping_country', $row ); | |
$data['shipping_company'] = $this->get_mapped_value( 'shipping_company', $row ); | |
$data['billing_first_name'] = $this->get_mapped_value( 'billing_first_name', $row ); | |
$data['billing_last_name'] = $this->get_mapped_value( 'billing_last_name', $row ); | |
$data['billing_address_1'] = $this->get_mapped_value( 'billing_address_1', $row ); | |
$data['billing_address_2'] = $this->get_mapped_value( 'billing_address_2', $row ); | |
$data['billing_city'] = $this->get_mapped_value( 'billing_city', $row ); | |
$data['billing_postalcode'] = $this->get_mapped_value( 'billing_postalcode', $row ); | |
$data['billing_province_state'] = $this->get_mapped_value( 'billing_province_state', $row ); | |
$data['billing_country'] = $this->get_mapped_value( 'billing_country', $row ); | |
$data['billing_phone'] = $this->get_mapped_value( 'billing_phone', $row ); | |
return $data; | |
} | |
public function run() { | |
$csv_data = $this->csv_to_array( $this->source_csv_filename ); | |
$new_data = array(); | |
//print_r( $csv_data ); | |
echo "CSV rows: " . count( $csv_data ) . PHP_EOL; | |
foreach ( $csv_data as $key => $row ) { | |
echo "🔑 $key" . PHP_EOL; | |
if ( $row['product_sku'] == 'EP-WHEA-250' ) { | |
continue; // skip it | |
} | |
$new_data[] = $this->transform_row( $row ); | |
} | |
//print_r( $new_data ); | |
echo "CSV rows ready: " . count( $new_data ) . PHP_EOL; | |
$this->write_csv( $new_data ); | |
} | |
public function write_csv( $data ) { | |
if ( ( $export_handle = fopen( $this->output_csv_filename, 'w' ) ) === false ) { | |
die( 'Could not open export csv filename' . PHP_EOL ); | |
} | |
fputcsv( $export_handle, array_keys( $data[0] ) ); | |
foreach ( $data as $row ) { | |
fputcsv( $export_handle, $row ); | |
} | |
fclose( $export_handle ); | |
echo "CSV is ready 👍 " . $this->output_csv_filename . PHP_EOL; | |
} | |
} | |
new Recharge_Compliant_CSV_From_SubscribePro_Export(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment