Files
kupshop/bundles/External/SprintBundle/Import/ImportDatabase.php
2025-08-02 16:30:27 +02:00

635 lines
25 KiB
PHP

<?php
namespace External\SprintBundle\Import;
use KupShop\ContentBundle\Util\Block;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\RewriteBundle\Util\Rewrite;
use Query\Operator;
class ImportDatabase
{
use \DatabaseCommunication;
public const DATABASE = 'import_ulvang';
/** @var \Downloader */
protected $downloader;
private $rewrite;
private $block;
private $variations;
private $variationsValues;
private $result;
private $relatedCache = [];
private $toDelete = [];
public function __construct()
{
$this->rewrite = ServiceContainer::getService(Rewrite::class);
$this->block = ServiceContainer::getService(Block::class);
$this->downloader = new \Downloader();
}
public function import($request)
{
$this->importCoupons($request);
// $this->importUsers();
// $this->importOrders(100000);
}
public function update($request)
{
$this->importUsers();
$this->importOrders(100000);
}
public function importUsers($update = false)
{
sqlGetConnection()->transactional(function () {
$qb = $this->getQueryBuilder('vmeqzk_users', 'u')
->select('ID as id, user_pass AS passw, display_name AS name, user_login AS surname,
user_email AS email, user_registered AS date_reg');
$count = 0;
foreach ($qb->execute() as $user) {
if ($this->selectSQL('users', ['email' => $user['email']])->fetch()) {
continue;
}
if ($this->selectSQL('users', ['id' => $user['id']])->fetch()) {
continue;
}
$user = $this->getUserMeta($user);
$this->insertSQL('users', $user);
$count++;
}
$this->writeLine('Naimportovano uzivatelu: '.$count);
});
}
public function getUserMeta($user)
{
$ID = $user['id'];
$meta_fields = ['first_name',
'last_name',
'nickname',
'ywces_birthday',
'billing_first_name',
'billing_last_name',
'billing_company',
'billing_email',
'billing_phone',
'billing_country',
'billing_city',
'billing_postcode',
'billing_address_1',
'billing_address_2',
'shipping_first_name',
'shipping_last_name',
'shipping_company',
'shipping_country',
'shipping_city',
'shipping_postcode',
'shipping_address_1',
'shipping_address_2',
];
$qb_meta = $this->getQueryBuilder('vmeqzk_usermeta', 'um')
->select('*')->where(Operator::inStringArray($meta_fields, 'meta_key'))
->andWhere('meta_value != ""')
->andWhere(Operator::equals(['user_id' => $ID]))
->orderBy('user_id');
$user_meta = $qb_meta->execute()->fetchAll();
if ($user_meta) {
$user_meta = array_combine(array_column($user_meta, 'meta_key'), array_column($user_meta, 'meta_value'));
$custom_data = [];
$user['name'] = $user_meta['billing_first_name'] ?? $user_meta['first_name'] ?? $user['name'];
$user['surname'] = $user_meta['billing_last_name'] ?? $user_meta['last_name'] ?? $user['surname'];
$user['firm'] = $user_meta['billing_company'] ?? null;
$user['phone'] = $user_meta['billing_phone'] ?? null;
$user['country'] = $user_meta['billing_country'] ?? null;
$user['city'] = $user_meta['billing_city'] ?? null;
$user['zip'] = $user_meta['billing_postcode'] ?? null;
$user['street'] = $user_meta['billing_address_1'] ?? null;
$user['custom_address'] = $user_meta['billing_address_2'] ?? null;
$user['id_language'] = ($user['country'] == 'SK' ? 'sk' : 'cs');
$user['delivery_name'] = $user_meta['shipping_first_name'] ?? null;
$user['delivery_surname'] = $user_meta['shipping_last_name'] ?? null;
$user['delivery_firm'] = $user_meta['shipping_company'] ?? null;
$user['delivery_country'] = $user_meta['shipping_country'] ?? null;
$user['delivery_city'] = $user_meta['shipping_city'] ?? null;
$user['delivery_zip'] = $user_meta['shipping_postcode'] ?? null;
$user['delivery_street'] = $user_meta['shipping_address_1'] ?? null;
$user['delivery_custom_address'] = $user_meta['shipping_address_2'] ?? null;
$custom_data['nickname'] = $user_meta['nickname'];
$custom_data['ywces_birthday'] = $user_meta['ywces_birthday'] ?? null;
if (($user_meta['billing_email'] ?? null) != $user['email']) {
$custom_data['billing_email'] = $user_meta['billing_email'] ?? null;
}
$user['custom_data'] = json_encode(array_filter($custom_data));
$user = array_filter($user);
}
return $user;
}
public function importOrders($limit = 1000, $offset = 0, $connectOnlyWithProducts = false)
{
ini_set('max_execution_time', 60 * 60 * 2);
ini_set('memory_limit', '1548M');
/* if (!$connectOnlyWithProducts) {
sqlQueryBuilder()->delete('orders')->execute();
sqlQuery('ALTER TABLE orders AUTO_INCREMENT = 1');
}*/
$qb = $this->getQueryBuilder('vmeqzk_posts', 'jp')
->select('jp.ID as id, jp.ID as order_no, jp.post_date AS date_created, jp.post_modified AS date_updated,
jp.post_excerpt AS note_user, jp.post_status')
->where(Operator::equals(['jp.post_type' => 'shop_order']))
->orderBy('jp.ID');
$counter = 0;
$meta_fields = [
'_customer_user',
'_customer_ip_address',
'_customer_user_agent',
'_completed_date',
'_paid_date',
'_billing_first_name',
'_billing_last_name',
'_billing_email',
'_billing_phone',
'_billing_company',
'_billing_dic',
'_billing_ic',
'_billing_address_1',
'_billing_address_2',
'_billing_city',
'_billing_country',
'_billing_postcode',
'_shipping_first_name',
'_shipping_last_name',
'_shipping_company',
'_shipping_address_1',
'_shipping_address_2',
'_shipping_city',
'_shipping_country',
'_shipping_postcode',
'_order_currency',
'_order_tax',
'_order_total',
'_cart_discount',
'_cart_discount_tax',
'_prices_include_tax',
'_payment_method',
'_payment_method_title',
'_selected_paymentchannel',
'f_payment_method',
'_shipping_method',
'_order_shipping',
'_order_shipping_tax',
];
foreach ($qb->execute() as $order) {
$counter++;
echo 'id - '.$order['order_no'].'<br />';
sqlQueryBuilder()->delete('orders')->andWhere(Operator::equals([
'order_no' => $order['order_no'],
]))->execute();
try {
$ID = $order['id'];
$status = $order['post_status'];
unset($order['post_status']);
switch ($status) {
case 'wc-cancelled':
$order['status_storno'] = 1;
// no break
case 'wc-completed':
case 'wc-refunded':
$order['status'] = 2; // vyřízena
break;
case 'wc-pending':
case 'wc-failed':
case 'wc-nezaplaceno':
$order['status'] = 2; // Čekání na platbu
break;
case 'wc-shipped':
$order['status'] = 2; // Odesláno
break;
case 'wc-processing':
$order['status'] = 2; // zpracovává se
break;
case 'wc-on-hold':
$order['status'] = 2; // Čeká na vyřízení
break;
}
$delivery_type = ['payment' => '', 'shipping' => ''];
$delivery_price = \DecimalConstants::zero();
$order_meta = $this->getQueryBuilder('vmeqzk_postmeta', 'jpm')
->select('jpm.*')->join('jpm', self::getTable('vmeqzk_posts'), 'jp', 'jpm.post_id = jp.ID')
->where(Operator::equals(['jp.post_type' => 'shop_order', 'jpm.post_id' => $ID]))
->andWhere(Operator::inStringArray($meta_fields, 'jpm.meta_key'))->execute()->fetchAll();
if ($order_meta) {
$order_meta = array_combine(array_column($order_meta, 'meta_key'), array_column($order_meta, 'meta_value'));
$order['id_user'] = $this->defaultWhenEmpty($order_meta['_customer_user']);
$order['source'] = 'import';
$note_admin['ip_address'] = $order_meta['_customer_ip_address'] ?? null;
$note_admin['user_agent'] = $order_meta['_customer_user_agent'] ?? null;
$order['note_admin'] = json_encode(array_filter($note_admin));
$order['currency'] = $this->defaultWhenEmpty($order_meta['_order_currency'], 'CZK');
$order['date_handle'] = $order_meta['_completed_date'] ?? null;
if (!empty($order_meta['_paid_date'])) {
$order['status_payed'] = 1;
}
$order['total_price'] = $order_meta['_order_total'] ?? 0;
$order['invoice_name'] = $order_meta['_billing_first_name'] ?? '';
$order['invoice_surname'] = $order_meta['_billing_last_name'] ?? '';
$order['invoice_firm'] = $order_meta['_billing_company'] ?? '';
$order['invoice_ico'] = $order_meta['_billing_ic'] ?? '';
$order['invoice_dic'] = $order_meta['_billing_dic'] ?? '';
$order['invoice_street'] = $order_meta['_billing_address_1'] ?? '';
$order['invoice_custom_address'] = $order_meta['_billing_address_2'] ?? '';
$order['invoice_city'] = $order_meta['_billing_city'] ?? '';
$order['invoice_zip'] = $order_meta['_billing_postcode'] ?? '';
$order['invoice_country'] = $order_meta['_billing_country'] ?? '';
$order['invoice_phone'] = $order_meta['_billing_phone'] ?? '';
$order['invoice_email'] = $order_meta['_billing_email'] ?? '';
$order['delivery_name'] = $order_meta['_shipping_first_name'] ?? '';
$order['delivery_surname'] = $order_meta['_shipping_last_name'] ?? '';
$order['delivery_firm'] = $order_meta['_shipping_company'] ?? '';
$order['delivery_street'] = $order_meta['_shipping_address_1'] ?? '';
$order['delivery_custom_address'] = $order_meta['_shipping_address_2'] ?? '';
$order['delivery_city'] = $order_meta['_shipping_city'] ?? '';
$order['delivery_zip'] = $order_meta['_shipping_postcode'] ?? '';
$order['delivery_country'] = $order_meta['_shipping_country'] ?? '';
$delivery_type['payment'] = ($order_meta['_payment_method_title'] ?? '');
if ($order_shipping = toDecimal($order_meta['_order_shipping'] ?? '')) {
$delivery_price = $order_shipping;
}
} else {
echo 'not meta';
}
if (!$connectOnlyWithProducts) {
$this->insertSQL('orders', $order);
}
$order_items = $this->getQueryBuilder('vmeqzk_woocommerce_order_items', 'jwoi')
->select('jwoi.*')
->where(Operator::equals(['jwoi.order_id' => $ID]))
->execute()->fetchAll();
if ($order_items) {
if ($connectOnlyWithProducts) {
$this->deleteSQL('order_items', ['id_order' => $ID]);
}
$order_items = array_combine(array_column($order_items, 'order_item_id'), $order_items);
foreach ($order_items as $key => $item) {
$qb_meta = $this->getQueryBuilder('vmeqzk_woocommerce_order_itemmeta', 'jwoim')
->select('jwoim.*')
->where(Operator::equals(['jwoim.order_item_id' => $key]))->execute();
$item_meta = array_filter(sqlFetchAll($qb_meta, ['meta_key' => 'meta_value']));
$order_item = ['id_order' => $item['order_id'], 'descr' => $item['order_item_name'], 'tax' => 21];
$order_item['id_product'] = $item_meta['_product_id'] ?? null;
$order_item['id_variation'] = $item_meta['_variation_id'] ?? null;
$order_item['date'] = $order['date_created'];
$order_item['pieces'] = $item_meta['_qty'] ?? 1;
$order_item['piece_price'] = toDecimal($item_meta['_line_subtotal'] ?? 0);
$order_item['total_price'] = toDecimal($item_meta['_line_total'] ?? 0);
if ($item['order_item_type'] == 'shipping') {
$delivery_type['shipping'] = $item['order_item_name'];
}
if ($item['order_item_type'] == 'fee') {
$delivery_type['payment'] = $item['order_item_name'];
$delivery_price = $delivery_price->add(toDecimal($item_meta['_line_total'] ?? 0));
}
if (($item['order_item_type'] == 'line_item') || ($item['order_item_type'] == 'coupon')) {
if ($item['order_item_type'] == 'coupon') {
$order_item['note'] = '{"item_type":"coupon"}';
}
$product['code'] = $this->getProductParam('_sync_id', $order_item['id_variation']) ?? 0;
if ($product['code']) {
if ($variation = sqlQueryBuilder()->select('id,id_product')->from('products_variations')->andWhere(Operator::equals(['code' => $product['code']]))->execute()->fetchAllAssociative()) {
$order_item['id_variation'] = $variation[0]['id'];
$order_item['id_product'] = $variation[0]['id_product'];
} elseif ($product = sqlQueryBuilder()->select('id')->from('products')->andWhere(Operator::equals(['code' => $product['code']]))->execute()->fetchAllAssociative()) {
$order_item['id_product'] = $product[0]['id'];
unset($order_item['id_variation']);
} else {
unset($order_item['id_product']);
unset($order_item['id_variation']);
}
} else {
unset($order_item['id_product']);
unset($order_item['id_variation']);
}
try {
sqlQueryBuilder()->insert('order_items')->directValues($order_item)->execute();
// $this->insertSQL('order_items', $order_item);
} catch (\Exception $e) {
echo $e->getMessage();
}
}
}
$paymentType = $delivery_type['payment'];
$delivery_type = implode(' - ', $delivery_type);
if (!$delivery_price->isZero()) {
$delivery_price = $delivery_price->removeVat(21);
$order_item = ['id_order' => $item['order_id'],
'date' => $order['date_created'],
'descr' => $delivery_type,
'tax' => 21,
'piece_price' => $delivery_price,
'total_price' => $delivery_price,
'note' => '{"item_type":"delivery"}'];
$this->insertSQL('order_items', $order_item);
}
if (!$connectOnlyWithProducts) {
$delivery = explode(' - ', $delivery_type);
$this->updateSQL('orders',
['delivery_type' => $delivery_type],
['id' => $ID]);
$this->insertSQL('orders_history', [
'comment' => $delivery_type,
'id_order' => $ID,
'id_status' => 0,
'date' => $order['date_created'],
'notified' => 0,
]);
if ($order['status_payed'] ?? false && !empty($paymentType)) {
$this->insertSQL('order_payments', [
'note' => $paymentType,
'id_order' => $ID,
'date' => $order_meta['_paid_date'],
'price' => $order['total_price'],
'method' => 0,
'status' => 0,
]);
}
}
}
} catch (\Exception $e) {
echo $e->getMessage();
}
}
echo 'konec';
}
private function defaultWhenEmpty($value, $default = null)
{
return (empty($value)) ? $default : $value;
}
/**
* @param null $alias
*
* @return \Query\QueryBuilder
*/
private function getQueryBuilder($table, $alias = null)
{
return sqlQueryBuilder()->from(self::getTable($table), $alias);
}
private static function getTable($table)
{
return self::DATABASE.'.'.$table;
}
public function getResult()
{
return $this->result;
}
private function writeLine($str)
{
$this->result[] = $str;
}
private function importCoupons($request)
{
$run = $request->query->get('run');
ini_set('max_execution_time', 60 * 60 * 5);
ini_set('memory_limit', '1548M');
$count = 0;
if (!$run) {
return;
}
$qb = $this->getQueryBuilder('vmeqzk_posts', 'p')
->select('*')
->andWhere(Operator::equals(['post_type' => 'shop_coupon']));
foreach ($qb->execute() as $item) {
sqlQueryBuilder()->delete('order_discounts')->andWhere(Operator::equals([
'name' => $item['post_title'],
]))->execute();
$data = [];
try {
foreach ($this->getQueryBuilder('vmeqzk_postmeta', 'pm')
->select('*')->andWhere(Operator::equals(['post_id' => $item['ID']]))->execute() as $options) {
$data[$options['meta_key']] = $options['meta_value'];
}
$id = $this->processTriggers($item, $data);
$this->processActions($item, $data, $id);
} catch (\Exception $e) {
echo $e->getMessage();
}
}
sqlQueryBuilder()->delete('order_discounts')
->where(Operator::inIntArray($this->toDelete, 'id'))
->execute();
echo 'sadf';
}
public function deleteCoupons($request)
{
$run = $request->query->get('run');
ini_set('max_execution_time', 60 * 60 * 5);
ini_set('memory_limit', '1548M');
$count = 0;
if (!$run) {
return;
}
$qb = $this->getQueryBuilder('vmeqzk_posts', 'p')
->select('*')
->andWhere(Operator::equals(['post_type' => 'shop_coupon']));
foreach ($qb->execute() as $item) {
$count = sqlQueryBuilder()->select('count(*)')
->from('order_discounts_triggers')
->andWhere('JSON_EXTRACT(data, \'$.codes\') like :title')
->setParameter('title', '%'.$item['post_title'].'%')->execute()->fetchOne()
;
if ($count > 1) {
sqlQueryBuilder()->delete('order_discounts')->andWhere(Operator::equals([
'name' => $item['post_title'],
]))->execute();
}
}
}
protected function processActions($item, $data, $id)
{
$json = [
'vat' => 1,
'divideDiscountPrice' => 'N',
];
if (empty($data['discount_type'])) {
return;
}
if ($data['discount_type'] == 'percent') {
$json['unit'] = 'perc';
} else {
if ($data['discount_type'] == 'fixed_cart') {
$json['unit'] = 'CZK';
}
}
$json['discount'] = $data['coupon_amount'];
sqlQueryBuilder()->insert('order_discounts_actions')
->directValues([
'id_order_discount' => $id,
'type' => 'global_discount',
'data' => json_encode($json),
])
->execute();
if ($data['free_shipping'] == 'yes') {
sqlQueryBuilder()->insert('order_discounts_actions')
->directValues([
'type' => 'free_delivery',
'id_order_discount' => $id,
])
->execute();
}
}
protected function processTriggers($item, $data)
{
sqlQueryBuilder()->insert('order_discounts')
->directValues([
'name' => $item['post_title'],
'uses_count' => $data['usage_count'] ?? 0,
'active' => 'Y',
])
->execute();
$discountId = sqlInsertId();
sqlQueryBuilder()->insert('order_discounts_triggers')
->directValues([
'id_order_discount' => $discountId,
'type' => 'coupon',
'data' => json_encode([
'codes' => [
$item['post_title'],
],
'multiple' => 'N',
]),
])
->execute();
if (!empty($data['date_expires'])) {
try {
$dt = new \DateTime($data['date_expires']);
} catch (\Exception $exception) {
$dt = new \DateTime('@'.$data['date_expires']);
}
if ($dt > new \DateTime()) {
sqlQueryBuilder()->insert('order_discounts_triggers')
->directValues([
'id_order_discount' => $discountId,
'type' => 'datetime',
'data' => json_encode(['dateTo' => $dt->format('Y-m-d H:i:s')]),
])
->execute();
} else {
$this->toDelete[] = $discountId;
}
}
if (!empty($data['usage_limit_per_user'])) {
sqlQueryBuilder()->insert('order_discounts_triggers')
->directValues([
'id_order_discount' => $discountId,
'type' => 'user_uses_count',
'data' => json_encode(['max_uses_count' => $data['usage_limit_per_user']]),
])
->execute();
}
if (!empty($data['usage_limit'])) {
sqlQueryBuilder()->insert('order_discounts_triggers')
->directValues([
'id_order_discount' => $discountId,
'type' => 'uses_count',
'data' => json_encode(['max_uses_count' => $data['usage_limit']]),
])
->execute();
}
if (!empty($data['exclude_sale_items']) && $data['exclude_sale_items'] == 'yes') {
sqlQueryBuilder()->insert('order_discounts_triggers')
->directValues([
'id_order_discount' => $discountId,
'type' => 'product_filter',
'data' => json_encode(['filter' => ['only_not_discounted' => 'Y']]),
])
->execute();
}
return $discountId;
}
private function getProductParam($key, $productId)
{
static $cache;
if (empty($cache[$productId])) {
$data = $this->getQueryBuilder('vmeqzk_postmeta')
->select('meta_key, meta_value')
->where(Operator::equals(['post_id' => $productId]))
->orderBy('meta_id', 'DESC')
->execute();
foreach ($data as $value) {
$cache[$productId][$value['meta_key']] = $value['meta_value'];
}
}
return $cache[$productId][$key] ?? null;
}
}