Skip to content

Instantly share code, notes, and snippets.

@duncanmcclean
Last active May 8, 2020 13:56
Show Gist options
  • Save duncanmcclean/a6d2f997493c5137036137806de7a8bf to your computer and use it in GitHub Desktop.
Save duncanmcclean/a6d2f997493c5137036137806de7a8bf to your computer and use it in GitHub Desktop.
Statamify to Simple Commerce migrator

Statamify Importer

This command should import most things like products, orders, customers etc for you but there are still some things that you'll need to configure by yourself.

If there's anything you neeed to customise for your store, just do it. It's why I didn't ship this as a package.

  1. Copy over the site directory of the site that used Statamify.
  2. Install Statamic's Migrator addon (this import script uses it) composer require statamic/migrator --dev
  3. Create a file in your App\Console\Commands folder called StatamifyImportCommand.php.
  4. Copy the whole of the script (the other Gist file) and paste it in as the command's contents.
  5. Run the script php please statamify-import
  6. Check over everything. If you want you can uninstall the Statamic migrator package and remove the command.
<?php
namespace App\Console\Commands;
use DoubleThreeDigital\SimpleCommerce\Models\Currency;
use DoubleThreeDigital\SimpleCommerce\Models\Country;
use DoubleThreeDigital\SimpleCommerce\Models\Coupon;
use DoubleThreeDigital\SimpleCommerce\Models\Order;
use DoubleThreeDigital\SimpleCommerce\Models\OrderStatus;
use DoubleThreeDigital\SimpleCommerce\Models\Product;
use DoubleThreeDigital\SimpleCommerce\Models\ProductCategory;
use DoubleThreeDigital\SimpleCommerce\Models\ShippingZone;
use DoubleThreeDigital\SimpleCommerce\Models\TaxRate;
use DoubleThreeDigital\SimpleCommerce\Models\Variant;
use Facades\Statamic\Console\Processes\Composer;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
use Statamic\Console\RunsInPlease;
use Statamic\Facades\Yaml;
use Statamic\Stache\Stache;
use Statamic\Migrator\Configurator;
class StatamifyImportCommand extends Command
{
/**
* For this script to work, please copy over your site folder
* from your Statamify install and copy it into this site's root.
*
* From there, the importer will try and import as much as it can.
*/
use RunsInPlease;
protected $signature = 'statamify-import';
protected $description = 'Import as much as possible from your Statamify site.';
public $siteFolder;
public $usersFolder;
public $categoriesFolder;
public $couponsFolder;
public $customersFolder;
public $ordersFolder;
public $productsFolder;
public $settingsFile;
public function __construct()
{
parent::__construct();
$this->siteFolder = base_path('site');
$this->usersFolder = $this->siteFolder.'/users';
$this->categoriesFolder = $this->siteFolder.'/content/collections/store_categories';
$this->couponsFolder = $this->siteFolder.'/content/collections/store_coupons';
$this->customersFolder = $this->siteFolder.'/content/collections/store_customers';
$this->ordersFolder = $this->siteFolder.'/storage/statamify/orders';
$this->productsFolder = $this->siteFolder.'/content/collections/store_products';
$this->settingsFile = $this->siteFolder.'/settings/addons/statamify.yaml';
}
public function handle()
{
if (! File::exists($this->siteFolder)) {
$this->error('Please copy your site folder.');
}
$this
->importSettings()
->importCategories()
->importCoupons()
->importProducts()
->importCustomersAndOrders();
}
protected function importSettings()
{
$this->info('Importing Settings...');
if (! File::exists($this->settingsFile)) {
$this->warn('The Statamify settings file could not be found. Moving on...');
return $this;
}
$statamifySettings = Yaml::parse(file_get_contents($this->settingsFile));
Configurator::file('simple-commerce.php')
->set('gateways', collect($statamifySettings['gateways'])
->reduce(function ($gatewayList, $gateway) {
switch ($gateway['type']) {
case "cheque":
$gatewayList[null] = [];
case "stripe":
Composer::require('doublethreedigital/simple-commerce-stripe');
$gatewayList["\DoubleThreeDigital\SimpleCommerceStripe\StripeGateway::class"] = [];
}
return $gatewayList;
})
)
->set('currency.iso', $statamifySettings['currency'][0]['code']);
TaxRate::create([
'name' => 'Old Tax Rate',
'description' => null,
'rate' => 0,
]);
collect($statamifySettings['shipping_zones'])
->each(function ($original) {
$zone = ShippingZone::create([
'name' => $original['name'],
]);
if (isset($original['countries'])) {
collect($original['countries'])
->each(function ($original) use ($zone) {
Country::where('iso', $original)
->get()
->each(function ($country) use ($zone) {
$country->update(['zone_id' => $zone->id]);
});
});
}
if (isset($original['price_rates'])) {
collect($original['price_rates'])
->each(function ($original) use ($zone) {
$zone->rates()->create([
'name' => $original['name'],
'type' => 'price-based',
'minimum' => $original['min'] ?? 0,
'maximum' => $original['max'] ?? 0,
'rate' => $original['rate'] ?? 0,
]);
});
}
if (isset($original['weight_rates'])) {
collect($original['weight_rates'])
->each(function ($original) use ($zone) {
$zone->rates()->create([
'name' => $original['name'],
'type' => 'weight-based',
'minimum' => $original['min'] ?? 0,
'maximum' => $original['max'] ?? 0,
'rate' => $original['rate'] ?? 0,
]);
});
}
});
return $this;
}
protected function importCategories()
{
$this->info('Importing Categories...');
if (! File::exists($this->categoriesFolder)) {
$this->warn('The Statamify categories folder could not be found. Moving on...');
return $this;
}
collect(File::files($this->categoriesFolder))
->reject(function ($file) {
return $file->getFilename() === 'folder.yaml';
})
->each(function ($file) {
$original = Yaml::parse(file_get_contents($file));
ProductCategory::create([
'uuid' => $original['id'],
'title' => $original['title'],
'slug' => Str::slug($original['title']),
]);
});
return $this;
}
protected function importCoupons()
{
$this->info('Importing Coupons...');
if (! File::exists($this->couponsFolder)) {
$this->warn('The Statamify coupons folder could not be found. Moving on...');
return $this;
}
collect(File::files($this->couponsFolder))
->reject(function ($file) {
return $file->getFilename() === 'folder.yaml';
})
->each(function ($file) {
$original = Yaml::parse(file_get_contents($file));
Coupon::create([
'uuid' => $original['id'],
'name' => $original['title'],
'code' => $file->getFilenameWithoutExtension(),
'type' => ($original['type'] === 'percentage' ?? 'percent_discount') ?? ($original['type'] === 'fixed' ?? 'fixed_discount') ?? null,
'value' => $original['value'] ?? 0,
'minimum_total' => $original['min'] ?? 0,
'total_uses' => $original['total'] ?? 0,
'start_date' => $original['start_date'] ?? null,
'end_date' => $original['end_date'] ?? null,
]);
});
return $this;
}
protected function importProducts()
{
$this->info('Importing Products...');
if (! File::exists($this->productsFolder)) {
$this->warn('The Statamify products folder could not be found. Moving on...');
return $this;
}
collect(File::files($this->productsFolder))
->reject(function ($file) {
return $file->getFilename() === 'folder.yaml';
})
->each(function ($file) {
$original = Yaml::parse(file_get_contents($file));
$original['slug'] = explode('.', $file->getFilenameWithoutExtension())[1];
$original['category'] = null;
if (isset($original['categories'][0])) {
$category = ProductCategory::where('uuid', $original['categories'][0])->first();
if (isset($category->id)) {
$original['category'] = $category;
}
}
$product = Product::create([
'uuid' => $original['id'],
'title' => $original['title'],
'slug' => $original['slug'],
'is_enabled' => true,
'needs_shipping' => false,
'product_category_id' => $original['category'],
'tax_rate_id' => TaxRate::first()->id,
]);
$weight = $original['weight'] ?? 0;
$unlimitedStock = $original['track_inventory'];
if (isset($original['variants'])) {
collect($original['variants'])
->each(function ($original) use ($product, $weight, $unlimitedStock) {
$product->variants()->create([
'uuid' => $original['id'] ?? (new Stache)->generateId(),
'name' => $original['attrs'] ?? $product->title,
'sku' => $original['sku'] ?? $product->slug.'-'.uniqid(),
'description' => '',
'images' => [],
'weight' => $weight,
'price' => (float) isset($original['price']) && $original['price'] != '' ? $original['price'] : 00.00,
'stock' => (bool) isset($original['inventory']) ? $original['inventory'] : 0,
'unlimited_stock' => $unlimitedStock,
'max_quantity' => 5,
]);
});
} else {
$product->variants()->create([
'name' => $product->title,
'sku' => $product->slug,
'description' => '',
'images' => [],
'weight' => $weight,
'price' => isset($original['price']) ? $original['price'] : 00.00,
'stock' => (bool) isset($original['inventory']) ? $original['inventory'] : 0,
'unlimited_stock' => $unlimitedStock,
'max_quantity' => 5,
]);
}
});
return $this;
}
protected function importCustomersAndOrders()
{
$this->info('Importing Customers and Orders...');
if (! File::exists($this->customersFolder)) {
$this->warn('The Statamify coupons folder could not be found. Moving on...');
return $this;
}
$statamicUsers = collect(File::files($this->usersFolder))
->map(function ($userFile) {
$details = Yaml::parse(file_get_contents($userFile));
if (! isset($details['email'])) {
$details['email'] = $userFile->getFilenameWithoutExtension();
}
return $details;
});
$orders = collect(File::files($this->ordersFolder))
->map(function ($orderFile) {
$details = Yaml::parse(file_get_contents($orderFile));
$details['filename'] = $orderFile->getFilenameWithoutExtension();
return $details;
});
collect(File::files($this->customersFolder))
->reject(function ($file) {
return $file->getFilename() === 'folder.yaml';
})
->each(function ($file) use ($statamicUsers, $orders) {
$original = Yaml::parse(file_get_contents($file));
$statamicUser = $statamicUsers->where('id', $original['user'])->first();
$customerModel = config('simple-commerce.customers.model');
$customerModel = new $customerModel();
// You may need to customise this depending on your setup...
$customer = $customerModel->create([
'id' => $statamicUser['id'],
'name' => $original['title'],
'email' => $statamicUser['email'],
'password' => $statamicUser['password_hash'],
]);
collect($original['addresses'])
->each(function ($original) use ($customer) {
$customer->addresses()->create([
'name' => $original['first_name'].' '.$original['last_name'],
'address1' => $original['address'],
'address2' => $original['address_2'],
'city' => $original['city'],
'zip_code' => $original['postal'],
'state_id' => null,
'country_id' => Country::where('iso', $original['country'])->first()->id,
]);
});
collect($original['orders'])
->each(function ($original) use ($orders, $customer) {
$statamifyOrder = $orders->where('filename', $original['slug'])->first();
$order = Order::create([
'uuid' => $statamifyOrder['id'],
'gateway' => 'DoubleThreeDigital\SimpleCommerce\Gateways\DummyGateway',
'is_paid' => $statamifyOrder['status'] === 'awaiting_payment' ? false : true,
'is_completed' => $statamifyOrder['status'] === 'awaiting_payment' ? false : true,
'total' => $statamifyOrder['summary']['total']['grand'],
'item_total' => $statamifyOrder['summary']['total']['sub'],
'tax_total' => $statamifyOrder['summary']['total']['tax'],
'shipping_total' => $statamifyOrder['summary']['total']['shipping'],
'coupon_total' => $statamifyOrder['summary']['total']['discount'],
'currency_id' => Currency::where('iso', $statamifyOrder['summary']['currency']['code'])->first()->id,
'order_status_id' => OrderStatus::first()->id,
'billing_address_id' => $statamifyOrder['billing'] === [] ? null : $customer->addresses()->where('zip_code', $statamifyOrder['shipping']['postal'])->first()->id,
'shipping_address_id' => $customer->addresses()->where('zip_code', $statamifyOrder['shipping']['postal'])->first()->id,
'customer_id' => $customer->id,
]);
collect($statamifyOrder['summary']['items'])
->each(function ($item) use ($order) {
$order->lineItems()->create([
'uuid' => $item['id'],
'sku' => $item['sku'],
'deescription' => $item['variant'],
'note' => '',
'price' => (float) $item['price'],
'total' => (float) $item['price'] * $item['quantity'],
'weight' => 0,
'quantity' => (int) $item['quantity'],
'variant_id' => Variant::where('sku', $item['sku'])->first()->id,
'tax_rate_id' => TaxRate::first()->id,
'shipping_rate_id' => null,
'coupon_id' => null,
]);
});
});
});
return $this;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment