Skip to content
Snippets Groups Projects
Commit aed3d4b2 authored by Andrei Vesterli's avatar Andrei Vesterli
Browse files

First release push.

parents
Branches
No related tags found
No related merge requests found
### Description
This module is a development purpose solution that is used to auto-generation of
- Products
- Product Types
- Product Variations
- Orders
with the possibility to delete all the data before generation and also to set up
the specific amount of each of the commerce entity type.
There is also the possibility to set the how old may products, product types,
product variations, orders be.
### Dependencies
- devel
- devel_generate
### Usage
There is a separated admin page for manual generation: `admin/config/development/generate/commerce`.
Second method is to use drush: `devel-generate:commerce` or alias `genc`.
These are the options that can be used to generation:
- `products_num` Specify a number of products to generate.
- `product_types_num` Specify a number of product types to generate.
- `product_variations_num` Specify a number of product variations to generate for
a certain product.
- `orders_num` Specify a number of orders to generate.
- `time_range` Specify a time framce for "created" from current time.
- `kill` Delete all entities before generation. A "true" or "false" flag.
Example command: `drush devel-generate:commerce --products_num=10`.
It will override the `products_num` to `10` (default value is `50`).
### Related modules
- https://www.drupal.org/project/devel_generate_plus
- https://www.drupal.org/project/commerce_devel
{
"name": "drupal/devel_generate_commerce",
"description": "Generate dummy commerce products, product types, product variations, orders",
"type": "drupal-module",
"homepage": "http://drupal.org/project/devel_generate_commerce",
"authors": [
{
"name": "Andrei Vesterli (andrei.vesterli)",
"email": "vesterli.andrei@gmail.com",
"homepage": "https://github.com/weitzman",
"role": "Maintainer"
}
],
"support": {
"issues": "http://drupal.org/project/devel_generate_commerce",
"source": "http://cgit.drupalcode.org/devel_generate_commerce"
},
"license": "GPL-2.0-or-later",
"minimum-stability": "dev",
"require": {
"drupal/devel": "^4.1"
},
"extra": {
"drush": {
"services": {
"drush.services.yml": "^9 || ^10"
}
}
}
}
type: module
name: 'Devel Generate Commerce'
description: 'Generate dummy commerce products, product types, product variations, orders'
package: Development
core_version_requirement: ^8.8 || ^9
php: 7.2
dependencies:
- drupal:devel
- drupal:devel_generate
tags:
- developer
administer devel_generate_commerce:
title: 'Administer devel_generate_commerce'
permission_callbacks:
- \Drupal\devel_generate\DevelGeneratePermissions::permissions
services:
develgenerate.commands:
class: Drupal\devel_generate_commerce\Commands\CommerceDevelGenerateCommand
arguments: ['@plugin.manager.develgenerate']
tags:
- { name: drush.command }
<?php
namespace Drupal\devel_generate_commerce\Commands;
use Drupal\devel_generate\Commands\DevelGenerateCommands;
/**
* Provide Drush commands for commerce devel generation.
*/
class CommerceDevelGenerateCommand extends DevelGenerateCommands {
/**
* Devel generate commerce command.
*
* @param array $options
* Array of options as described below.
*
* @command devel-generate:commerce
* @aliases genc, devel-generate-commerce
* @pluginId commerce
*
* @option products_num Specify a number of products to generate.
* @option product_types_num Specify a number of product types to generate.
* @option product_variations_num Specify a number of product variations to
* generate for a certain product.
* @option orders_num Specify a number of orders to generate.
* @option time_range Specify a time framce for "created" from current time.
* @option kill Delete all entities before generation. A "true" or "false" flag.
*/
public function commerce(
array $options = [
'kill' => FALSE,
'products_num' => 50,
'product_types_num' => 1,
'product_variations_num' => 1,
'orders_num' => 50,
'time_range' => 604800,
]
) {
// Run the generate command.
$this->generate();
}
}
<?php
namespace Drupal\devel_generate_commerce\Plugin\DevelGenerate;
use Drupal\commerce_order\Adjustment;
use Drupal\commerce_price\Price;
use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\devel_generate\DevelGenerateBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a CommerceDevelGenerate plugin.
*
* @DevelGenerate(
* id = "commerce",
* label = @Translation("commerce"),
* description = @Translation("Generate a given number of products, product types, product variations, orders."),
* url = "commerce",
* permission = "administer devel_generate_commerce",
* settings = {
* "kill" = FALSE,
* "products_num" = 50,
* "product_types_num" = 1,
* "product_variations_num" = 1,
* "orders_num" = 50,
* "time_range" = 604800
* }
* )
*/
class CommerceDevelGenerate extends DevelGenerateBase implements ContainerFactoryPluginInterface {
/**
* The user storage.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The date formatter service.
*
* @var \Drupal\Core\Datetime\DateFormatterInterface
*/
protected $dateFormatter;
/**
* Provides system time.
*
* @var \Drupal\Core\Datetime\TimeInterface
*/
protected $time;
/**
* Constructs a new UserDevelGenerate object.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The user storage.
* @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
* The date formatter service.
* @param \Drupal\Core\Datetime\TimeInterface $time
* Provides system time.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, DateFormatterInterface $date_formatter, TimeInterface $time) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->entityTypeManager = $entity_type_manager;
$this->dateFormatter = $date_formatter;
$this->time = $time;
// Load the default store.
$this->store = $this
->entityTypeManager
->getStorage('commerce_store')
->loadDefault();
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration, $plugin_id, $plugin_definition,
$container->get('entity_type.manager'),
$container->get('date.formatter'),
$container->get('datetime.time')
);
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$form['products_num'] = [
'#type' => 'number',
'#title' => $this->t('Products'),
'#description' => $this->t('How many products would you like to generate?'),
'#default_value' => $this->getSetting('products_num'),
'#required' => TRUE,
'#min' => 0,
'#max' => 100,
];
$form['product_types_num'] = [
'#type' => 'number',
'#title' => $this->t('Product types'),
'#description' => $this->t('How many product types would you like to generate?'),
'#default_value' => $this->getSetting('product_types_num'),
'#required' => TRUE,
'#min' => 0,
'#max' => 100,
];
$form['product_variations_num'] = [
'#type' => 'number',
'#title' => $this->t('Product variations'),
'#description' => $this->t('How many product variations would you like to generate for a certain product?'),
'#default_value' => $this->getSetting('product_variations_num'),
'#required' => TRUE,
'#min' => 0,
'#max' => 10,
];
$form['orders_num'] = [
'#type' => 'number',
'#title' => $this->t('Orders'),
'#description' => $this->t('How many orders would you like to generate?'),
'#default_value' => $this->getSetting('orders_num'),
'#required' => TRUE,
'#min' => 0,
'#max' => 100,
];
$form['kill'] = [
'#type' => 'checkbox',
'#title' => $this->t('Delete all?'),
'#description' => $this->t('Delete all the generated products, product types, product variations, orders before generating new.'),
'#default_value' => $this->getSetting('kill'),
];
$options = [1 => $this->t('Now')];
foreach ([3600, 86400, 604800, 2592000, 31536000] as $interval) {
$options[$interval] = $this->dateFormatter->formatInterval($interval, 1) . ' ' . $this->t('ago');
}
$form['time_range'] = [
'#type' => 'select',
'#title' => $this->t('How old may products, product types, product variations, orders be?'),
'#description' => $this->t('Created date will be distributed randomly from the current time, back to the selected time.'),
'#options' => $options,
'#default_value' => $this->getSetting('time_range'),
];
return $form;
}
/**
* {@inheritdoc}
*/
protected function generateElements(array $values) {
// Collect the submited form config values.
$kill = $values['kill'];
$products_num = $values['products_num'];
$product_types_num = $values['product_types_num'];
$product_variations_num = $values['product_variations_num'];
$orders_num = $values['orders_num'];
$time_range = $values['time_range'];
// Remove all the products, product types, product variations, orders.
if ($kill) {
$this->geleteAllEntities();
}
// Generate product types.
if ($product_types_num > 0) {
$this->generateProductTypes($product_types_num);
}
// Generate products.
if ($products_num > 0) {
$this->generateProducts($products_num, $product_variations_num, $time_range);
}
// Generate orders.
if ($orders_num > 0) {
$this->generateOrders($orders_num, $time_range);
}
}
/**
* Delete all the generated commerce entities.
*/
protected function geleteAllEntities() {
$kill_config = [
'commerce_product' => [
'singular' => 'product',
'plural' => 'products',
],
'commerce_product_type' => [
'singular' => 'product type',
'plural' => 'products types',
],
'commerce_product_variation' => [
'singular' => 'product variation',
'plural' => 'products variations',
],
'commerce_product_variation_type' => [
'singular' => 'product variation type',
'plural' => 'products variation types',
],
'commerce_order' => [
'singular' => 'order',
'plural' => 'orders',
],
];
foreach ($kill_config as $entity_name => $config) {
// Load and delete all entities.
$entities = $this
->entityTypeManager
->getStorage($entity_name)
->loadMultiple();
if ($entities) {
$this->entityTypeManager->getStorage($entity_name)->delete($entities);
// Display a message after deletion.
$this->setMessage(
$this->formatPlural(
count($entities),
'1 ' . $config['singular'] . ' deleted',
'@count ' . $config['plural'] . ' deleted.'
)
);
}
else {
$this->setMessage('0 ' . $config['plural'] . ' deleted.');
}
}
}
/**
* Generate orders by the given amount.
*
* @param int $orders_num
* The number of orders to generate.
* @param int $time_range
* The time range to set for the order "created".
*/
protected function generateOrders(int $orders_num, int $time_range) {
// Load and delete all entities.
$variations = $this
->entityTypeManager
->getStorage('commerce_product_variation')
->loadMultiple();
if (!$variations) {
return $this->setMessage('There are no available product variations in oder to generate an order.');
}
$generated_orders = 0;
while ($orders_num > 0) {
// Get a random variation ID and then attach it to the order item.
$variation_id = array_rand($variations, 1);
// Prepare and save an order item before the actual order saving.
$order_item = $this
->entityTypeManager
->getStorage('commerce_order_item')
->createFromPurchasableEntity($variations[$variation_id]);
// Save the order item.
$order_item->save();
// Order data preparation for saving.
$order = $this->entityTypeManager
->getStorage('commerce_order')->create([
'type' => 'default',
'mail' => $this->store->getEmail(),
'store_id' => $this->store->id(),
'order_items' => [$order_item],
'state' => 'completed',
'placed' => $this->time->getRequestTime() - mt_rand(0, $time_range),
]);
// Add a dummy order adjustment.
$order->addAdjustment(new Adjustment([
'type' => 'tax',
'label' => $this->t('Tax'),
'amount' => new Price(mt_rand(0, 100), $this->store->getDefaultCurrencyCode()),
'included' => TRUE,
]));
// Re-calculate the total price.
$order->recalculateTotalPrice();
$order->save();
// Decrease the orders number.
$orders_num--;
// Increase the number of the generated orders.
$generated_orders++;
}
// Display a system message after products insertion.
$this->setMessage(
$this->t(
'@orders_num created.',
['@orders_num' => $this->formatPlural($generated_orders, '1 order', '@count orders')]
)
);
}
/**
* Generate products by the given amount.
*
* @param int $products_num
* The number of products to generate.
* @param int $product_variations_num
* The number of variations for add for a certain product.
* @param int $time_range
* The time range to set for the product "created".
*/
protected function generateProducts(int $products_num, int $product_variations_num, int $time_range) {
// Load all the available product types.
$product_types = $this
->entityTypeManager
->getStorage('commerce_product_type')
->loadMultiple();
if (!$product_types) {
return $this->setMessage('There are no available product types. Can not generate products.');
}
// Allow a product generation only when there is at least 1 product type.
if (!empty($product_types)) {
$product_types = array_keys($product_types);
$generated_products = 0;
while ($products_num > 0) {
// Set a random product title.
$title = $this->getRandom()->word(mt_rand(6, 20));
// Get a random product type (if there are more than 1).
$product_type = $product_types[array_rand($product_types, 1)];
// Generate the product variations (if any).
$variations = $this->generateProductVariations($product_type, $product_variations_num);
// Prepare the product.
$product = $this->entityTypeManager
->getStorage('commerce_product')->create([
'uid' => 1,
'type' => $product_type,
'title' => $title,
'status' => TRUE,
'stores' => [$this->store],
'variations' => $variations,
'created' => $this->time->getRequestTime() - mt_rand(0, $time_range),
]);
// Populate all fields with sample values.
$this->populateFields($product);
$product->save();
// Decrease the products number.
$products_num--;
// Increase the number of the generated products.
$generated_products++;
}
// Display a system message after products insertion.
$this->setMessage(
$this->t(
'@products_num created.',
['@products_num' => $this->formatPlural($generated_products, '1 product', '@count products')]
)
);
}
}
/**
* Generate the product types by the given amount.
*
* @param int $product_types_num
* The number of product types to generate.
*/
protected function generateProductTypes(int $product_types_num) {
$generated_product_types = 0;
while ($product_types_num > 0) {
// Set a random product type id, label, variation type.
$type = $this->getRandom()->word(mt_rand(6, 20));
$product_type = $this
->entityTypeManager
->getStorage('commerce_product_type')->create([
'id' => $type,
'label' => $type,
'variationType' => $type,
'multipleVariations' => TRUE,
'injectVariationFields' => TRUE,
]);
// Populate all fields with sample values.
$this->populateFields($product_type);
$product_type->save();
// Once we have the product type we need to create the variation type.
$this->entityTypeManager->getStorage('commerce_product_variation_type')->create([
'id' => $type,
'label' => $type,
'status' => TRUE,
'orderItemType' => 'default',
'generateTitle' => TRUE,
'trait' => ['purchasable_entity_shippable'],
])->save();
// Decrease the product types number.
$product_types_num--;
// Increase the number of the generated products.
$generated_product_types++;
}
// Display a system message after product types insertion.
$this->setMessage(
$this->t(
'@product_types_num created.',
['@product_types_num' => $this->formatPlural($generated_product_types, '1 product type', '@count product types')]
)
);
}
/**
* Generate product variations per product type (by the given amount).
*
* @param string $product_type
* The product type to generate variations for.
* @param int $count
* The number of variations to generate.
*
* @return array
* The list of generated variations for the given product type.
*/
protected function generateProductVariations(string $product_type, int $count) {
$variations = [];
// Preprocess product variations import.
while ($count > 0) {
// Set a random price for each variation in part.
$product_price = mt_rand(1, 1000);
// Let's get the currency from the default store.
$price = new Price($product_price, $this->store->getDefaultCurrencyCode());
// Set a random product variation name.
$name = $this->getRandom()->word(mt_rand(6, 20));
$product_variation = $this
->entityTypeManager
->getStorage('commerce_product_variation')->create([
'type' => $product_type,
'sku' => $product_type,
'status' => TRUE,
'title' => $name,
'price' => $price,
// Set unlimited stock.
'commerce_stock_always_in_stock' => TRUE,
]);
// Populate all fields with sample values.
$this->populateFields($product_variation);
$product_variation->save();
$variations[] = $product_variation;
// Decrease the product variations number.
$count--;
}
return $variations;
}
/**
* {@inheritdoc}
*/
public function validateDrushParams(array $args, array $options = []) {
// Prepare the sent values from terminal.
$values = [
'kill' => $options['kill'],
'products_num' => $options['products_num'],
'product_types_num' => $options['product_types_num'],
'product_variations_num' => $options['product_variations_num'],
'orders_num' => $options['orders_num'],
'time_range' => $options['time_range'],
];
return $values;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment