Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ashfame/a8c01108fee24a9654bebe388ee3fb7d to your computer and use it in GitHub Desktop.
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
<?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