Я посмотрел на Google для некоторых образцов / решений по этому поводу, например Создание системы скидок (MySQL / php) но я не нашел хорошего решения.
Моя ситуация такова, что у меня есть платформа, где пользователь должен иметь баланс в виртуальной валюте и может покупать виртуальные предметы для нее. Теперь хочется реализовать ваучеры и скидки. Были бы различные виды кодов, например, такой, который дает 50% скидку на покупку товаров, х количество дополнительных товаров (с минимальной суммой товара или без нее), просто код для получения некоторой валюты или ссылочный код, который дает рефералу что-то ,
Я реализовал его как Campaign и CampaignType, где первый содержит информацию о кампании, а второй — информацию о действии.
Вот структура:
-- Table structure for table `cake_campaigns`
CREATE TABLE IF NOT EXISTS `cake_campaigns` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(50) CHARACTER SET utf8 NOT NULL,
`code` varchar(100) COLLATE utf8_bin NOT NULL,
`type_id` varchar(50) CHARACTER SET utf16 COLLATE utf16_bin NOT NULL DEFAULT '1',
`value` int(10) unsigned NOT NULL DEFAULT '5' COMMENT 'Percentage or amount',
`min_amount` bigint(20) unsigned NOT NULL DEFAULT '0',
`owner_id` bigint(20) unsigned NOT NULL,
`created` datetime NOT NULL,
`active` tinyint(1) unsigned NOT NULL DEFAULT '1',
`single_use` tinyint(1) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `code` (`code`),
KEY `owner_id` (`owner_id`),
FULLTEXT KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=4 ;
-- Table structure for table `cake_campaign_types`
CREATE TABLE IF NOT EXISTS `cake_campaign_types` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) CHARACTER SET utf8 NOT NULL,
`unit` varchar(10) CHARACTER SET utf16 NOT NULL DEFAULT '%',
`multiplier` double(10,8) NOT NULL DEFAULT '0.01000000',
`type` varchar(50) COLLATE utf8_bin DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=7 ;
В настоящее время моя логика заключается в том, что при использовании кампании действие соответствует имени CampaignType, например, в логике покупки:
if (isset($this->request->data['Purchase']['code'])) {
$code = $this->request->data['Purchase']['code'];
$campaign = $this->Campaign->findByCode($code);
$this->Campaign->id = $campaign['Campaign']['id'];
// campaign no longer active
if ($this->Campaign->field('active') == 0) $code = false;
if ($this->CampaignLog->find('first', array('conditions' => array(
'user_id' => $this->User->field('id'),
'campaign_id' => $this->Campaign->field('id'),
'activated' => 1,
)))) $code = false; // code has already been used
unset($this->request->data['Purchase']['code']);
} else $code = false;
// Some purchasing logic here
if ($code) {
$this->CampaignLog->create();
$this->CampaignLog->save(array(
'campaign_id' => $this->Campaign->field('id'),
'user_id' => $this->User->field('id'),
'activated' => 1,
'source' => $this->Session->read('referrer'),
'earnings' => $earned,
'created' => strftime('%Y-%m-%d %H:%M:%S'),
));
if ($this->Campaign->field('single_use') == 1) {
$this->Campaign->saveField("active", 0);
}
// Apply code here
}
Теперь мой вопрос:
Что было бы наилучшим вариантом при применении этих кодов, потому что мне немного не по себе при работе с if-then-else или switch-case через все возможные типы кода. Но сейчас, так как есть много вещей, которые могут отличаться (например, скидка — в процентах или установленной сумме), тогда это, кажется, единственный вариант.
Может быть, структура / логика кодов должна быть другой?
С моей точки зрения, это уже просто, поэтому лучше всего интегрировать его с покупкой в понимание дальнейших проблем. Предполагая, что у нас есть $this->request->data['price']
по цене, тогда у нас есть пример type_id
из 1
что представляет собой скидку.
Все, что нам нужно сделать, это получить value
и сделать процентное уравнение, так что было бы как
$discount = floatval('0.' . $this->Campaign->value);
$finalPrice = $this->request->data['price'] * $discount;
Лучше, если мы реализуем это на switch
дело изолировать их логику. Это может зависеть от того, как вы реализуете это, но это суть концепции.
Проверить плагин корзины это используя события для всего и ничего не закодировано, это довольно гибкий с использованием этого подхода.
Есть один метод Это срабатывает всякий раз, когда необходимо пересчитать корзину. Внутри он вызывает другие методы для расчета налогов и скидки.
Реализация этого через события имеет то преимущество, что его очень легко расширить с помощью дополнительных скидок или налоговых расчетов позже.
Не стесняйтесь просматривать весь код плагина, это не простая реализация, она охватывает cookie, сеансы и хранилище базы данных для данных корзины и содержит события для многих вещей.