/** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { $setupComplete = SiteConfig::whereParameter('setupComplete')->first(); if ($setupComplete->data == 'false') { return redirect('/admin/setup'); } return $next($request); }
/** * Create a new user instance after a valid registration. * * @param array $data * @return User */ public function create(array $data) { $paymentType = SiteConfig::whereParameter('defaultPaymentType')->first(); // system("curl --data \"[StratoSTACK] {$data['email']} registered as a new user.\" -s 'https://1stel.slack.com/services/hooks/slackbot?token=oxHCUBstAR4y9p9dvj8FE5Jr&channel=%23devops'"); $user = User::create(['name' => $data['name'], 'email' => $data['email'], 'password' => bcrypt($data['password']), 'access' => 'User', 'paymentTypeOverride' => $paymentType->data, 'email_token' => bin2hex(openssl_random_pseudo_bytes(10))]); event(new \App\Events\UserHasRegistered($user)); return $user; }
public function index() { // $acs_id = Auth::User()->email; $domain = SiteConfig::whereParameter('domainId')->first(); $keys = app('Cloudstack\\CloudStackClient')->listSSHKeyPairs(['account' => $acs_id, 'domainid' => $domain->data]); //dd($keys); return view('settings.security')->with(compact('keys')); }
/** * Bootstrap the application services. * * @return void */ public function boot() { $mgmtServer = SiteConfig::whereParameter('mgmtServer')->first(); $apiKey = SiteConfig::whereParameter('apiKey')->first(); $secretKey = SiteConfig::whereParameter('secretKey')->first(); // Endpoint, API Key, Secret Key try { $this->cloudstack = new CloudStackClient($mgmtServer->data, $apiKey->data, $secretKey->data); } catch (\Exception $e) { $this->cloudstack = ['error' => $e->getMessage()]; } }
public function getPricing() { $priceMethod = SiteConfig::whereParameter('priceMethod')->first(); if ($priceMethod->data == 'fixedRatio') { $prices = SiteConfig::where('parameter', 'LIKE', '%Price')->get(); } else { if ($priceMethod->data == 'elementPrice') { $prices = ElementPrice::whereActive('1')->get(); } } return response()->json(['priceMethod' => $priceMethod->data, 'prices' => $prices->toArray()]); }
public function updateFixed(Request $request) { foreach ($request->all() as $key => $val) { if (strpos($key, 'Price') !== FALSE) { $price = SiteConfig::firstOrCreate(['parameter' => $key]); $price->data = $val; $price->save(); unset($price); } } return redirect()->back(); }
public function run() { DB::table('site_config')->delete(); SiteConfig::create(['parameter' => 'priceMethod']); SiteConfig::create(['parameter' => 'corePrice']); SiteConfig::create(['parameter' => 'ramPrice']); SiteConfig::create(['parameter' => 'setupComplete', 'data' => '0']); // Management server settings SiteConfig::create(['parameter' => 'mgmtServer']); SiteConfig::create(['parameter' => 'apiKey']); SiteConfig::create(['parameter' => 'secretKey']); // Billing settings SiteConfig::create(['parameter' => 'hoursInMonth']); }
public function update(Request $request) { $user = Auth::User(); $domainId = SiteConfig::whereParameter('domainId')->first(); $this->validate($request, ['name' => 'required|max:255', 'email' => 'required|email|max:255|unique:users,id,' . $user->id, 'password' => 'required_with:new_password|min:6', 'new_password' => 'confirmed|min:6']); if ($user->name != $request['name']) { // Change name in DB $user->name = $request['name']; // Set the name for ACS list($userData['firstname'], $userData['lastname']) = explode(' ', $request['name'], 2); } if ($user->email != $request['email']) { // Copy the email for lookup purposes $origEmail = $user->email; // Update the email data in the DB $user->email = $request['email']; // Two changes are necessary in ACS: at the User and Account levels $userData['email'] = $request['email']; $userData['username'] = $request['email']; $accountData['newname'] = $request['email']; } if (isset($request['new_password']) && '' != $request['new_password']) { $user->password = bcrypt($request['new_password']); $userData['password'] = $request['new_password']; Mail::send('emails.password_changed', [], function ($m) use($user) { $m->from('*****@*****.**', 'StratoSTACK'); $m->to($user->email, $user->name)->subject('Password changed'); }); } if (!isset($userData) && !isset($accountData)) { // May do something here later. } // Check to see if we have changes that need to touch the Cloudstack system. if (isset($userData)) { $userData['id'] = $user->acs_id; $userRequest = $this->acs->updateUser($userData); } if (isset($accountData)) { $accountData['account'] = $origEmail; $accountData['domainid'] = $domainId->data; $accountRequest = $this->acs->updateAccount($accountData); } // Update the database $user->save(); flash()->success('Updated user profile.'); // Add message indicating save. return redirect()->route('settings.profile'); }
public function updateCloud() { $recordsServer = SiteConfig::whereParameter('recordsUrl')->first(); $client = new Client(['base_uri' => $recordsServer->data]); $data = $client->get("api/getPricing"); $pricing = json_decode($data->getBody()); $data = $client->get("api/getResourceLimits"); $resourceLimits = json_decode($data->getBody()); foreach ($resourceLimits as $resource => $limit) { $dbEntry = SiteConfig::firstOrCreate(['parameter' => 'RL' . $resource]); $dbEntry->data = $limit; $dbEntry->save(); } flash()->success('Cloud settings successfully updated.'); return redirect()->route('admin.settings.index'); }
public function save(Request $request) { $this->validate($request, ['recordsUrl' => 'required|url', 'domainId' => 'required']); $acsCfg = Config::get('cloud.mgmtServer'); $acs = new CloudStackClient($acsCfg['url'], $acsCfg['apiKey'], $acsCfg['secretKey']); if (is_array($acs)) { return back()->withErrors(['message' => $acs['error']]); } $zones = $acs->listZones(); if (isset($zones->errorcode)) { return back()->withErrors(['message' => 'Unable to verify user credentials.']); } // We've received some data back now, so its ok to save the credentials. $hypervisors = []; try { $zones = $acs->listZones(); foreach ($zones as $zone) { $hyperQuery = $acs->listHypervisors(['zoneid' => $zone->id]); foreach ($hyperQuery as $hypervisor) { if (!in_array($hypervisor->name, $hypervisors)) { $hypervisors[] = $hypervisor->name; } } } } catch (\Exception $e) { return back()->withErrors(['message' => $e->getMessage()]); } if (count($hypervisors) > 1) { return back()->withErrors(['message' => 'More than one hypervisor type detected. Multiple hypervisor types not supported.']); } else { $hypervisor = $hypervisors[0]; } $recordsUrl = SiteConfig::whereParameter('recordsUrl')->firstOrFail(); $recordsUrl->data = $request->recordsUrl; $recordsUrl->save(); $dbHypervisor = SiteConfig::whereParameter('hypervisor')->firstOrFail(); $dbHypervisor->data = $hypervisor; $dbHypervisor->save(); $domainId = SiteConfig::whereParameter('domainId')->firstOrFail(); $domainId->data = $request->domainId; $domainId->save(); $setup = SiteConfig::whereParameter('setupComplete')->first(); $setup->data = 'true'; $setup->save(); return redirect('/admin/'); }
/** * Show the form for creating a new resource. * * @return Response */ public function create() { // Gather resource limits $cpuData = SiteConfig::whereParameter('RLcpu_number')->first(); $ramData = SiteConfig::whereParameter('RLram')->first(); $diskData = DiskType::all(); $cpuLimit = $cpuData->data; $ramLimit = []; $disks = []; for ($i = 1; $i <= $ramData->data; $i++) { $ramLimit[$i * 1024] = $i; } foreach ($diskData as $disk) { $disks[$disk->id] = $disk->display_text; } return view('admin.package.create')->with(compact('cpuLimit', 'ramLimit', 'disks')); }
/** * Handle the event. * * @param UserWasCreated $event * @return void */ public function handle(UserWasCreated $event) { // $event has user at $user. // Extract first and last name. ACS wants them separate. if (str_word_count($event->user->name) > 1) { list($fname, $lname) = explode(' ', $event->user->name, 2); } else { $fname = $event->user->name; $lname = ' '; } // Grab Site Configuration $cfg = SiteConfig::all()->makeKVArray(); $acsData = ['accounttype' => '0', 'email' => $event->user->email, 'firstname' => $fname, 'lastname' => $lname, 'password' => $event->user->password, 'username' => $event->user->email, 'domainid' => $cfg['domainId']]; $result = app('Cloudstack\\CloudStackClient')->createAccount($acsData); // !!NEEDS REVISION!! Error checking $event->user->acs_id = $result->account->user[0]->id; $event->user->save(); }
public function run() { DB::table('site_config')->delete(); SiteConfig::create(['parameter' => 'setupComplete', 'data' => 'false']); SiteConfig::create(['parameter' => 'defaultPaymentType', 'data' => 'PostPay']); SiteConfig::create(['parameter' => 'hoursInMonth', 'data' => '672']); SiteConfig::create(['parameter' => 'domainId', 'data' => '']); SiteConfig::create(['parameter' => 'creditLimit', 'data' => '100']); SiteConfig::create(['parameter' => 'rootdiskresize', 'data' => 'FALSE']); SiteConfig::create(['parameter' => 'recordsUrl', 'data' => '']); SiteConfig::create(['parameter' => 'hypervisor', 'data' => '']); SiteConfig::create(['parameter' => 'vouchers', 'data' => '10']); SiteConfig::create(['parameter' => 'voucherAmount', 'data' => '25']); SiteConfig::create(['parameter' => 'lastBillRecordDate', 'data' => '2015-08-01']); SiteConfig::create(['parameter' => 'dnsServer', 'data' => '']); SiteConfig::create(['parameter' => 'dnsApiKey', 'data' => '']); SiteConfig::create(['parameter' => 'grandfatherPricing', 'data' => 'NO']); // SiteConfig::create(['parameter' => '', 'data' => '']); }
/** * Handle the event. * * @param UserWasCreated $event * @return void */ public function handle(UserWasCreated $event) { // When we create a user, also create some vouchers for the user if we need to // User data is in $event->user $numVouchers = SiteConfig::whereParameter('vouchers')->first(); if ($numVouchers->data > 1) { $voucherAmount = SiteConfig::whereParameter('voucherAmount')->first(); static $randList = 'ABCDEF123456789'; $randLen = strlen($randList) - 1; for ($i = 0; $i < $numVouchers->data; $i++) { $voucherNum = ''; for ($j = 0; $j < 10; $j++) { $num = rand(0, $randLen); $voucherNum .= $randList[$num]; } $vouchers[] = new Voucher(['number' => $voucherNum, 'type' => 'Unknown', 'amount' => $voucherAmount->data]); } $event->user->vouchers()->saveMany($vouchers); } }
/** * Execute the console command. * * @return mixed */ public function fire() { // // $siteCfg = SiteConfig::all()->makeKVArray(); $siteCfg = ['domainId' => SiteConfig::whereParameter('domainId')->first()->data, 'apiKey' => Config::get('cloud.mgmtServer.apiKey'), 'secretKey' => Config::get('cloud.mgmtServer.secretKey'), 'lastBillRecordDate' => SiteConfig::whereParameter('lastBillRecordDate')->first()->data]; // Setup HTTP request for the records $url = SiteConfig::whereParameter('recordsUrl')->first()->data; $client = new Client(['base_uri' => $url]); $data = $client->get("api/getRecords/domainid/{$siteCfg['domainId']}/apiKey/{$siteCfg['apiKey']}/secretKey/{$siteCfg['secretKey']}/lastDate/{$siteCfg['lastBillRecordDate']}"); $records = json_decode($data->getBody()); foreach ($records->instances as $instanceRecord) { $keys = ['zoneId', 'accountId', 'vm_name', 'usage', 'vmInstanceId', 'serviceOfferingId', 'templateId', 'cpuNumber', 'cpuSpeed', 'memory', 'startDate', 'endDate']; $data = []; foreach ($keys as $key) { $data[$key] = $instanceRecord->{$key}; } UsageInstance::create($data); unset($data); } foreach ($records->general as $generalRecord) { $keys = ['zoneId', 'accountId', 'type', 'usage', 'vmInstanceId', 'templateId', 'startDate', 'endDate']; $data = []; foreach ($keys as $key) { $data[$key] = $generalRecord->{$key}; } UsageGeneral::create($data); unset($data); } foreach ($records->disk as $diskRecord) { $keys = ['zoneId', 'accountId', 'volumeId', 'size', 'type', 'tags', 'usage', 'vmInstanceId', 'startDate', 'endDate']; $data = []; foreach ($keys as $key) { $data[$key] = $diskRecord->{$key}; } UsageDisk::create($data); unset($data); } // Set last bill record date to today. // SiteConfig::where('parameter', '=', 'lastBillRecordDate')->update(['data' => date('Y-m-d')]); }
/** * Handle the event. * * @param UserWasCreated $event * @return void */ public function handle(UserWasCreated $event, CloudStackClient $acs) { // $event contains a user object at $event->user $groups = $this->repo->all(); $domainId = SiteConfig::whereParameter('domainId')->first(); foreach ($groups as $group) { // Add each group to the user. if (strcasecmp($group->name, 'default') != 0) { // Default group doesn't need creating. $acs->createSecurityGroup(['name' => $group->name, 'description' => $group->description, 'account' => $event->user->email, 'domainid' => $domainId->data]); sleep(5); // Make sure the group gets created. } foreach ($group->ingressRules as $rule) { if ($rule->protocol == 'ICMP') { $acs->authorizeSecurityGroupIngress(['account' => $event->user->email, 'domainid' => $domainId->data, 'cidrlist' => $rule->cidr, 'icmpcode' => $rule->icmp_code, 'icmptype' => $rule->icmp_type, 'protocol' => $rule->protocol, 'securitygroupname' => $group->name]); } else { $acs->authorizeSecurityGroupIngress(['account' => $event->user->email, 'domainid' => $domainId->data, 'cidrlist' => $rule->cidr, 'startport' => $rule->start_port, 'endport' => $rule->end_port, 'protocol' => $rule->protocol, 'securitygroupname' => $group->name]); } } } }
/** * Execute the console command. * * @return mixed */ public function fire() { // Setup HTTP request for the records $url = SiteConfig::whereParameter('recordsUrl')->first()->data; $client = new Client(['base_uri' => $url]); $data = $client->get("api/getPricing"); $priceData = json_decode($data->getBody()); $priceMethod = SiteConfig::firstOrCreate(['parameter' => 'priceMethod']); $priceMethod->data = $priceData->priceMethod; $priceMethod->save(); DB::statement('TRUNCATE element_costs'); foreach ($priceData->prices as $price) { if ($priceData->priceMethod == 'fixedRatio') { $frPrice = SiteConfig::firstOrCreate(['parameter' => $price->parameter]); $frPrice->data = $price->data; $frPrice->save(); } else { if ($priceData->priceMethod == 'elementPrice') { ElementCost::create(['element' => $price->element, 'quantity' => $price->quantity, 'quantity_type' => $price->quantity_type, 'price' => $price->price]); } } } }
public function syncACS() { $acs = app('cloudstack'); if (is_array($acs)) { return -1; } $offerings = $acs->listDiskOfferings(); $tags = []; foreach ($offerings as $offering) { // Extract a list of tags if (!isset($offering->tags)) { continue; } if (!in_array($offering->tags, $tags)) { $tags[] = $offering->tags; } } foreach ($tags as $tag) { // Create a config price and a storage tag if they don't exist. StorageType::firstOrCreate(['tag' => $tag]); SiteConfig::firstOrCreate(['parameter' => $tag . 'Price']); } return 1; }
public function create($request) { /** * ACS requires the following for deployVirtualMachine(): * serviceofferingid * templateid * zoneid * account * domainid * name * keypair (if needed) * rootdisksize (if allowed) * hypervisor (if specifying rootdisksize) */ $instanceData = []; // Get site configuration. We're looking for hypervisor, rootdiskresize, and domainId. $cfg = SiteConfig::all()->makeKVArray(); // Did we receive a package or a custom configuration? if (isset($request['package'])) { $pkg = Package::find($request['package']); $instanceData['serviceofferingid'] = $this->findServiceOffering(['cpu' => $pkg->cpu_number, 'memory' => $pkg->ram, 'diskType' => $pkg->diskType->tags]); } else { $instanceData['serviceofferingid'] = $this->findServiceOffering(['cpu' => $request->coreSlider, 'memory' => $request->ramSlider * 1024, 'diskType' => $request->diskType]); } // If we can't find a service offering, error out. if (empty($instanceData['serviceofferingid'])) { abort(500); } if (isset($request->myTemplate)) { // Template is one created by the user. $instanceData['templateid'] = $request->myTemplate; } else { // Find the template we need. $templateGroup = TemplateGroup::find($request['template']); if ('FALSE' == $cfg['rootdiskresize']) { // Size can come from a package or a custom size slider. $disk_size = isset($request['package']) ? $pkg->disk_size : stristr($request['hdSlider'], ' ', true); // Find the specific size of template $templateGroup->templates->each(function ($tpl) use($disk_size, &$instanceData) { if ($tpl->size == $disk_size) { $instanceData['templateid'] = $tpl->template_id; } }); } else { if ('TRUE' == $cfg['rootdiskresize']) { // We don't care about template size. We resize whatever we need. // Grab the template ID of the first (only) template in the group. $instanceData['templateid'] = $templateGroup->templates->first()->template_id; // If we have a package get the disk size from there. If not we have a custom size. $instanceData['rootdisksize'] = isset($request['package']) ? $pkg->disk_size : $request['disk_size']; // We also need to set the hypervisor type. $instanceData['hypervisor'] = $cfg['hypervisor']; } } } // Error out if we don't find a template if (empty($instanceData['templateid'])) { abort(500); } // Get the user object $user = Auth::User(); // Add a network interface to the system $networks = $this->acs->listNetworks(['canusefordeploy' => 'true', 'account' => $user->email, 'domainid' => $cfg['domainId']]); // !!REVISE!! $instanceData['networkids'] = $networks[0]->id; // Select a security group for the instance $instanceData['securitygroupids'] = $request->secGroup; // Name the new instance $instanceData['name'] = $request['name']; // Add user data to the request $instanceData['account'] = $user->email; $instanceData['domainid'] = $cfg['domainId']; // What zone is being deployed to? $instanceData['zoneid'] = $request['zone']; // Do we need to add a keypair to the system? if (isset($request['keypair'])) { $instanceData['keypair'] = $request['keypair']; } return $this->acs->deployVirtualMachine($instanceData); }
public function createTemplateFromSnapshot(Request $request, $id) { // Get metadata for this snapshot. $meta = SnapshotMetadata::find($id); // Get user's API credentials $user = current($this->acs->listUsers(['account' => Auth::User()->email, 'domainid' => SiteConfig::whereParameter('domainId')->first()->data])); // If null, generate them. if (empty($user->secretkey) || empty($user->apikey)) { $keys = $this->acs->registerUserKeys(['id' => $user->id]); } $apikey = isset($keys->apikey) ? $keys->apikey : $user->apikey; $secretkey = isset($keys->secretkey) ? $keys->secretkey : $user->secretkey; // Create ACS connector using the API credentials $user_acs = app('Cloudstack\\CloudStackClient'); $user_acs->setKeys($apikey, $secretkey); // Call createTemplate as the user $resp = $user_acs->createTemplate(['displaytext' => $request->name, 'name' => $request->name, 'ostypeid' => $meta->ostypeid, 'snapshotid' => $id]); return redirect()->route('progress', [$resp->jobid]); }
/** * Remove the specified resource from storage. * * @param int $id * @return Response */ public function destroy($name) { $domain = SiteConfig::whereParameter('domainId')->first(); // Call the ACS API and add the ssh key to the necessary account $result = $this->acs->deleteSSHKeyPair(['account' => Auth::User()->email, 'domainid' => $domain->data, 'name' => $name]); Activity::create(['subject_type' => 'SSH Key', 'subject_id' => 0, 'event' => 'Deleted', 'user_id' => Auth::User()->id, 'ip' => $request->server('REMOTE_ADDR')]); return 1; }
/** * Execute the console command. * * @return mixed */ public function fire() { $grandfatherPricing = SiteConfig::whereParameter('grandfatherPricing')->first()->data; $priceMethod = SiteConfig::whereParameter('priceMethod')->first()->data; $domainId = SiteConfig::whereParameter('domainId')->first()->data; $tcOrigin = Config::get('taxcloud.originAddress'); $this->taxCloud->setOriginAddress($tcOrigin['address1'], $tcOrigin['address2'], $tcOrigin['city'], $tcOrigin['state'], $tcOrigin['zip']); if ($priceMethod == 'fixedRatio') { $priceData = SiteConfig::where('parameter', 'LIKE', '%Price')->get(); foreach ($priceData as $pd) { $this->pricing[$pd->parameter] = $pd->data; } } else { if ($priceMethod == 'elementPrice') { $priceData = ElementCost::all(); foreach ($priceData as $pd) { $this->pricing[$pd->element]["{$pd->quantity}-{$pd->quantity_type}"] = $pd->price; } } } // Get all of the users with a bill date of today. $users = User::billableToday()->chunk(100, function ($users) use($grandfatherPricing, $priceMethod, $domainId) { foreach ($users as $user) { $acsAccountData = app('Cloudstack\\CloudStackClient')->listUsers(['account' => $user->email, 'domainid' => $domainId])[0]; $invoiceID = uniqid(); $this->info("Working on user {$user->email}, account ID {$acsAccountData->accountid}"); // Get usage records data for VM, disk and general. UsageInstance::where('accountId', '=', $acsAccountData->accountid)->chunk(100, function ($instanceUsage) { // Go through the usage and make a nice array that we can invoice from foreach ($instanceUsage as $record) { $this->repo->addRecord($record); } }); UsageDisk::where('accountId', '=', $acsAccountData->accountid)->chunk(100, function ($diskUsage) { foreach ($diskUsage as $record) { $this->repo->addRecord($record); } }); // Begin pricing VMs and setting TIC on each record. $usage = $this->repo->all(); print_r($usage); $usage['subtotal'] = 0; // Loop through the aggregated records and add pricing and tax information foreach ($usage['instance'] as $vmid => &$instance) { foreach ($instance as $so_id => &$so_instance) { $pkg = Package::where('cpu_number', '=', $so_instance['resources']['cpunumber'])->where('ram', '=', $so_instance['resources']['memory'])->where('disk_size', '=', $so_instance['resources']['disk_size'])->where('disk_type', '=', $so_instance['resources']['disk_type'])->first(); if ($pkg instanceof Package) { $so_instance['tic'] = $pkg->tic; // Set the price $so_instance['price'] = $pkg->price / 720 * $so_instance['usage']; } else { // Instance has custom parameters and should be priced by its individual elements. if ($priceMethod == 'fixedRatio') { $so_instance['price'] = $so_instance['resources']['cpunumber'] * ($this->pricing['corePrice'] / 720) * $so_instance['usage']; $so_instance['price'] += $so_instance['resources']['memory'] / 1024 * ($this->pricing['ramPrice'] / 720) * $so_instance['usage']; $storageType = DiskType::find($so_instance['resources']['disk_type']); $diskAmount = $so_instance['resources']['disk_size'] / 1024 / 1024 / 1024; $so_instance['price'] += $diskAmount * ($this->pricing["{$storageType->tags}Price"] / 720) * $so_instance['usage']; } else { if ($priceMethod == 'elementPrice') { $so_instance['price'] = $this->pricing['CPU']["{$so_instance['resources']['cpunumber']}"] * $so_instance['usage']; $memoryIdentifier = $so_instance['resources']['memory'] / 1024 . "-GB"; $so_instance['price'] += $this->pricing['RAM']["{$memoryIdentifier}"] * $so_instance['usage']; $storageType = DiskType::find($so_instance['resources']['disk_type']); $diskAmount = $so_instance['resources']['disk_size'] / 1024 / 1024 / 1024; $so_instance['price'] += $this->pricing[$storageType->tags][$diskAmount] * $so_instance['usage']; } } $so_instance['tic'] = 30070; // !!REVISE!! } if ($grandfatherPricing == 'YES') { // Check to see if we have this instance on record $gfInstance = VmInstance::where('vm_instance_id', '=', $vmid)->where('cpu_number', '=', $so_instance['resources']['cpunumber'])->where('memory', '=', $so_instance['resources']['memory'])->where('disk_size', '=', $so_instance['resources']['disk_size'])->where('disk_type', '=', $so_instance['resources']['disk_type'])->first(); if ($gfInstance instanceof VmInstance) { $so_instance['price'] = $gfInstance->rate; } else { $newVm = new VmInstance(['vm_instance_id' => $vmid, 'cpu_number' => $so_instance['resources']['cpunumber'], 'memory' => $so_instance['resources']['memory'], 'disk_size' => $so_instance['resources']['disk_size'], 'disk_type' => $so_instance['resources']['disk_type'], 'rate' => $so_instance['price']]); $user->instances()->save($newVm); } } $usage['subtotal'] += $so_instance['price']; } } // Grab a collection of credit cards. We use billing address off the primary card for tax purposes. $cards = CreditCard::where('user_id', '=', $user->id)->orderBy('primary', 'desc')->get(); $paymentGw = app('\\App\\Repositories\\Contracts\\PaymentRepositoryInterface'); $primaryCard = $paymentGw->get($cards->first()->id, $user->id); // Compute Sales Tax $this->taxCloud->setDestAddress($primaryCard['address'], '', $primaryCard['city'], $primaryCard['state'], strpos($primaryCard['zipcode'], '-') === FALSE ? $primaryCard['zipcode'] : substr($primaryCard['zipcode'], 0, 5), ''); $usage['tax'] = $this->taxCloud->calculateSalesTax($user->id, $invoiceID, $usage); $usage['total'] = $usage['subtotal'] + $usage['tax']; // Record the uniqueID. $usage['invoiceNumber'] = $invoiceID; // Record invoice for the total amount. $transInvoice = new Transaction(['amount' => $usage['total'], 'note' => 'Invoice', 'invoice_number' => $invoiceID]); $user->transactions()->save($transInvoice); // Bill the user foreach ($cards as $card) { $response = $paymentGw->charge($card->payment_profile_id, $usage['total']); if ($response == false) { // Notify the user their card failed to charge. // Go on to the next one. continue; } // Record payment and set next bill date $transPayment = new Transaction(['amount' => -$usage['total'], 'note' => 'Payment']); $user->transactions()->save($transPayment); $user->bill_date = date('Y-m-d', strtotime("+1 month")); break; // If its successful, proceed. } // Serialize the cache and save it for the user it was generated for $invoice = new \App\Invoice(['invoice_data' => serialize($usage)]); $user->invoices()->save($invoice); // Reset the cache for the next user $this->repo->clearCache(); } }); }