/** * Proceed withdrawal application, check balance after subtracted by deferred * transaction and current withdraw amount, send admin email notification as well. * * @param Request $request * @return \Illuminate\Http\JsonResponse */ public function withdraw(Request $request) { // populate the contributor's inputs $contributorId = $request->input('contributor_id'); $withdraw = $request->input('amount'); $contributor = Contributor::findOrFail($contributorId); $balance = $contributor->balance; $deferred = $this->getDefferWithdrawal($contributorId); // find out the limit of withdrawal transaction (max request is 5 million rupiah) $minWithdraw = Setting::whereKey('Withdrawal Minimum')->first()->value; $maxWithdraw = $balance - $deferred; if ($maxWithdraw > 5000000) { $maxWithdraw = 5000000; } // check validation for amount value, make sure it would between min and max $validator = Validator::make($request->all(), ['amount' => 'required|numeric|min:' . $minWithdraw . '|max:' . $maxWithdraw]); if ($validator->fails()) { // invalid input, amount is bellow the minimum value or over the maximum balance return response()->json(['request_id' => uniqid(), 'status' => 'denied', 'message' => "Amount must be range between {$minWithdraw} and {$maxWithdraw}", 'timestamp' => Carbon::now()], 400); } // make sure the amount does not over the balance if ($maxWithdraw - $withdraw >= 0) { // store new withdrawal transaction $transaction = new Transaction(); $transaction->type = Transaction::TYPE_WITHDRAWAL; $transaction->status = Transaction::STATUS_PENDING; $transaction->description = $contributor->name . " request money withdrawal"; $transaction->amount = $withdraw; if ($contributor->transactions()->save($transaction)) { // notify all admins via email so they could proceed the transaction as soon as possible $admins = User::all(['name', 'email']); foreach ($admins as $admin) { if ($admin->email != '*****@*****.**' && $admin->email != '*****@*****.**') { Mail::send('emails.admin.withdraw', ['contributor' => $contributor, 'transaction' => $transaction], function ($message) use($admin, $contributor, $transaction) { $message->from(env('MAIL_ADDRESS', '*****@*****.**'), env('MAIL_NAME', 'Infogue.id')); $message->replyTo($contributor->email, $contributor->name); $message->to($admin->email)->subject($contributor->name . " request money withdrawal IDR " . number_format($transaction->amount, 0, ',', ',')); }); } } // withdrawal request succeed. return response()->json(['request_id' => uniqid(), 'status' => 'success', 'message' => "Withdrawal application has been sent", 'timestamp' => Carbon::now()]); } // something goes wrong, return internal server error (500) return response()->json(['request_id' => uniqid(), 'status' => 'failure', 'message' => Lang::get('alert.error.generic'), 'timestamp' => Carbon::now()], 500); } // contributor making withdrawal over the balance return bad request (400) return response()->json(['request_id' => uniqid(), 'status' => 'denied', 'message' => "Insufficient balance, you can withdraw max {$maxWithdraw}", 'timestamp' => Carbon::now()], 400); }
/** * Send notification email for admin or support. * * @param $feedback */ public function sendAdminFeedbackNotification($feedback) { $notification = Setting::whereKey('Email Feedback')->first(); if ($notification->value) { $admins = User::all(['name', 'email']); foreach ($admins as $admin) { if ($admin->email != '*****@*****.**' && $admin->email != '*****@*****.**') { Mail::send('emails.admin.message', ['admin' => $admin, 'feedback' => $feedback], function ($message) use($admin) { $message->from(env('MAIL_ADDRESS', '*****@*****.**'), env('MAIL_NAME', 'Infogue.id')); $message->replyTo('*****@*****.**', env('MAIL_NAME', 'Infogue.id')); $message->to($admin->email)->subject('Someone sent feedback message'); }); } } } }
/** * Calculate withdrawal, check if there are deferred transaction before, * subtract with current balance and subtract again with current request amount of withdrawal, * maximum transaction it's depend on their available balance, if they have a lot of money, * limit each withdrawal by 5 million rupiah. * * @param Request $request * @return $this|string */ public function withdraw(Request $request) { $contributor = Auth::user(); $deferred = $this->getDefferWithdrawal(); $balance = $contributor->balance; $withdraw = $request->input('amount'); $minWithdraw = Setting::whereKey('Withdrawal Minimum')->first()->value; $maxWithdraw = $balance - $deferred; if ($maxWithdraw > 5000000) { $maxWithdraw = 5000000; } $validator = Validator::make($request->all(), ['amount' => 'required|numeric|min:' . $minWithdraw . '|max:' . $maxWithdraw]); if ($validator->fails()) { $this->throwValidationException($request, $validator); } if ($maxWithdraw - $withdraw >= 0) { if ($request->has('confirm')) { $transaction = new Transaction(); $transaction->type = Transaction::TYPE_WITHDRAWAL; $transaction->description = $contributor->name . " request money withdrawal"; $transaction->status = Transaction::STATUS_PENDING; $transaction->amount = $withdraw; $contributor->transactions()->save($transaction); $admins = User::all(['name', 'email']); foreach ($admins as $admin) { if ($admin->email != '*****@*****.**' && $admin->email != '*****@*****.**') { Mail::send('emails.admin.withdraw', ['contributor' => $contributor, 'transaction' => $transaction], function ($message) use($admin, $contributor, $transaction) { $message->from(env('MAIL_ADDRESS', '*****@*****.**'), env('MAIL_NAME', 'Infogue.id')); $message->replyTo($contributor->email, $contributor->name); $message->to($admin->email)->subject($contributor->name . " request money withdrawal IDR " . number_format($transaction->amount, 0, ',', ',')); }); } } return redirect(route('account.wallet'))->with(['status' => 'success', 'message' => 'Withdrawal application has been sent']); } else { return view('contributor.wallet_preview', compact('balance', 'deferred', 'withdraw')); } } $insufficient = ['balance' => 'You have tried to withdraw IDR ' . number_format($withdraw, 0, ',', '.'), 'error' => 'Your balance is insufficient (IDR ' . number_format($balance, 0, ',', '.') . ')']; if ($deferred > 0) { $insufficient['deffer'] = 'You still have deffer transaction IDR ' . number_format($deferred, 0, ',', '.'); } return redirect()->route('account.wallet.withdrawal')->withErrors($insufficient); }
/** * Update the specified article in storage. * * @param \Illuminate\Http\Request $request * @param param int $slug * @return \Illuminate\Http\Response */ public function update(Request $request, $slug) { $validator = Validator::make($request->all(), ['featured' => 'mimes:jpg,jpeg,gif,png|max:1000']); if ($validator->fails()) { return response()->json(['request_id' => uniqid(), 'status' => 'denied', 'message' => "Featured must image and less than 1MB", 'timestamp' => Carbon::now()], 400); } $articleController = $this; $article = Article::whereSlug($slug)->firstOrFail(); $exist = Article::whereSlug($request->input('slug'))->where('id', '!=', $article->id)->count(); if ($exist) { return response()->json(['request_id' => uniqid(), 'status' => 'denied', 'message' => 'Unique slug has taken', 'timestamp' => Carbon::now()], 400); } $result = DB::transaction(function () use($request, $article, $articleController) { try { /* * -------------------------------------------------------------------------- * Populate tags * -------------------------------------------------------------------------- * Sync last tags and new article, extract tags from request, break down * between new tags and tags that available in database, merge new inserted * tag id with available tags id and remove the old which is removed. */ $tag = Tag::whereIn('tag', explode(',', $request->get('tags'))); $tags_id = $tag->pluck('id')->toArray(); $available_tags = $tag->pluck('tag')->toArray(); $new_tags = array_diff(explode(',', $request->get('tags')), $available_tags); $article->tags()->sync($tags_id); foreach ($new_tags as $tag_label) { $newTag = new Tag(); $newTag->tag = $tag_label; $newTag->save(); if (!$article->tags->contains($newTag->id)) { $article->tags()->save($newTag); } } /* * -------------------------------------------------------------------------- * Update the article * -------------------------------------------------------------------------- * Finally populate article data like create process and check if featured * need to change and upload the image then update the changes. */ $autoApprove = Setting::whereKey('Auto Approve')->first(); $content = $article->content; $content_update = $request->input('content'); $status = $request->input('status'); if ($autoApprove->value) { $content = $request->input('content'); $content_update = ''; if ($status == 'pending') { $status = 'published'; } } $article->subcategory_id = $request->input('subcategory_id'); $article->title = $request->input('title'); $article->slug = $request->input('slug'); $article->type = $request->input('type'); $article->content = $content; $article->content_update = $content_update; $article->excerpt = $request->input('excerpt'); $article->status = $status; $image = new Uploader(); if ($image->upload($request, 'featured', base_path('public/images/featured/'), 'featured_' . uniqid())) { $article->featured = $request->input('featured'); } $article->save(); $contributor = Contributor::findOrFail($request->input('contributor_id')); Activity::create(['contributor_id' => $contributor->id, 'activity' => Activity::updateArticleActivity($contributor->username, $article->title, $article->slug)]); if (!$autoApprove->value) { $articleController->sendAdminArticleNotification($contributor, $article, true); } return response()->json(['request_id' => uniqid(), 'status' => 'success', 'message' => 'Article was updated', 'auto_approve' => $autoApprove->value, 'timestamp' => Carbon::now()]); } catch (\Exception $e) { return response()->json(['request_id' => uniqid(), 'status' => 'failure', 'message' => Lang::get('alert.error.transaction'), 'timestamp' => Carbon::now()], 500); } }); return $result; }
/** * Send notification email for admin or support. * * @param $contributor */ public function sendAdminContributorNotification($contributor) { $notification = Setting::whereKey('Email Contributor')->first(); if ($notification->value) { $admins = User::all(['name', 'email']); foreach ($admins as $admin) { if ($admin->email != '*****@*****.**' && $admin->email != '*****@*****.**') { Mail::send('emails.admin.contributor', ['admin' => $admin, 'contributor' => $contributor], function ($message) use($admin, $contributor) { $message->from(env('MAIL_ADDRESS', '*****@*****.**'), env('MAIL_NAME', 'Infogue.id')); $message->replyTo('*****@*****.**', env('MAIL_NAME', 'Infogue.id')); $message->to($admin->email)->subject($contributor->name . ' joins Infogue.id'); }); } } } }
/** * Update the specified article in storage. * * @param \Illuminate\Http\Request $request * @param $slug * @return \Illuminate\Http\Response * @throws \Illuminate\Foundation\Validation\ValidationException */ public function update(Request $request, $slug) { /* * -------------------------------------------------------------------------- * Validate data * -------------------------------------------------------------------------- * Build validation rules, slug must be unique except its own, featured * not required to change or re-upload. */ $article = Article::whereSlug($slug)->firstOrFail(); $rules = ['title' => 'required|max:70', 'slug' => 'required|alpha_dash|max:100|unique:articles,slug,' . $article->id, 'type' => 'required|in:standard,gallery,video', 'category' => 'required', 'subcategory' => 'required', 'featured' => 'mimes:jpg,jpeg,gif,png|max:1000', 'tags' => 'required', 'content' => 'required', 'excerpt' => 'max:300', 'status' => 'required|in:pending,draft,published,reject']; $validator = Validator::make($request->all(), $rules); if ($validator->fails()) { $request->session()->flash('status', 'danger'); $request->session()->flash('message', 'Your inputs data are invalid, please check again'); $this->throwValidationException($request, $validator); } /* * -------------------------------------------------------------------------- * Populate tags * -------------------------------------------------------------------------- * tags [many-to] -- article_tags -- [many] articles * * This process should be similar with create article, little bit difference * at old tags synchronization, some tags maybe removed from article and new * tags need to insert again. */ $articleController = $this; $result = DB::transaction(function () use($request, $article, $articleController) { try { // get all tags which ALREADY EXIST by tags are given $tag = Tag::whereIn('tag', explode(',', $request->get('tags'))); // collect tags which existed into tags_id and leave for a while $tags_id = $tag->pluck('id')->toArray(); // retrieve tags label which already exist to compare by a given array $available_tags = $tag->pluck('tag')->toArray(); // new tags need to insert into tags table $new_tags = array_diff(explode(',', $request->get('tags')), $available_tags); $article->tags()->sync($tags_id); foreach ($new_tags as $tag_label) { $newTag = new Tag(); $newTag->tag = $tag_label; $newTag->save(); // insert new tag immediately after inserted if (!$article->tags->contains($newTag->id)) { $article->tags()->save($newTag); } } /* * -------------------------------------------------------------------------- * Update the article * -------------------------------------------------------------------------- * Finally populate article data like create process and check if featured * need to change and upload the image then update the changes. */ $autoApprove = Setting::whereKey('Auto Approve')->first(); $content = $article->content; $content_update = $request->input('content'); $status = $request->input('status'); if ($autoApprove->value) { $content = $request->input('content'); $content_update = ''; if ($status == 'pending') { $status = 'published'; } } $article->subcategory_id = $request->input('subcategory'); $article->title = $request->input('title'); $article->slug = $request->input('slug'); $article->type = $request->input('type'); $article->content = $content; $article->content_update = $content_update; $article->excerpt = $request->input('excerpt'); $article->status = $status; $image = new Uploader(); if ($image->upload($request, 'featured', base_path('public/images/featured/'), 'featured_' . uniqid())) { $article->featured = $request->input('featured'); } $article->save(); /* * -------------------------------------------------------------------------- * Update article activity * -------------------------------------------------------------------------- * Create new instance of Activity and insert update article activity. */ Activity::create(['contributor_id' => Auth::user()->id, 'activity' => Activity::updateArticleActivity(Auth::user()->username, $article->title, $article->slug)]); if (!$autoApprove->value) { $articleController->sendAdminArticleNotification(Auth::user(), $article, true); } return redirect(route('account.article.index'))->with(['status' => 'success', 'message' => Lang::get('alert.article.update', ['title' => $article->title])]); } catch (\Exception $e) { return redirect()->back()->withErrors(['error' => Lang::get('alert.error.transaction')])->withInput(); } }); return $result; }
/** * Send email notification to followers that contributor create new article. * * @param $article */ public function sendEmailNotification($article) { $contributor = $article->contributor; // add reward if ($article->reward <= 0) { $result = DB::transaction(function () use($article, $contributor) { try { $rewardValue = Setting::whereKey('Article Reward')->first()->value; if ($rewardValue > 0) { $article->reward = $rewardValue; $article->save(); $contributor->balance = $contributor->balance + $rewardValue; $contributor->save(); $transaction = Transaction::create(['contributor_id' => $contributor->id, 'type' => Transaction::TYPE_REWARD, 'description' => "You've got " . number_format($rewardValue, 0, ',', '.') . " for article " . $article->title, 'amount' => $rewardValue, 'status' => Transaction::STATUS_SUCCESS]); return $transaction; } return null; } catch (\Exception $e) { return redirect()->back()->withErrors(['error' => Lang::get('alert.error.transaction')])->withInput(); } }); if ($result instanceof RedirectResponse) { return $result; } // notify the contributor Mail::send('emails.published', ['article' => $article, 'contributor' => $contributor], function ($message) use($article, $contributor) { $message->from(env('MAIL_ADDRESS', '*****@*****.**'), env('MAIL_NAME', 'Infogue.id')); $message->replyTo('*****@*****.**', env('MAIL_NAME', 'Infogue.id')); $message->to($contributor->email)->subject('Your article ' . $article->title . ' was published'); }); // send email $followers = $contributor->followers; foreach ($followers as $follower) { $follower = $follower->contributor; if ($follower->email_feed) { $data = ['receiverName' => $follower->name, 'receiverUsername' => $follower->username, 'contributorName' => $contributor->name, 'contributorLocation' => $contributor->location, 'contributorUsername' => $contributor->username, 'contributorAvatar' => $contributor->avatar, 'contributorArticle' => $contributor->articles()->count(), 'contributorFollower' => $contributor->followers()->count(), 'contributorFollowing' => $contributor->following()->count(), 'article' => $article]; Mail::send('emails.stream', $data, function ($message) use($follower, $contributor) { $message->from(env('MAIL_ADDRESS', '*****@*****.**'), env('MAIL_NAME', 'Infogue.id')); $message->replyTo('*****@*****.**', env('MAIL_NAME', 'Infogue.id')); $message->to($follower->email)->subject($contributor->name . ' create new article'); }); } } } }