Пример #1
0
 /**
  * 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')]);
 }
 public function getRecords($domainid, $apiKey, $secretKey, $lastDate)
 {
     // Request should contain an API key, Secret key, start date and end date.
     $acs = app('cloudstack');
     if (is_array($acs)) {
         return response()->json(['error' => 'Internal server error. ' . $acs['error']]);
     }
     $loginResponse = $acs->listUsers(['domainid' => $domainid]);
     foreach ($loginResponse as $user) {
         if (!isset($user->apikey, $user->secretkey)) {
             continue;
         }
         if ($apiKey == $user->apikey && $secretKey == $user->secretkey) {
             // User found, give up the records.
             $usageGeneral = UsageGeneral::where('domainId', '=', $domainid)->where('startDate', '>=', $lastDate)->get()->toArray();
             $usageVMs = UsageVm::where('domainId', '=', $domainid)->where('startDate', '>=', $lastDate)->get()->toArray();
             $usageDisk = UsageDisk::where('domainId', '=', $domainid)->where('startDate', '>=', $lastDate)->get()->toArray();
             return response()->json(['general' => $usageGeneral, 'instances' => $usageVMs, 'disk' => $usageDisk]);
         }
     }
     return response()->json(['error' => 'Invalid credentials.']);
 }
 /**
  * Execute the console command.
  *
  * @return mixed
  */
 public function fire()
 {
     // Setup lists to look up ACS IDs.
     // We need: zones, accounts, domains, instances, service offerings and templates.
     $dataTypes = ['cloud.data_center' => 'zones', 'cloud.domain' => 'domains', 'cloud.account' => 'accounts', 'cloud.vm_instance' => 'instances', 'cloud.service_offering_view' => 'serviceofferings', 'cloud.template_view' => 'templates'];
     $uuidLookup = [];
     foreach ($dataTypes as $table => $type) {
         $dbInfo = DB::table($table)->get();
         $uuidLookup[$type] = [];
         foreach ($dbInfo as $info) {
             $uuidLookup[$type][$info->id] = $info->uuid;
         }
     }
     $diskInfo = DB::table('cloud.disk_offering')->get();
     $diskOfferings = [];
     foreach ($diskInfo as $do) {
         $diskOfferings[$do->id] = $do->tags;
     }
     // Grab yesterday's records
     $yesterday = date('Y-m-d', time() - 84600);
     $records = App\CloudUsage::like('start_date', $yesterday . '%')->billable()->get()->each(function ($record) use($uuidLookup, $diskOfferings) {
         $recordType = '';
         switch ($record->usage_type) {
             case 2:
                 $recordType = 'VM Instance';
                 // Grab the service offering of the VM
                 $serviceOffering = App\ServiceOffering::find($record->offering_id);
                 if (null == $serviceOffering->cpu && null == $serviceOffering->speed && null == $serviceOffering->ram_size) {
                     // Our service offering is Custom.  Grab its resources from our custom table.
                     $resources = App\VmResources::find($record->vm_instance_id);
                     $cpuNumber = $resources->cpuNumber;
                     $cpuSpeed = $resources->cpuSpeed;
                     $memory = $resources->memory;
                 } else {
                     $cpuNumber = $serviceOffering->cpu;
                     $cpuSpeed = $serviceOffering->speed;
                     $memory = $serviceOffering->ram_size;
                 }
                 App\UsageVm::create(['zoneId' => $uuidLookup['zones'][$record->zone_id], 'accountId' => $uuidLookup['accounts'][$record->account_id], 'domainId' => $uuidLookup['domains'][$record->domain_id], 'vm_name' => $record->vm_name, 'type' => 'VM', 'usage' => $record->raw_usage, 'vmInstanceId' => $uuidLookup['instances'][$record->vm_instance_id], 'serviceOfferingId' => $uuidLookup['serviceofferings'][$record->offering_id], 'templateId' => $uuidLookup['templates'][$record->template_id], 'cpuNumber' => $cpuNumber, 'cpuSpeed' => $cpuSpeed, 'memory' => $memory, 'startDate' => $record->start_date, 'endDate' => $record->end_date]);
                 break;
             case 4:
             case 5:
                 $recordType = 'Network Usage';
                 App\UsageGeneral::create(['zoneId' => $uuidLookup['zones'][$record->zone_id], 'accountId' => $uuidLookup['accounts'][$record->account_id], 'domainId' => $uuidLookup['domains'][$record->domain_id], 'type' => stripos($record->usage_display, 'Received') === false ? 'Network Sent' : 'Network Received', 'usage' => $record->raw_usage, 'startDate' => $record->start_date, 'endDate' => $record->end_date]);
                 break;
             case 6:
                 $recordType = 'Disk/Volume';
                 // Fetch the VM instance this volume belongs to.
                 $vol = App\Volume::find($record->usage_id);
                 try {
                     $instance = App\VmInstance::find($vol->instance_id);
                 } catch (\Exception $e) {
                     continue;
                     // Ignored bad record.
                 }
                 if (!$instance instanceof App\VmInstance) {
                     continue;
                 }
                 // Ignore this record, its bad for some reason.
                 App\UsageDisk::create(['zoneId' => $uuidLookup['zones'][$record->zone_id], 'accountId' => $uuidLookup['accounts'][$record->account_id], 'domainId' => $uuidLookup['domains'][$record->domain_id], 'volumeId' => $vol->uuid, 'type' => $vol->volume_type == 'ROOT' ? 'Root Volume' : 'Volume', 'tags' => $diskOfferings[$vol->disk_offering_id], 'usage' => $record->raw_usage, 'size' => $record->size, 'vmInstanceId' => $uuidLookup['instances'][$instance->id], 'startDate' => $record->start_date, 'endDate' => $record->end_date]);
                 break;
             case 9:
                 $recordType = 'Snapshot';
                 App\UsageDisk::create(['zoneId' => $uuidLookup['zones'][$record->zone_id], 'accountId' => $uuidLookup['accounts'][$record->account_id], 'domainId' => $uuidLookup['domains'][$record->domain_id], 'type' => 'Snapshot', 'usage' => $record->raw_usage, 'size' => $record->size, 'startDate' => $record->start_date, 'endDate' => $record->end_date]);
                 break;
             case 11:
                 $recordType = 'Load Balancer';
                 App\UsageGeneral::create(['zoneId' => $uuidLookup['zones'][$record->zone_id], 'accountId' => $uuidLookup['accounts'][$record->account_id], 'domainId' => $uuidLookup['domains'][$record->domain_id], 'type' => 'LB', 'usage' => $record->raw_usage, 'vmInstanceId' => $uuidLookup['instances'][$record->vm_instance_id], 'templateId' => $uuidLookup['templates'][$record->template_id], 'startDate' => $record->start_date, 'endDate' => $record->end_date]);
                 break;
             case 12:
                 $recordType = 'Port Forward';
                 App\UsageGeneral::create(['zoneId' => $uuidLookup['zones'][$record->zone_id], 'accountId' => $uuidLookup['accounts'][$record->account_id], 'domainId' => $uuidLookup['domains'][$record->domain_id], 'type' => 'PF', 'usage' => $record->raw_usage, 'vmInstanceId' => $uuidLookup['instances'][$record->vm_instance_id], 'templateId' => $uuidLookup['templates'][$record->template_id], 'startDate' => $record->start_date, 'endDate' => $record->end_date]);
                 break;
             case 14:
                 $recordType = 'VPN';
                 App\UsageGeneral::create(['zoneId' => $uuidLookup['zones'][$record->zone_id], 'accountId' => $uuidLookup['accounts'][$record->account_id], 'domainId' => $uuidLookup['domains'][$record->domain_id], 'type' => 'VPN', 'usage' => $record->raw_usage, 'vmInstanceId' => $uuidLookup['instances'][$record->vm_instance_id], 'templateId' => $uuidLookup['templates'][$record->template_id], 'startDate' => $record->start_date, 'endDate' => $record->end_date]);
                 break;
             default:
                 $recordType = 'Unknown (' . $record->usage_type . ')';
                 break;
         }
         $this->info('Found a record of type ' . $recordType);
     });
 }
Пример #4
0
 /**
  * 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();
         }
     });
 }