diff --git a/composer.json b/composer.json index df26d24..1133e02 100755 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "felipemateus/iptv-customers", - "version": "0.1.4", + "version": "0.2.0", "description": "This package controls the IPTV Customers list and generates an m3u8 file for each customer using laravel.", "type": "library", "license": "MIT", @@ -36,9 +36,10 @@ "require": { "php": "^7.4|^8.0", "laravel/framework": "8.82.0", - "felipemateus/iptv-core":"^1.0", - "felipemateus/iptv-channels": "^3.0.2", - "felipemateus/http-build-url": "^0.0.1" + "felipemateus/iptv-core":"^1.1", + "felipemateus/iptv-channels": "^3.0.3", + "felipemateus/http-build-url": "^0.0.1", + "felipemateus/laravel-iptv-gateway-payment":"^0.0.1" }, "autoload": { "psr-4": { @@ -53,5 +54,8 @@ } }, "minimum-stability": "stable", - "prefer-stable": true + "prefer-stable": true, + "suggest": { + "felipemateus/iptv-customers": "Allows you to control customers, plans assigned to each channel." + } } diff --git a/src/Commands/GenerateInvoces.php b/src/Commands/GenerateInvoces.php new file mode 100644 index 0000000..025c6bf --- /dev/null +++ b/src/Commands/GenerateInvoces.php @@ -0,0 +1,57 @@ +info( sprintf('Generating invoices for the month %s.', date('m/Y')) ); + $customers = IPTVCustomer::where("active",1)->get(); + + foreach($customers as $customer){ + $format = sprintf('Y-m-%d', $customer->due_day); + $due_day_this_month = date($format); + IPTVCustomerInvoce::create(['duedate_at'=>$due_day_this_month,'iptv_customer_id'=> $customer->id]); + $message = sprintf('Generated invoce to %s with due date %s.', $customer->name, $due_day_this_month ); + $this->warn($message); + } + $this->info('All Invoces generate successfully.'); + } +} diff --git a/src/Controllers/CustomerController.php b/src/Controllers/CustomerController.php index 7b035b2..eec86c8 100755 --- a/src/Controllers/CustomerController.php +++ b/src/Controllers/CustomerController.php @@ -8,6 +8,7 @@ use FelipeMateus\IPTVCustomers\Models\IPTVCustomer; use FelipeMateus\IPTVCore\Controllers\CoreController; use FelipeMateus\IPTVChannels\Model\IPTVCdn; +use FelipeMateus\IPTVGatewayPayment\Models\IPTVGateway; class CustomerController extends CoreController { @@ -35,8 +36,8 @@ public function new(){ /** * Show page from customer with id. * - * @param $id - channewl id - * @return view -> IPTV:chanel + * @param $id - customer id + * @return view -> IPTV::customer */ public function show($id){ $data["Customer"] = IPTVCustomer::findOrFail($id); @@ -45,59 +46,70 @@ public function show($id){ $data['Cdnslist'] = IPTVCdn::all(); $data['CustomerPlansAddionalList'] = $data["Customer"]->plans_additional()->get(); $data['CustomerInvoceList'] = $data["Customer"]->customer_invoce()->get(); + $data['GatewaysList'] = IPTVGateway::where('active',1)->get(); return view("IPTV::customer",$data); } /** - * Save new data from new channel in database. + * Save new data from new customer in database. * - * @return redirect -> list_channels + * @return redirect -> show_costumer */ public function create(Request $request){ $this->validate($request, [ 'name' => 'string|required', 'username' => 'required|string', 'iptv_plan_id' => 'required|exists:iptv_plans,id', + 'industry'=>'string|nullable', + 'address'=>'string|nullable', + 'phone'=>'string|nullable', + 'email'=>'string|nullable', + 'tax_no'=>'string|nullable', ]); $data = $request->all(); $data['hash_acess'] = md5(now()); - IPTVCustomer::create($data); - return redirect()->route('list_customer'); + $customer = IPTVCustomer::create($data); + return redirect()->route('show_customer',['id'=>$customer->id]); } /** - * Save new data from new channel in database. + * Update customer in database. * - * @param id from channel - * @return redirect -> list_channels + * @param id from customer + * @return redirect -> list_customers */ public function update($id,Request $request){ - $channel =IPTVCustomer::findOrFail($id); + $customer =IPTVCustomer::findOrFail($id); $this->validate($request, [ 'name' => 'string|required', 'username' => 'required|string', 'iptv_plan_id' => 'required|exists:iptv_plans,id', + 'industry'=>'string|nullable', + 'address'=>'string|nullable', + 'phone'=>'string|nullable', + 'email'=>'string|nullable', + 'tax_no'=>'string|nullable', + 'active'=>'boolean', ]); $data = $request->all(); - $data['active'] = $request->boolean('active','bool'); - $channel->update($data); + $customer->update($data); - return redirect()->route('list_customer'); + return redirect()->route('show_customer',['id'=>$customer->id]); } /** - * Delete channel form database. + * Delete customer form database. * - * @param id from channel + * @param id from customer * @return redirect -> list_customer */ public function delete($id,Request $request){ - $group =IPTVCustomer::findOrFail($id); - $group->delete(); + $customer =IPTVCustomer::findOrFail($id); + $customer->delete(); return redirect()->route('list_customer'); } diff --git a/src/Controllers/InvoceController.php b/src/Controllers/InvoceController.php index 26a81bf..1ca118b 100644 --- a/src/Controllers/InvoceController.php +++ b/src/Controllers/InvoceController.php @@ -5,7 +5,11 @@ use Illuminate\Http\Request; use FelipeMateus\IPTVCore\Controllers\CoreController; use FelipeMateus\IPTVCustomers\Models\IPTVCustomerInvoce; +use FelipeMateus\IPTVCustomers\Models\IPTVCustomer; use FelipeMateus\IPTVCustomers\Requests\IPTVCustomerInvoceCreateInvoceRequest; +use FelipeMateus\IPTVGatewayPayment\Models\IPTVGateway; +use FelipeMateus\IPTVCore\Model\IPTVConfig; + use DateTime; class InvoceController extends CoreController @@ -29,16 +33,73 @@ public function create($customer_id, IPTVCustomerInvoceCreateInvoceRequest $requ } public function pay($customer_id, $id){ - $customer = IPTVCustomerInvoce::find($id); - $customer->payment_at = now(); - $customer->save(); - return redirect()->route('show_customer', ['id'=>$customer_id]); + $data['invoce'] = IPTVCustomerInvoce::find($id); + $data['GatewaysList'] = IPTVGateway::where('active', true)->get(); + $data['ConfigData'] = IPTVConfig::getAllStringSettings(); + + $data['subtotal'] = 0; + $data['totalDiscount'] = 0; + $data['total'] = 0 ; + $data['totalTax'] = 0; + $data['final'] = 0; + + $customer = IPTVCustomer::find($customer_id); + $index = 0; + $services[$index ]['service'] = $customer->plan->name; + $services[$index ]['service_type'] = 'Principal'; + $services[$index ]['price'] = $customer->plan->price; + $services[$index ]['discont'] = 0; + $services[$index ]['tax'] = ($services[$index ]['price'] - $services[$index ]['discont']) * ( ((isset($customer->plan->tax_vat->porcent))? $customer->plan->tax_vat->porcent : 0) / 100) ; + $services[$index ]['tax_porcent'] = (isset($customer->plan->tax_vat->porcent))? $customer->plan->tax_vat->porcent : 0; + $services[$index ]['total'] = $services[$index ]['price'] + $services[$index ]['tax']; + $services[$index ]['subtotal'] = $services[$index ]['price'] - $services[$index ]['discont']; + $index++; + + foreach($customer->plans_additional as $plan){ + $services[$index ]['service'] = $plan->name; + $services[$index ]['service_type'] = 'Additional'; + $services[$index ]['price'] = $plan->price; + $services[$index ]['discont'] = 0; + $services[$index ]['tax'] = ($services[$index ]['price'] - $services[$index ]['discont']) * ( ((isset($plan->tax_vat->porcent))? $plan->tax_vat->porcent : 0) / 100) ; + $services[$index ]['tax_porcent'] = (isset($plan->tax_vat->porcent) && $plan->tax_vat->porcent != null)? $plan->tax_vat->porcent : 0; + $services[$index ]['total'] = $services[$index ]['price'] + $services[$index ]['tax']; + $services[$index ]['subtotal'] = $services[$index ]['price'] - $services[$index ]['discont']; + $index ++; + } + + $data['services'] = $services; + // Total + foreach($services as $service){ + $data['subtotal'] += $service['price']; + } + + // Total Discount + foreach($services as $service){ + $data['totalDiscount'] += $service['discont']; + } + + // Total = Total - Discount + foreach($services as $service){ + $data['total'] += $service['price'] - $service['discont']; + } + + // Total tax + foreach($services as $service){ + $data['totalTax'] += $service['tax']; + } + + // Final + foreach($services as $service){ + $data['final'] = $data['totalTax'] + $data['total']; + } + + return view("IPTV::invoce", $data); } public function cancel($customer_id, $id){ - $customer = IPTVCustomerInvoce::find($id); - $customer->canceled_at = now(); - $customer->save(); + $invoce = IPTVCustomerInvoce::find($id); + $invoce->canceled_at = now(); + $invoce->save(); return redirect()->route('show_customer', ['id'=>$customer_id]); } } diff --git a/src/Controllers/PlanController.php b/src/Controllers/PlanController.php index c387e3b..09c5d97 100755 --- a/src/Controllers/PlanController.php +++ b/src/Controllers/PlanController.php @@ -4,8 +4,9 @@ use Illuminate\Http\Request; use FelipeMateus\IPTVCustomers\Models\IPTVPlan; -use FelipeMateus\IPTVChannels\Model\IPTVChannelGroup; +use FelipeMateus\IPTVChannels\Model\IPTVChannelGroup; use FelipeMateus\IPTVCore\Controllers\CoreController; +use FelipeMateus\IPTVGatewayPayment\Models\IPTVTaxVat; class PlanController extends CoreController { @@ -25,7 +26,8 @@ public function __construct() * @return view -> IPTV::plan */ public function new(){ - return view("IPTV::plan"); + $data['TaxVatList'] = IPTVTaxVat::where('active', true)->get(); + return view("IPTV::plan", $data); } /** @@ -35,6 +37,8 @@ public function new(){ */ public function create(Request $request){ $data = $request->all(); + $data = $request->except(['iptv_tax_vat_id']); + $tax_vat = $request->only('iptv_tax_vat_id')['iptv_tax_vat_id']; IPTVPlan::create($data); return redirect()->route('list_plan'); } @@ -49,6 +53,7 @@ public function show($id){ $data["Plan"] = IPTVPlan::findOrFail($id); $data['GroupList'] = $data["Plan"]->groupsList(); $data['PlanGroupList'] =$data["Plan"]->groups; + $data['TaxVatList'] = IPTVTaxVat::where('active', true)->get(); return view("IPTV::plan",$data); } @@ -60,7 +65,9 @@ public function show($id){ */ public function update($id,Request $request){ $plan =IPTVPlan::findOrFail($id); - $data = $request->all(); + $data = $request->except(['iptv_tax_vat_id']); + $tax_vat = $request->only('iptv_tax_vat_id')['iptv_tax_vat_id']; + $plan->update($data); if(!isset($data['active'])){ @@ -75,6 +82,14 @@ public function update($id,Request $request){ $plan->additional=true; } + if(isset($tax_vat) ){ + $plan->iptv_tax_vat_id= ($tax_vat == 'null')? + null + : + $tax_vat + ; + } + $plan->save(); return redirect()->route('list_plan'); } diff --git a/src/Dashs/Customers.php b/src/Dashs/Customers.php index 90403ac..720a671 100755 --- a/src/Dashs/Customers.php +++ b/src/Dashs/Customers.php @@ -2,7 +2,7 @@ namespace FelipeMateus\IPTVCustomers\Dashs; -use FelipeMateus\IPTVCore\Class\IPTVDashBase; +use FelipeMateus\IPTVCore\Helpers\IPTVDashBase; use FelipeMateus\IPTVCustomers\Models\IPTVCustomer; class Customers extends IPTVDashBase { diff --git a/src/Dashs/Plans.php b/src/Dashs/Plans.php index 8c9dac1..e20eafa 100755 --- a/src/Dashs/Plans.php +++ b/src/Dashs/Plans.php @@ -2,7 +2,7 @@ namespace FelipeMateus\IPTVCustomers\Dashs; -use FelipeMateus\IPTVCore\Class\IPTVDashBase; +use FelipeMateus\IPTVCore\Helpers\IPTVDashBase; use FelipeMateus\IPTVCustomers\Models\IPTVPlan; class Plans extends IPTVDashBase { diff --git a/src/IPTVProvider.php b/src/IPTVProvider.php index f7d9b39..cf5435b 100755 --- a/src/IPTVProvider.php +++ b/src/IPTVProvider.php @@ -5,9 +5,10 @@ use Illuminate\Routing\Router; use Illuminate\Support\ServiceProvider; use FelipeMateus\IPTVCustomers\Middleware\CustomerMiddleware; -use FelipeMateus\IPTVCore\Class\IPTVProviderBase; +use FelipeMateus\IPTVCore\Helpers\IPTVProviderBase; use FelipeMateus\IPTVCustomers\Dashs\Customers; use FelipeMateus\IPTVCustomers\Dashs\Plans; +use FelipeMateus\IPTVCustomers\Commands\GenerateInvoces; class IPTVProvider extends IPTVProviderBase { @@ -27,10 +28,9 @@ public function boot() $this->loadJSONTranslationsFrom(__DIR__.'/resources/translations'); $this->loadMenusFrom(__DIR__.'/resources/menu'); $this->registerDashboard(); + $this->registerCommands(); } - - /** * Register the application services. * @@ -61,5 +61,17 @@ private function registerDashboard(){ $this->loadDashFrom(Plans::class); } + /** + * Register Commands + * + * @return void + */ + private function registerCommands(){ + if ($this->app->runningInConsole()) { + $this->commands([ + GenerateInvoces::class, + ]); + } + } } diff --git a/src/Models/IPTVCustomer.php b/src/Models/IPTVCustomer.php index c09bd46..bb6f547 100755 --- a/src/Models/IPTVCustomer.php +++ b/src/Models/IPTVCustomer.php @@ -15,7 +15,18 @@ class IPTVCustomer extends Model * @var array */ protected $fillable = [ - 'name', 'username', 'hash_acess', 'iptv_plan_id','iptv_cdn_id','active' + 'name', + 'username', + 'hash_acess', + 'iptv_plan_id', + 'iptv_cdn_id', + 'active', + 'due_day', + 'industry', + 'address', + 'phone', + 'email', + 'tax_no' ]; protected $table = "iptv_customers"; @@ -98,10 +109,21 @@ public function getDefeatedAttribute(){ $first_day_this_month = date('Y-m-01'); $last_day_this_month = date('Y-m-t'); - return IPTVCustomerInvoce::whereBetween('duedate_at', [$first_day_this_month, $last_day_this_month ]) + $this_month_deafeted = IPTVCustomerInvoce::whereBetween('duedate_at', [$first_day_this_month, $last_day_this_month ]) ->where('payment_at','=',null) ->where('canceled_at','=',null) ->count(); + + $before_months = IPTVCustomerInvoce::where('duedate_at', '<', $first_day_this_month) + ->where('payment_at','=',null) + ->where('canceled_at','=',null) + ->count(); + + if($this_month_deafeted || $before_months){ + return true; + } + + return false; } } diff --git a/src/Models/IPTVCustomerInvoce.php b/src/Models/IPTVCustomerInvoce.php index d8ab1b0..56a81d9 100644 --- a/src/Models/IPTVCustomerInvoce.php +++ b/src/Models/IPTVCustomerInvoce.php @@ -56,5 +56,14 @@ public function getIsCanceledAttribute($value) } } + /** + * customer do invoce + * + * @return realation + * + */ + public function customer(){ + return $this->belongsTo('FelipeMateus\IPTVCustomers\Models\IPTVCustomer', 'iptv_customer_id'); + } } diff --git a/src/Models/IPTVPlan.php b/src/Models/IPTVPlan.php index d02493e..3184f2d 100755 --- a/src/Models/IPTVPlan.php +++ b/src/Models/IPTVPlan.php @@ -4,6 +4,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use FelipeMateus\IPTVGatewayPayment\Models\IPTVTaxVat; class IPTVPlan extends Model { @@ -15,7 +16,7 @@ class IPTVPlan extends Model * @var array */ protected $fillable = [ - 'name', 'price', 'active', 'additional' + 'name', 'price', 'active', 'additional','iptv_tax_vat_id' ]; protected $table = "iptv_plans"; @@ -37,4 +38,8 @@ public function groupsList(){ static public function activePlanList(){ return self::where("active",1)->where("additional",0)->get(); } + + public function tax_vat (){ + return $this->belongsTo(IPTVTaxVat::class, 'iptv_tax_vat_id'); + } } diff --git a/src/database/migrations/2022_01_11_145921_create_iptv_customer_invoces_table.php b/src/database/migrations/2022_01_11_145921_create_iptv_customer_invoces_table.php index 0e71839..54977ef 100644 --- a/src/database/migrations/2022_01_11_145921_create_iptv_customer_invoces_table.php +++ b/src/database/migrations/2022_01_11_145921_create_iptv_customer_invoces_table.php @@ -16,7 +16,7 @@ public function up() Schema::create('iptv_customer_invoces', function (Blueprint $table) { $table->id(); $table->foreignId('iptv_customer_id')->constrained('iptv_customers'); - $table->date('duedate_at'); + $table->date('duedate_at')->unique(); $table->timestamp('payment_at')->nullable(); $table->timestamp('canceled_at')->nullable(); }); diff --git a/src/database/migrations/2022_02_06_160336_update_iptv_customers_table.php b/src/database/migrations/2022_02_06_160336_update_active_iptv_customers_table.php similarity index 92% rename from src/database/migrations/2022_02_06_160336_update_iptv_customers_table.php rename to src/database/migrations/2022_02_06_160336_update_active_iptv_customers_table.php index 21bd0b4..0dbfc3f 100644 --- a/src/database/migrations/2022_02_06_160336_update_iptv_customers_table.php +++ b/src/database/migrations/2022_02_06_160336_update_active_iptv_customers_table.php @@ -4,7 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class UpdateIptvCustomersTable extends Migration +class UpdateActiveIptvCustomersTable extends Migration { /** * Run the migrations. diff --git a/src/database/migrations/2022_02_19_144217_update_due_iptv_customers_table.php b/src/database/migrations/2022_02_19_144217_update_due_iptv_customers_table.php new file mode 100644 index 0000000..16b4bd6 --- /dev/null +++ b/src/database/migrations/2022_02_19_144217_update_due_iptv_customers_table.php @@ -0,0 +1,35 @@ +enum('due_day', [5,10,15,20,25])->default(15); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + + Schema::table('iptv_customers', function (Blueprint $table) { + $table->dropColumn('due_day'); + }); + } +} diff --git a/src/database/migrations/2022_03_02_152323_update_tax_iptv_customers_table.php b/src/database/migrations/2022_03_02_152323_update_tax_iptv_customers_table.php new file mode 100644 index 0000000..ffb54a0 --- /dev/null +++ b/src/database/migrations/2022_03_02_152323_update_tax_iptv_customers_table.php @@ -0,0 +1,34 @@ +foreignId('iptv_tax_vat_id')->nullable()->constrained('iptv_tax_vat'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + Schema::table('iptv_plans', function (Blueprint $table) { + $table->dropColumn('iptv_tax_vat_id'); + }); + } +} diff --git a/src/database/migrations/2022_03_11_013657_update_customer_invoce_table.php b/src/database/migrations/2022_03_11_013657_update_customer_invoce_table.php new file mode 100644 index 0000000..9848bed --- /dev/null +++ b/src/database/migrations/2022_03_11_013657_update_customer_invoce_table.php @@ -0,0 +1,32 @@ +text('payment_data')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('iptv_customer_invoces', function (Blueprint $table) { + $table->dropColumn('payment_data'); + }); + } +} diff --git a/src/database/migrations/2022_04_08_024905_update_custumer_datais_table.php b/src/database/migrations/2022_04_08_024905_update_custumer_datais_table.php new file mode 100755 index 0000000..747174b --- /dev/null +++ b/src/database/migrations/2022_04_08_024905_update_custumer_datais_table.php @@ -0,0 +1,42 @@ +string('industry')->nullable(); + $table->string('address')->nullable(); + $table->string('phone')->nullable(); + $table->string('email')->nullable(); + $table->string('tax_no')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + Schema::table('iptv_customers', function (Blueprint $table) { + $table->dropColumn('industry'); + $table->dropColumn('address'); + $table->dropColumn('phone'); + $table->dropColumn('email'); + $table->dropColumn('tax_no'); + }); + } +} diff --git a/src/resources/translations/br.json b/src/resources/translations/br.json index a11db7a..a31e3f2 100755 --- a/src/resources/translations/br.json +++ b/src/resources/translations/br.json @@ -26,5 +26,10 @@ "Invoces": "Faturas", "Due date": "Vencimento", "Paid": "Pago", - "Canceled": "Cancelado" + "Canceled": "Cancelado", + "Due Day":"Dia de Vencimento", + "Address": "Endereço", + "Industry": "Atividade", + "Tax Number": "CNPJ", + "Phone": "Telefone" } diff --git a/src/resources/views/customer.blade.php b/src/resources/views/customer.blade.php index 4f22d92..c7745c3 100755 --- a/src/resources/views/customer.blade.php +++ b/src/resources/views/customer.blade.php @@ -72,6 +72,62 @@ +