Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
Страницы 1
Хочу прописать дату окончания триального периода подписки по умолчанию.
Где это лучше сделать?
В конфиг дату прописать не получается.
'subscription' => [
'trialEndsAt' => \Carbon::today()->addDays(1),
]
Не работает.
В класс Subscription прописать константу или статическую переменную имеющую значение Carbon::today()->addDays(1) не получается.
Как вообще принято даты по умолчанию прописывать?
Нет конечно можно прописать период по умолчанию через durationUnit и duration, но это две переменные и вообще хочется иметь все таки именно дату по умолчанию.
Как быть???
Не в сети
Не в сети
Спасибо так и сделаю.
А если я хочу из формы принимать дату. То преобразовать ее из того что прислала форма ну например html 5 поле с датой или js календарь итд в Carbon дату где лучше? Мне кажется модель не должна знать что там за дата в форм, значки в контроллере или в реквесте быть может?
Как красивее? В реквесте по любому дату ведь проверять
Не в сети
Мне кажется модель не должна знать что там за дата в форм
Почему нет? Я не задумывался об этом особо, но мне кажется, что это можно делать в модели, в контроллере/сервисе/трансформере, в преобразователе модели (mutator) и т.д.
Не в сети
Почему модель не должна знать?
Допустим есть метод
class ExampleModel
{
function create($request)
{
$request['trial_end'] = fromSomeFormatDate($request['trial_end']);
}
И вот этот fromSomeFormatDate() зависит от того, что мы сделали в форме и интерфейсе? Кажется совсем не красиво. Тк в форме то мы захотим в таком формате у юзера брать дату, а затем заказчик скажет некрасиво давайте в чуть другом, а мы уже модель меняем. А в метод create модели данные могут и не только из данной формы поступать...
Про сервис понятно, но допустим его не приминяем... А как в мутаторе? Можешь пример привести?
Изменено htclog81 (03.12.2017 12:11:41)
Не в сети
- как в мутаторе? Можешь пример привести?
public function setTrialEndsAtAttribute($value)
{
$this->attributes['trial_ends_at'] = Carbon::now()->addHours(config('subscription.trial_ends_in_hours'));
}
public function setSomeDateAttribute($value)
{
$this->attributes['some_date'] = Carbon::parse($value);
}
Если логика простая, как в последнем примере, то можно просто сделать так:
protected $dates = [
'created_at',
'updated_at',
'some_date'
];
Не в сети
Нет, посмотрел свой код мутатор мне не подходит, так как мне нужно менять формат даты не в момент создания объекта именно...
Мне нужно следующее:
1) Принять дату из формы или из конфига
2) Заслать через API дату. Причем там есть варианты и более чистый что ли это через TrialDuration и TrialDurationUnit, а не просто DateTime
3) Использовать дату при создании объекта Subscription
Очевидно что мутатор по крайней мере задачу 2 не решает. Можно конечно написать Хелпер который переводит дату из TimeStamp в TrialDuration и TrialDurationUnit. А перед этим то что в форме перевести в Timestamp
Не в сети
Сделал это таким образом
Конфиг
'subscription' => [
'trial_ends_in_days' => 4,
]
Контроллер в случае если мы эту дату берем из конфига, а не из формы. Те если платит юзер, а не админ, то ему дату не выбирать.
$user-> createSubscription(array_merge(
$request->all(), [
"trial_ends_at" => config('services.subscription.trial_ends_in_days') ? Carbon::today()->addDays(config('services.subscription.trial_ends_in_days')) : null,
]
));
Модель. Трейт юзера, где мы создаем для юзера подписку. От разных форматов даты удалось избавиться, тк я понял что через API можно и просто timestamp передать, узнал у саппорта.
public function createSubscription($request)
{
if (isset($request['payment_method_nonce'])) {
if ($this->gateway_id) {
throw new \LogicException('When user have payment method add subscription only with this method');
} else {
$this->createGatewayCustomerWithPaymentMethod($request['payment_method_nonce']);
}
} else {
if (!$this->gateway_id) {
throw new \LogicException('When user have not payment method add subscription only with add payment data');
}
}
$plan = Plan::findOrFail($request['plan_id']);
if (empty($request['trial_ends_at'])) {
$response = GatewaySubscription::create([
'planId' => $plan->gateway_id,
'paymentMethodToken' => $this->defaultCard->gateway_id,
'options' => ['startImmediately' => true]
]);
} else {
$response = GatewaySubscription::create([
'planId' => $plan->gateway_id,
'paymentMethodToken' => $this->defaultCard->gateway_id,
'firstBillingDate' => $request['trial_ends_at'],
]);
}
if (! $response->success) {
throw new Exception('Gateway failed to create subscription: '.$response->message);
}
return $this->subscriptions()->create([
'gateway_id' => $response->subscription->id,
'card_id' => $this->defaultCard->id,
'current_period_end' => $response->subscription->billingPeriodEndDate,
'plan_id' => $plan->id,
'trial_ends_at' => $request['trial_ends_at'],
]);
}
Ну а в случае с админом, я просто через js календарик в нужном формате дату запрашиваю и ничего так же преобразовывать не приходиться. Все что нужно в Request
public function createSubscriptionByAdmin($request)
{
$plan = Plan::findOrFail($request['plan_id']);
if ($this->hasCard()) {
if (empty($request['trial_ends_at'])) {
$response = GatewaySubscription::create([
'planId' => $plan->gateway_id,
'paymentMethodToken' => $this->defaultCard->gateway_id,
'options' => ['startImmediately' => true]
]);
} else {
$response = GatewaySubscription::create([
'planId' => $plan->gateway_id,
'paymentMethodToken' => $this->defaultCard->gateway_id,
'firstBillingDate' => $request['trial_ends_at'],
]);
}
if (!$response->success) {
throw new Exception('Gateway failed to create subscription: '.$response->message);
}
return $this->subscriptions()->create([
'gateway_id' => $response->subscription->id,
'card_id' => $this->defaultCard->id,
'current_period_end' => $response->subscription->billingPeriodEndDate,
'plan_id' => $plan->id,
'trial_ends_at' => $request['trial_ends_at'],
]);
} else {
return $this->subscriptions()->create([
'plan_id' => $plan->id,
'trial_ends_at' => $request['trial_ends_at'],
]);
}
}
До сегодняшних изменений все это в двух сервисных классах SubscriptionBuilder и GenericSubscriptionBuilder было которыя у cashier пакета подсмотрел. Кода меньше стало. Но осталось эти две метода createSubscription() и createSubscriptionByAdmin() зарефакторить на предмет повторного кода и меньше условий. Благодаря тому что с датой разобрался все куда лучше стало.
Изменено htclog81 (03.12.2017 22:28:23)
Не в сети
Страницы 1