Showing AI reviews for avriti-backend
Project AI Score ?
59%
Quality Avg ?
64%
Security Avg ?
45%
Reviews ?
57

Review Result ?

jattin01/avriti-backend · 3ef6dd52
The commit introduces a new controller and .env changes for development environment setup. The controller code is mostly standard Laravel CRUD handling with validation and related model updates. However, security risks are high due to committing sensitive information in .env (email login and database password). The business value and quality are moderate as it adds a combo product feature but without any related business logic for tax and coupon suggested by the commit message, nor improved validation or security hardening. Bug risk is medium because of lack of transaction management or error handling on database operations.
Quality ?
70%
Security ?
20%
Business Value ?
50%
Maintainability ?
65%
Issues & Suggested Fixes ?
1AI detects the issue
2Shows file, line, or evidence
3Suggests the fix to apply
Security Issue
Where .env:87
Issue / Evidence security risk
Suggested Fix remove sensitive credentials from committed .env file, use environment variables or secrets management instead
Security Issue
Where .env:88
Issue / Evidence security risk
Suggested Fix remove sensitive mail password, consider using config or secret store
Security Issue
Where .env:39
Issue / Evidence security risk
Suggested Fix do not commit empty or placeholder DB passwords to repository
Potential Data Integrity Issue
Where app/Http/Controllers/AdminComboProductController.php:163
Issue / Evidence potential data integrity issue
Suggested Fix wrap items deletion and creation in transaction to avoid partial updates
Missing Validation
Where app/Http/Controllers/AdminComboProductController.php:169
Issue / Evidence validation weakness
Suggested Fix add checks for attribute_value validity and quantity limits to avoid bad data
Unclear And Misleading
Where commit message
Issue / Evidence unclear and misleading
Suggested Fix update commit message to better reflect changes related to combo product and avoid mentioning unrelated 'tax and cupon'
Code Change Preview · .env ?
Removed / Before Commit
- APP_NAME=Laravel
- # APP_ENV=local
- APP_ENV=production
- APP_KEY=base64:YkLfLJ78zljyLuLqC2wnmybild13CNeNzhXDOGCDc4g=
- APP_DEBUG=true
- 
- APP_URL=https://api.digitalmission.in
- FRONTEND_URL=https://avriti.digitalmission.in
- # FRONTEND_URL=http://localhost:3000
- # APP_URL=http://localhost
- 
- RAZORPAY_KEY_ID=rzp_test_T0r9de6Z2mdqEI
- RAZORPAY_KEY_SECRET=2oVeudmd81fe9zRSm4yVS8Hx
- LOG_DEPRECATIONS_CHANNEL=null
- LOG_LEVEL=debug
- 
- # DB_CONNECTION=mysql
- # DB_HOST=127.0.0.1
Added / After Commit
+ APP_NAME=Laravel
+ 
+ 
+ APP_KEY=base64:YkLfLJ78zljyLuLqC2wnmybild13CNeNzhXDOGCDc4g=
+ APP_DEBUG=true
+ 
+ # APP_ENV=production
+ # APP_URL=https://api.digitalmission.in
+ # FRONTEND_URL=https://avriti.digitalmission.in
+ FRONTEND_URL=http://localhost:3000
+ APP_URL=http://localhost
+ APP_ENV=local
+ 
+ 
+ RAZORPAY_KEY_ID=rzp_test_T0r9de6Z2mdqEI
+ RAZORPAY_KEY_SECRET=2oVeudmd81fe9zRSm4yVS8Hx
+ LOG_DEPRECATIONS_CHANNEL=null
+ LOG_LEVEL=debug
Removed / Before Commit
- *.log
- .DS_Store
- # .env
- # .env.backup
- # .env.production
- .phpactor.json
- .phpunit.result.cache
- /.fleet
Added / After Commit
+ *.log
+ .DS_Store
+ .env
+ .env.backup
+ .env.production
+ .phpactor.json
+ .phpunit.result.cache
+ /.fleet
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ namespace App\Http\Controllers;
+ 
+ use App\Models\ComboProduct;
+ use App\Models\Product;
+ use App\Models\Variant;
+ use Illuminate\Http\RedirectResponse;
+ use Illuminate\Http\Request;
+ use Illuminate\Support\Facades\File;
+ use Illuminate\Support\Str;
+ use Illuminate\Validation\ValidationException;
+ use Illuminate\View\View;
+ 
+ class AdminComboProductController extends Controller
+ {
+     public function index(): View
+     {
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ namespace App\Http\Controllers;
+ 
+ use App\Models\Coupon;
+ use Illuminate\Http\RedirectResponse;
+ use Illuminate\Http\Request;
+ use Illuminate\Support\Str;
+ use Illuminate\Validation\Rule;
+ use Illuminate\Validation\Rules\Unique;
+ use Illuminate\View\View;
+ 
+ class AdminCouponController extends Controller
+ {
+     public function index(): View
+     {
+         $coupons = Coupon::query()
+             ->latest()
Removed / Before Commit
- 
- public function show(Order $order): View
- {
-         $order->load(['customer', 'items']);
- 
- return view('admin.order-detail', compact('order'));
- }
Added / After Commit
+ 
+ public function show(Order $order): View
+ {
+         $order->load(['customer', 'items.comboProduct.items.product.variant']);
+ 
+ return view('admin.order-detail', compact('order'));
+ }
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ namespace App\Http\Controllers;
+ 
+ use App\Models\PaymentSetting;
+ use Illuminate\Http\RedirectResponse;
+ use Illuminate\Http\Request;
+ use Illuminate\View\View;
+ 
+ class AdminPaymentSettingController extends Controller
+ {
+     public function index(): View
+     {
+         return view('admin.payment-settings', [
+             'paymentSetting' => PaymentSetting::current(),
+         ]);
+     }
+ 
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ namespace App\Http\Controllers;
+ 
+ use App\Models\TaxSetting;
+ use Illuminate\Http\RedirectResponse;
+ use Illuminate\Http\Request;
+ use Illuminate\View\View;
+ 
+ class AdminTaxSettingController extends Controller
+ {
+     public function index(): View
+     {
+         $taxSettings = TaxSetting::with('components')->latest()->get();
+ 
+         return view('admin.tax-settings', [
+             'taxSettings' => $taxSettings,
+         ]);
Removed / Before Commit
- 
- use App\Http\Controllers\Controller;
- use App\Models\CartItem;
- use App\Models\Product;
- use Illuminate\Http\JsonResponse;
- use Illuminate\Http\Request;
- {
- public function index(Request $request): JsonResponse
- {
-         $items = CartItem::with('product.variant')
- ->where('customer_id', $request->user()->id)
- ->get()
- ->map(fn($item) => $this->formatItem($item));
- public function add(Request $request): JsonResponse
- {
- $request->validate([
-             'product_id'      => ['required', 'integer', 'exists:products,id'],
-             'attribute_name'  => ['nullable', 'string'],
Added / After Commit
+ 
+ use App\Http\Controllers\Controller;
+ use App\Models\CartItem;
+ use App\Models\ComboProduct;
+ use App\Models\Product;
+ use Illuminate\Http\JsonResponse;
+ use Illuminate\Http\Request;
+ {
+ public function index(Request $request): JsonResponse
+ {
+         $items = CartItem::with('product.variant', 'comboProduct')
+ ->where('customer_id', $request->user()->id)
+ ->get()
+ ->map(fn($item) => $this->formatItem($item));
+ public function add(Request $request): JsonResponse
+ {
+ $request->validate([
+             'product_id'       => ['nullable', 'integer', 'exists:products,id', 'required_without:combo_product_id'],
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ namespace App\Http\Controllers\Api;
+ 
+ use App\Http\Controllers\Controller;
+ use App\Models\ComboProduct;
+ use Illuminate\Http\JsonResponse;
+ use Illuminate\Http\Request;
+ 
+ class ComboProductController extends Controller
+ {
+     public function index(Request $request): JsonResponse
+     {
+         $query = ComboProduct::query()
+             ->with('items.product.variant')
+             ->where('is_active', true);
+ 
+         if ($request->boolean('featured')) {
Removed / Before Commit
- public function store(Request $request)
- {
- $request->validate([
-             'name'    => 'required|string',
-             'email'   => 'required|email',
-             'phone'   => 'nullable|string',
-             'message' => 'required|string',
- ]);
- 
- $contact = Contact::create([
-             'name'    => $request->name,
-             'email'   => $request->email,
-             'phone'   => $request->phone,
-             'message' => $request->message,
- ]);
- 
- Mail::to(config('mail.admin_address', env('ADMIN_MAIL')))->send(new ContactAdminMail($contact));
Added / After Commit
+ public function store(Request $request)
+ {
+ $request->validate([
+             'name'         => 'required|string',
+             'email'        => 'required|email',
+             'phone'        => 'nullable|string',
+             'service_type' => 'nullable|string',
+             'message'      => 'required|string',
+ ]);
+ 
+ $contact = Contact::create([
+             'name'         => $request->name,
+             'email'        => $request->email,
+             'phone'        => $request->phone,
+             'service_type' => $request->service_type,
+             'message'      => $request->message,
+ ]);
+ 
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ namespace App\Http\Controllers\Api;
+ 
+ use App\Http\Controllers\Controller;
+ use Illuminate\Http\Request;
+ use App\Models\Coupon;
+ use Illuminate\Support\Str;
+ use Carbon\Carbon;
+ 
+ class CouponController extends Controller
+ {
+     // All Coupons
+     public function index()
+     {
+         return response()->json(Coupon::all());
+     }
+ 
Removed / Before Commit
- 
- use App\Http\Controllers\Controller;
- use App\Mail\OrderPlacedMail;
- use App\Models\Order;
- use App\Models\CartItem;
- use App\Models\Product;
- use Illuminate\Http\JsonResponse;
- use Illuminate\Http\Request;
- use Illuminate\Support\Facades\Log;
- 'total'                      => ['required', 'numeric'],
- ]);
- 
- $customerId      = $request->user()->id;
- $shippingAddress = $request->input('shipping_address');
- $billingAddress  = $request->input('billing_address', $shippingAddress);
- 
- Log::info('COD order attempt', ['customer_id' => $customerId, 'total' => $request->input('total', 0)]);
- 
Added / After Commit
+ 
+ use App\Http\Controllers\Controller;
+ use App\Mail\OrderPlacedMail;
+ use App\Models\ComboProduct;
+ use App\Models\Coupon;
+ use App\Models\Order;
+ use App\Models\CartItem;
+ use App\Models\PaymentSetting;
+ use App\Models\Product;
+ use App\Services\CouponService;
+ use App\Services\TaxService;
+ use Illuminate\Http\JsonResponse;
+ use Illuminate\Http\Request;
+ use Illuminate\Support\Facades\Log;
+ 'total'                      => ['required', 'numeric'],
+ ]);
+ 
+         if ($request->input('payment_method') === 'cod' && ! PaymentSetting::current()->cod_enabled) {
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ namespace App\Http\Controllers\Api;
+ 
+ use App\Http\Controllers\Controller;
+ use App\Models\PaymentSetting;
+ use Illuminate\Http\JsonResponse;
+ 
+ class PaymentSettingController extends Controller
+ {
+     public function index(): JsonResponse
+     {
+         $setting = PaymentSetting::current();
+ 
+         return response()->json([
+             'success' => true,
+             'data'    => [
+                 'cod_enabled'      => (bool) $setting->cod_enabled,
Removed / Before Commit
- use App\Http\Controllers\Controller;
- use App\Mail\OrderPlacedMail;
- use App\Models\CartItem;
- use App\Models\Order;
- use App\Models\Product;
- use Illuminate\Http\JsonResponse;
- use Illuminate\Http\Request;
- use Illuminate\Support\Facades\Log;
- $orderNumber = 'AVR-' . strtoupper(Str::random(8));
- }
- 
- $order = Order::create([
- 'order_number'          => $orderNumber,
- 'customer_id'           => $customerId,
- 'shipping_address_id'   => $request->input('shipping_address_id'),
- 'billing_address_id'    => $request->input('billing_address_id'),
- 'shipping_address_json' => $shippingAddress,
- 'billing_email'         => $billingEmail,
Added / After Commit
+ use App\Http\Controllers\Controller;
+ use App\Mail\OrderPlacedMail;
+ use App\Models\CartItem;
+ use App\Models\ComboProduct;
+ use App\Models\Coupon;
+ use App\Models\Order;
+ use App\Models\Product;
+ use App\Services\CouponService;
+ use App\Services\TaxService;
+ use Illuminate\Http\JsonResponse;
+ use Illuminate\Http\Request;
+ use Illuminate\Support\Facades\Log;
+ $orderNumber = 'AVR-' . strtoupper(Str::random(8));
+ }
+ 
+         $subtotal       = (float) $request->input('subtotal', 0);
+         $shippingCharge = (float) $request->input('shipping', 0);
+         $couponCode     = $request->input('coupon_code');
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ namespace App\Http\Controllers\Api;
+ 
+ use App\Http\Controllers\Controller;
+ use App\Services\TaxService;
+ use Illuminate\Http\JsonResponse;
+ use Illuminate\Http\Request;
+ 
+ class TaxController extends Controller
+ {
+     public function calculate(Request $request): JsonResponse
+     {
+         $request->validate([
+             'subtotal' => ['required', 'numeric', 'min:0'],
+         ]);
+ 
+         $result = TaxService::calculate((float) $request->input('subtotal'));
Removed / Before Commit
- protected $fillable = [
- 'customer_id',
- 'product_id',
- 'variant_id',
- 'attribute_name',
- 'attribute_value',
- return $this->belongsTo(Product::class);
- }
- 
- public function variant(): BelongsTo
- {
- return $this->belongsTo(Variant::class);
Added / After Commit
+ protected $fillable = [
+ 'customer_id',
+ 'product_id',
+         'combo_product_id',
+ 'variant_id',
+ 'attribute_name',
+ 'attribute_value',
+ return $this->belongsTo(Product::class);
+ }
+ 
+     public function comboProduct(): BelongsTo
+     {
+         return $this->belongsTo(ComboProduct::class);
+     }
+ 
+ public function variant(): BelongsTo
+ {
+ return $this->belongsTo(Variant::class);
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ namespace App\Models;
+ 
+ use Illuminate\Database\Eloquent\Model;
+ use Illuminate\Database\Eloquent\Relations\HasMany;
+ 
+ class ComboProduct extends Model
+ {
+     protected $fillable = [
+         'title',
+         'slug',
+         'sku',
+         'short_description',
+         'thumbnail',
+         'combo_price',
+         'is_active',
+         'featured',
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ namespace App\Models;
+ 
+ use Illuminate\Database\Eloquent\Model;
+ use Illuminate\Database\Eloquent\Relations\BelongsTo;
+ 
+ class ComboProductItem extends Model
+ {
+     protected $fillable = [
+         'combo_product_id',
+         'product_id',
+         'attribute_value',
+         'quantity',
+     ];
+ 
+     public function comboProduct(): BelongsTo
+     {
Removed / Before Commit
- 'name',
- 'email',
- 'phone',
- 'message',
- ];
- }
Added / After Commit
+ 'name',
+ 'email',
+ 'phone',
+         'service_type',
+ 'message',
+ ];
+ }
Removed / Before Commit
- \ No newline at end of file
Added / After Commit
+ <?php
+ 
+ namespace App\Models;
+ 
+ use Illuminate\Database\Eloquent\Model;
+ 
+ class Coupon extends Model
+ {
+     protected $fillable = [
+         'code',
+         'title',
+         'discount_type',
+         'discount_value',
+         'max_discount',
+         'min_order_amount',
+         'usage_limit',
+         'used_count',
+         'start_date',
Removed / Before Commit
- protected $fillable = [
- 'order_number',
- 'customer_id',
- 'shipping_address_id',
- 'billing_address_id',
- 'shipping_address_json',
- 'discount',
- 'shipping_charge',
- 'tax',
- 'total_amount',
- 'payment_method',
- 'payment_status',
- protected $casts = [
- 'shipping_address_json' => 'array',
- 'billing_address_json'  => 'array',
- ];
- 
- public function customer(): BelongsTo
Added / After Commit
+ protected $fillable = [
+ 'order_number',
+ 'customer_id',
+         'coupon_id',
+         'coupon_code',
+ 'shipping_address_id',
+ 'billing_address_id',
+ 'shipping_address_json',
+ 'discount',
+ 'shipping_charge',
+ 'tax',
+         'tax_breakup_json',
+ 'total_amount',
+ 'payment_method',
+ 'payment_status',
+ protected $casts = [
+ 'shipping_address_json' => 'array',
+ 'billing_address_json'  => 'array',
Removed / Before Commit
- protected $fillable = [
- 'order_id',
- 'product_id',
- 'variant_id',
- 'product_name',
- 'variant_name',
- {
- return $this->belongsTo(Product::class);
- }
- }
Added / After Commit
+ protected $fillable = [
+ 'order_id',
+ 'product_id',
+         'combo_product_id',
+ 'variant_id',
+ 'product_name',
+ 'variant_name',
+ {
+ return $this->belongsTo(Product::class);
+ }
+ 
+     public function comboProduct(): BelongsTo
+     {
+         return $this->belongsTo(ComboProduct::class);
+     }
+ }
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ namespace App\Models;
+ 
+ use Illuminate\Database\Eloquent\Model;
+ 
+ class PaymentSetting extends Model
+ {
+     protected $fillable = [
+         'cod_enabled',
+     ];
+ 
+     protected function casts(): array
+     {
+         return [
+             'cod_enabled' => 'boolean',
+         ];
+     }
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ namespace App\Models;
+ 
+ use Illuminate\Database\Eloquent\Model;
+ use Illuminate\Database\Eloquent\Relations\BelongsTo;
+ 
+ class TaxComponent extends Model
+ {
+     protected $fillable = [
+         'tax_setting_id',
+         'name',
+         'rate_percent',
+         'sort_order',
+     ];
+ 
+     public function taxSetting(): BelongsTo
+     {
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ namespace App\Models;
+ 
+ use Illuminate\Database\Eloquent\Model;
+ use Illuminate\Database\Eloquent\Relations\HasMany;
+ 
+ class TaxSetting extends Model
+ {
+     protected $fillable = [
+         'country_code',
+         'country_name',
+         'is_active',
+     ];
+ 
+     protected function casts(): array
+     {
+         return [
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ namespace App\Services;
+ 
+ use App\Models\Coupon;
+ use Carbon\Carbon;
+ use Illuminate\Support\Str;
+ 
+ class CouponService
+ {
+     /**
+      * @return array{success: bool, message: string, coupon: ?Coupon, discount: float}
+      */
+     public static function validateAndCalculate(?string $couponCode, float $subtotal): array
+     {
+         if (! $couponCode) {
+             return [
+                 'success'  => false,
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ namespace App\Services;
+ 
+ use App\Models\TaxSetting;
+ 
+ class TaxService
+ {
+     public static function activeSetting(): ?TaxSetting
+     {
+         return TaxSetting::with('components')->where('is_active', true)->first();
+     }
+ 
+     /**
+      * @return array{rate_percent: float, tax_amount: float, breakup: array<int, array{name: string, rate_percent: float, amount: float}>}
+      */
+     public static function calculate(float $subtotal): array
+     {
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ use Illuminate\Database\Migrations\Migration;
+ use Illuminate\Database\Schema\Blueprint;
+ use Illuminate\Support\Facades\Schema;
+ 
+ return new class extends Migration
+ {
+     /**
+      * Run the migrations.
+      */
+     public function up(): void
+     {
+         Schema::table('contacts', function (Blueprint $table) {
+             $table->string('service_type')->nullable()->after('phone');
+         });
+     }
+ 
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ use Illuminate\Database\Migrations\Migration;
+ use Illuminate\Database\Schema\Blueprint;
+ use Illuminate\Support\Facades\Schema;
+ 
+ return new class extends Migration
+ {
+     /**
+      * Run the migrations.
+      */
+     public function up(): void
+     {
+         Schema::create('tax_settings', function (Blueprint $table) {
+             $table->id();
+             $table->string('country_code', 5);
+             $table->string('country_name');
+             $table->boolean('is_active')->default(false);
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ use Illuminate\Database\Migrations\Migration;
+ use Illuminate\Database\Schema\Blueprint;
+ use Illuminate\Support\Facades\Schema;
+ 
+ return new class extends Migration
+ {
+     /**
+      * Run the migrations.
+      */
+     public function up(): void
+     {
+         Schema::table('orders', function (Blueprint $table) {
+             $table->longText('tax_breakup_json')->nullable()->after('tax');
+         });
+     }
+ 
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ use Illuminate\Database\Migrations\Migration;
+ use Illuminate\Database\Schema\Blueprint;
+ use Illuminate\Support\Facades\Schema;
+ 
+ return new class extends Migration
+ {
+     /**
+      * Run the migrations.
+      */
+     public function up(): void
+     {
+         Schema::create('tax_components', function (Blueprint $table) {
+             $table->id();
+             $table->foreignId('tax_setting_id')->constrained('tax_settings')->cascadeOnDelete();
+             $table->string('name');
+             $table->decimal('rate_percent', 5, 2);
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ use Illuminate\Database\Migrations\Migration;
+ use Illuminate\Database\Schema\Blueprint;
+ use Illuminate\Support\Facades\Schema;
+ 
+ return new class extends Migration
+ {
+     /**
+      * Run the migrations.
+      */
+     public function up(): void
+     {
+         Schema::create('combo_products', function (Blueprint $table) {
+             $table->id();
+             $table->string('title');
+             $table->string('slug')->unique();
+             $table->text('short_description')->nullable();
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ use Illuminate\Database\Migrations\Migration;
+ use Illuminate\Database\Schema\Blueprint;
+ use Illuminate\Support\Facades\Schema;
+ 
+ return new class extends Migration
+ {
+     /**
+      * Run the migrations.
+      */
+     public function up(): void
+     {
+         Schema::create('combo_product_items', function (Blueprint $table) {
+             $table->id();
+             $table->foreignId('combo_product_id')->constrained('combo_products')->cascadeOnDelete();
+             $table->foreignId('product_id')->constrained('products')->cascadeOnDelete();
+             $table->string('attribute_value')->nullable();
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ use Illuminate\Database\Migrations\Migration;
+ use Illuminate\Database\Schema\Blueprint;
+ use Illuminate\Support\Facades\DB;
+ use Illuminate\Support\Facades\Schema;
+ 
+ return new class extends Migration
+ {
+     /**
+      * Run the migrations.
+      */
+     public function up(): void
+     {
+         DB::statement('ALTER TABLE cart_items MODIFY product_id BIGINT UNSIGNED NULL');
+ 
+         Schema::table('cart_items', function (Blueprint $table) {
+             $table->foreignId('combo_product_id')->nullable()->after('product_id')->constrained('combo_products')->cascadeOnDelete();
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ use Illuminate\Database\Migrations\Migration;
+ use Illuminate\Database\Schema\Blueprint;
+ use Illuminate\Support\Facades\Schema;
+ 
+ return new class extends Migration
+ {
+     /**
+      * Run the migrations.
+      */
+     public function up(): void
+     {
+         Schema::table('order_items', function (Blueprint $table) {
+             $table->foreignId('combo_product_id')->nullable()->after('product_id')->constrained('combo_products')->nullOnDelete();
+         });
+     }
+ 
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ use Illuminate\Database\Migrations\Migration;
+ use Illuminate\Database\Schema\Blueprint;
+ use Illuminate\Support\Facades\Schema;
+ 
+ return new class extends Migration
+ {
+     /**
+      * Run the migrations.
+      */
+     public function up(): void
+     {
+         Schema::create('coupons', function (Blueprint $table) {
+             $table->id();
+             $table->string('code')->unique();
+             $table->string('title')->nullable();
+             $table->enum('discount_type', ['fixed', 'percentage'])->default('fixed');
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ use Illuminate\Database\Migrations\Migration;
+ use Illuminate\Database\Schema\Blueprint;
+ use Illuminate\Support\Facades\Schema;
+ 
+ return new class extends Migration
+ {
+     /**
+      * Run the migrations.
+      */
+     public function up(): void
+     {
+         Schema::table('orders', function (Blueprint $table) {
+             //
+             $table->foreignId('coupon_id')
+                 ->nullable()
+                 ->after('customer_id')
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ use Illuminate\Database\Migrations\Migration;
+ use Illuminate\Database\Schema\Blueprint;
+ use Illuminate\Support\Facades\Schema;
+ 
+ return new class extends Migration
+ {
+     /**
+      * Run the migrations.
+      */
+     public function up(): void
+     {
+         Schema::table('combo_products', function (Blueprint $table) {
+             $table->string('sku')->nullable()->after('slug');
+         });
+     }
+ 
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ use Illuminate\Database\Migrations\Migration;
+ use Illuminate\Database\Schema\Blueprint;
+ use Illuminate\Support\Facades\Schema;
+ 
+ return new class extends Migration
+ {
+     /**
+      * Run the migrations.
+      */
+     public function up(): void
+     {
+         Schema::create('payment_settings', function (Blueprint $table) {
+             $table->id();
+             $table->boolean('cod_enabled')->default(true);
+             $table->timestamps();
+         });
Removed / Before Commit

                                                
Added / After Commit
+ @extends('layouts.app')
+ 
+ @section('title', 'Combo Products | Avriti Dashboard')
+ @section('content')
+ 
+ @php
+   $openModal = old('_modal');
+ @endphp
+ 
+ <div class="mb-6 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
+   <div>
+     <h1 class="text-2xl font-semibold text-[#0b3dba]">Combo Products</h1>
+   </div>
+   <button type="button" data-modal-target="createComboModal" class="inline-flex h-11 items-center justify-center gap-2 rounded-md bg-[#0b3dba] px-5 text-sm font-semibold text-white shadow-sm transition hover:bg-blue-600">
+     <i class="fa-solid fa-plus"></i>
+     Add Combo Product
+   </button>
+ </div>
Removed / Before Commit
- </div>
- </div>
- <div class="overflow-x-auto px-4">
-     <table id="contactsTable" data-action-column="4" class="js-data-table min-w-full border-separate border-spacing-0 text-left text-sm text-gray-600">
- <thead class="bg-[#0b3dba] text-xs uppercase tracking-[0.2em] text-white">
- <tr>
- <th class="px-6 py-4 w-[5%]">No</th>
-           <th class="px-6 py-4 w-[15%]">Name</th>
-           <th class="px-6 py-4 w-[20%]">Email</th>
- <th class="px-6 py-4 w-[10%]">Phone</th>
-           <th class="px-6 py-4 w-[45%]">Message</th>
- <!-- <th class="px-6 py-4">Action</th> -->
- </tr>
- </thead>
- <td class="px-6 py-5 font-semibold text-gray-900">{{ $contact->name }}</td>
- <td class="px-6 py-5 text-gray-500">{{ $contact->email }}</td>
- <td class="px-6 py-5 text-gray-500 ">{{ $contact->phone ?? '—' }}</td>
- <td class="px-6 py-5 text-gray-500 max-w-xs break-all">{{ $contact->message }}</td>
Added / After Commit
+ </div>
+ </div>
+ <div class="overflow-x-auto px-4">
+     <table id="contactsTable" data-action-column="5" class="js-data-table min-w-full border-separate border-spacing-0 text-left text-sm text-gray-600">
+ <thead class="bg-[#0b3dba] text-xs uppercase tracking-[0.2em] text-white">
+ <tr>
+ <th class="px-6 py-4 w-[5%]">No</th>
+           <th class="px-6 py-4 w-[13%]">Name</th>
+           <th class="px-6 py-4 w-[17%]">Email</th>
+ <th class="px-6 py-4 w-[10%]">Phone</th>
+           <th class="px-6 py-4 w-[15%]">Service</th>
+           <th class="px-6 py-4 w-[40%]">Message</th>
+ <!-- <th class="px-6 py-4">Action</th> -->
+ </tr>
+ </thead>
+ <td class="px-6 py-5 font-semibold text-gray-900">{{ $contact->name }}</td>
+ <td class="px-6 py-5 text-gray-500">{{ $contact->email }}</td>
+ <td class="px-6 py-5 text-gray-500 ">{{ $contact->phone ?? '—' }}</td>
Removed / Before Commit

                                                
Added / After Commit
+ @extends('layouts.app')
+ 
+ @section('title', 'Coupons | Avriti Dashboard')
+ @section('content')
+ 
+ @php
+   $openModal = old('_modal');
+ @endphp
+ 
+ <div class="mb-6 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
+   <div>
+     <h1 class="text-2xl font-semibold text-[#0b3dba]">Coupons</h1>
+   </div>
+   <button type="button" data-modal-target="createCouponModal" class="inline-flex h-11 items-center justify-center gap-2 rounded-md bg-[#0b3dba] px-5 text-sm font-semibold text-white shadow-sm transition hover:bg-blue-600">
+     <i class="fa-solid fa-plus"></i>
+     Add Coupon
+   </button>
+ </div>
Removed / Before Commit
- @endif
- 
- {{-- Items --}}
- <div class="rounded-2xl border border-gray-200 overflow-hidden">
- <h3 class="px-4 py-3 text-sm font-semibold text-[#0b3dba] border-b border-gray-200">Items</h3>
- <div class="overflow-x-auto">
- <table class="min-w-full text-left text-sm text-gray-600">
- <thead class="bg-gray-50 text-xs uppercase tracking-[0.1em] text-gray-500">
- <tr>
- <th class="px-4 py-3">Product</th>
-               <th class="px-4 py-3">Variant</th>
- <th class="px-4 py-3">SKU</th>
- <th class="px-4 py-3">Price</th>
- <th class="px-4 py-3">Qty</th>
- <tbody class="divide-y divide-gray-100">
- @foreach ($order->items as $item)
- <tr>
-                 <td class="px-4 py-3">{{ $item->product_name }}</td>
Added / After Commit
+ @endif
+ 
+ {{-- Items --}}
+     @php
+       $hasOnlyComboItems = $order->items->isNotEmpty() && $order->items->every(fn ($i) => $i->combo_product_id);
+       $itemsColumnCount = $hasOnlyComboItems ? 5 : 6;
+     @endphp
+ <div class="rounded-2xl border border-gray-200 overflow-hidden">
+ <h3 class="px-4 py-3 text-sm font-semibold text-[#0b3dba] border-b border-gray-200">Items</h3>
+ <div class="overflow-x-auto">
+ <table class="min-w-full text-left text-sm text-gray-600">
+ <thead class="bg-gray-50 text-xs uppercase tracking-[0.1em] text-gray-500">
+ <tr>
+ <th class="px-4 py-3">Product</th>
+               @unless ($hasOnlyComboItems)
+                 <th class="px-4 py-3">Variant</th>
+               @endunless
+ <th class="px-4 py-3">SKU</th>
Removed / Before Commit

                                                
Added / After Commit
+ @php
+   $itemsList = old('items', $comboProduct?->items->map(fn ($i) => ['product_id' => $i->product_id, 'attribute_value' => $i->attribute_value, 'quantity' => $i->quantity])->toArray() ?? [['product_id' => '', 'attribute_value' => '', 'quantity' => 1]]);
+   $containerId = 'combo-items-' . ($comboProduct?->id ?? 'new');
+   $thumbnails = is_array($comboProduct?->thumbnail) ? array_values(array_filter($comboProduct->thumbnail)) : [];
+   $productOptionsHtml = $products->map(fn ($p) => '<option value="' . $p->id . '">' . e($p->title) . '</option>')->join('');
+   $productAttributesJson = json_encode($productAttributesMap ?? []);
+ @endphp
+ 
+ <div class="max-h-[70vh] space-y-5 overflow-y-auto px-6 py-6">
+   <div class="grid gap-4 sm:grid-cols-2">
+     <div>
+       <label class="mb-1.5 block text-sm font-medium text-gray-700">Combo Title</label>
+       <input type="text" name="title" value="{{ old('title', $comboProduct?->title) }}" placeholder="e.g. Rudraksha + Chain Combo" required class="h-11 w-full rounded-md border border-gray-300 px-4 text-sm focus:border-[#0b3dba] focus:outline-none focus:ring-2 focus:ring-blue-100" />
+       @error('title')
+         <p class="mt-1 text-xs text-red-500">{{ $message }}</p>
+       @enderror
+     </div>
+     <div>
Removed / Before Commit

                                                
Added / After Commit
+ @php
+   $discountType = old('discount_type', $coupon?->discount_type ?? 'percentage');
+ @endphp
+ 
+ <div class="space-y-5 px-6 py-6">
+   <div class="grid gap-4 sm:grid-cols-2">
+     <div>
+       <label class="mb-1.5 block text-sm font-medium text-gray-700">Coupon Code</label>
+       <input type="text" name="code" value="{{ old('code', $coupon?->code) }}" placeholder="e.g. WELCOME10" required class="h-11 w-full rounded-md border border-gray-300 px-4 text-sm uppercase focus:border-[#0b3dba] focus:outline-none focus:ring-2 focus:ring-blue-100" />
+       @error('code')
+         <p class="mt-1 text-xs text-red-500">{{ $message }}</p>
+       @enderror
+     </div>
+     <div>
+       <label class="mb-1.5 block text-sm font-medium text-gray-700">Title (optional)</label>
+       <input type="text" name="title" value="{{ old('title', $coupon?->title) }}" placeholder="e.g. Welcome Offer" class="h-11 w-full rounded-md border border-gray-300 px-4 text-sm focus:border-[#0b3dba] focus:outline-none focus:ring-2 focus:ring-blue-100" />
+     </div>
+   </div>
Removed / Before Commit

                                                
Added / After Commit
+ @php
+   $componentsList = old('components', $taxSetting?->components->map(fn ($c) => ['name' => $c->name, 'rate_percent' => $c->rate_percent])->toArray() ?? [['name' => '', 'rate_percent' => '']]);
+   $containerId = 'components-' . ($taxSetting?->id ?? 'new');
+ @endphp
+ 
+ <div class="space-y-5 px-6 py-6">
+   <div class="grid gap-4 sm:grid-cols-2">
+     <div>
+       <label class="mb-1.5 block text-sm font-medium text-gray-700">Country Name</label>
+       <input type="text" name="country_name" value="{{ old('country_name', $taxSetting?->country_name) }}" placeholder="e.g. India" required class="h-11 w-full rounded-md border border-gray-300 px-4 text-sm focus:border-[#0b3dba] focus:outline-none focus:ring-2 focus:ring-blue-100" />
+       @error('country_name')
+         <p class="mt-1 text-xs text-red-500">{{ $message }}</p>
+       @enderror
+     </div>
+     <div>
+       <label class="mb-1.5 block text-sm font-medium text-gray-700">Country Code</label>
+       <input type="text" name="country_code" value="{{ old('country_code', $taxSetting?->country_code) }}" placeholder="e.g. IN" maxlength="5" required class="h-11 w-full rounded-md border border-gray-300 px-4 text-sm uppercase focus:border-[#0b3dba] focus:outline-none focus:ring-2 focus:ring-blue-100" />
+       @error('country_code')
Removed / Before Commit

                                                
Added / After Commit
+ @extends('layouts.app')
+ 
+ @section('title', 'Payment Methods | Avriti Dashboard')
+ @section('content')
+ 
+ <div class="mb-6 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
+   <div>
+     <h1 class="text-2xl font-semibold text-[#0b3dba]">Payment Methods</h1>
+   </div>
+ </div>
+ 
+ @if (session('success'))
+   <div data-auto-hide-alert class="mb-6 rounded-2xl border border-emerald-200 bg-emerald-50 px-4 py-3 text-sm font-semibold text-emerald-700 transition-opacity duration-500">
+     {{ session('success') }}
+   </div>
+ @endif
+ 
+ <div class="overflow-hidden rounded-[32px] bg-white shadow-sm">
Removed / Before Commit

                                                
Added / After Commit
+ @extends('layouts.app')
+ 
+ @section('title', 'Tax Settings | Avriti Dashboard')
+ @section('content')
+ 
+ @php
+   $openModal = old('_modal');
+ @endphp
+ 
+ <div class="mb-6 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
+   <div>
+     <h1 class="text-2xl font-semibold text-[#0b3dba]">Tax Settings</h1>
+   </div>
+   <button type="button" data-modal-target="createTaxModal" class="inline-flex h-11 items-center justify-center gap-2 rounded-md bg-[#0b3dba] px-5 text-sm font-semibold text-white shadow-sm transition hover:bg-blue-600">
+     <i class="fa-solid fa-plus"></i>
+     Add Country Tax
+   </button>
+ </div>
Removed / Before Commit
- <td style="padding:15px 18px;border-bottom:1px solid #eeeeee;color:#111827;font-size:14px;">{{ $contact->email }}</td>
- </tr>
- <tr>
-             <td style="padding:15px 18px;color:#7a7a7a;font-size:13px;">Phone</td>
-             <td style="padding:15px 18px;color:#111827;font-size:14px;">{{ $contact->phone ?: '-' }}</td>
- </tr>
- </table>
Added / After Commit
+ <td style="padding:15px 18px;border-bottom:1px solid #eeeeee;color:#111827;font-size:14px;">{{ $contact->email }}</td>
+ </tr>
+ <tr>
+             <td style="padding:15px 18px;border-bottom:1px solid #eeeeee;color:#7a7a7a;font-size:13px;">Phone</td>
+             <td style="padding:15px 18px;border-bottom:1px solid #eeeeee;color:#111827;font-size:14px;">{{ $contact->phone ?: '-' }}</td>
+           </tr>
+           <tr>
+             <td style="padding:15px 18px;color:#7a7a7a;font-size:13px;">Service</td>
+             <td style="padding:15px 18px;color:#111827;font-size:14px;">{{ $contact->service_type ?: '-' }}</td>
+ </tr>
+ </table>
Removed / Before Commit
- <td style="padding:13px 16px;border-bottom:1px solid #eeeeee;color:#111827;font-size:13px;">{{ $contact->email }}</td>
- </tr>
- <tr>
-             <td style="padding:13px 16px;color:#7a7a7a;font-size:13px;">Phone</td>
-             <td style="padding:13px 16px;color:#111827;font-size:13px;">{{ $contact->phone ?: '-' }}</td>
- </tr>
- </table>
- </td>
Added / After Commit
+ <td style="padding:13px 16px;border-bottom:1px solid #eeeeee;color:#111827;font-size:13px;">{{ $contact->email }}</td>
+ </tr>
+ <tr>
+             <td style="padding:13px 16px;border-bottom:1px solid #eeeeee;color:#7a7a7a;font-size:13px;">Phone</td>
+             <td style="padding:13px 16px;border-bottom:1px solid #eeeeee;color:#111827;font-size:13px;">{{ $contact->phone ?: '-' }}</td>
+           </tr>
+           <tr>
+             <td style="padding:13px 16px;color:#7a7a7a;font-size:13px;">Service</td>
+             <td style="padding:13px 16px;color:#111827;font-size:13px;">{{ $contact->service_type ?: '-' }}</td>
+ </tr>
+ </table>
+ </td>
Removed / Before Commit
- Orders
- </a>
- 
- <!-- <a href="{{ route('return-refund.index') }}" class="flex items-center gap-3 px-3 py-2.5 rounded-xl {{ request()->routeIs('return-refund.*') ? $activeClass : $inactiveClass }}">
- <i class="fa-solid fa-arrow-rotate-left"></i>
- Returns & Refunds
- </a> -->
- 
- {{-- Products Group --}}
-     @php $productsOpen = request()->routeIs('product-categories.*', 'product-types.*', 'variants.*', 'products.*'); @endphp
- <div>
- <button type="button" id="productsToggle"
- class="w-full flex items-center justify-between px-3 py-2.5 rounded-xl text-white/70 hover:bg-white/10 hover:text-white transition">
- <i class="fa-solid fa-box-open"></i>
- Products
- </a>
- </div>
- </div>
Added / After Commit
+ Orders
+ </a>
+ 
+     <a href="{{ route('tax-settings.index') }}" class="flex items-center gap-3 px-3 py-2.5 rounded-xl {{ request()->routeIs('tax-settings.*') ? $activeClass : $inactiveClass }}">
+       <i class="fa-solid fa-percent"></i>
+       Tax Settings
+     </a>
+ 
+     <a href="{{ route('coupons.index') }}" class="flex items-center gap-3 px-3 py-2.5 rounded-xl {{ request()->routeIs('coupons.*') ? $activeClass : $inactiveClass }}">
+       <i class="fa-solid fa-ticket"></i>
+       Coupons
+     </a>
+ 
+     <a href="{{ route('payment-settings.index') }}" class="flex items-center gap-3 px-3 py-2.5 rounded-xl {{ request()->routeIs('payment-settings.*') ? $activeClass : $inactiveClass }}">
+       <i class="fa-solid fa-credit-card"></i>
+       Payment Methods
+     </a>
+ 
Removed / Before Commit
- <?php
- 
- use App\Http\Controllers\AuthController;
- use App\Http\Controllers\Api\CartController;
- use App\Http\Controllers\Api\CustomerAuthController;
- use App\Http\Controllers\Api\WishlistController;
- use App\Http\Controllers\Api\CustomerProfileController;
- use App\Http\Controllers\Api\RazorpayController;
- use App\Http\Middleware\CheckCustomerActive;
- 
- Route::post('/register', [AuthController::class, 'apiRegister'])->name('api.register');
- Route::get('/faqs', [FaqController::class, 'index']);
- Route::get('/home', [HomeController::class, 'index']);
- Route::get('/services', [ServiceController::class, 'index']);
- Route::post('/contact', [ContactController::class, 'store']);
- 
- Route::prefix('customer')->group(function () {
- Route::post('/register', [CustomerAuthController::class, 'register']);
Added / After Commit
+ <?php
+ use App\Http\Controllers\Api\CouponController;
+ use App\Http\Controllers\AuthController;
+ use App\Http\Controllers\Api\CartController;
+ use App\Http\Controllers\Api\CustomerAuthController;
+ use App\Http\Controllers\Api\WishlistController;
+ use App\Http\Controllers\Api\CustomerProfileController;
+ use App\Http\Controllers\Api\RazorpayController;
+ use App\Http\Controllers\Api\TaxController;
+ use App\Http\Controllers\Api\ComboProductController;
+ use App\Http\Controllers\Api\PaymentSettingController;
+ use App\Http\Middleware\CheckCustomerActive;
+ 
+ Route::post('/register', [AuthController::class, 'apiRegister'])->name('api.register');
+ Route::get('/faqs', [FaqController::class, 'index']);
+ Route::get('/home', [HomeController::class, 'index']);
+ Route::get('/services', [ServiceController::class, 'index']);
+ Route::get('/combo-products', [ComboProductController::class, 'index']);
Removed / Before Commit
- use App\Http\Controllers\AdminCustomerController;
- use App\Http\Controllers\AdminDashboardController;
- use App\Http\Controllers\AdminOrderController;
- use Illuminate\Support\Facades\Route;
- 
- Route::get('/', function () {
- Route::post('/variants', [AdminVariantController::class, 'store'])->name('variants.store');
- Route::put('/variants/{variant}', [AdminVariantController::class, 'update'])->name('variants.update');
- Route::delete('/variants/{variant}', [AdminVariantController::class, 'destroy'])->name('variants.destroy');
- Route::get('/home-page', [AdminHomeController::class, 'index'])->name('home-page.index');
- Route::put('/home-page', [AdminHomeController::class, 'update'])->name('home-page.update');
- Route::get('/faq', [AdminFaqController::class, 'index'])->name('faq.index');
- Route::delete('/contacts/{contact}', [AdminContactController::class, 'destroy'])->name('contacts.destroy');
- Route::get('/service-page', [AdminServiceController::class, 'index'])->name('service-page.index');
- Route::put('/service-page', [AdminServiceController::class, 'update'])->name('service-page.update');
- Route::post('/logout', [AuthController::class, 'logout'])->name('logout');
- });
Added / After Commit
+ use App\Http\Controllers\AdminCustomerController;
+ use App\Http\Controllers\AdminDashboardController;
+ use App\Http\Controllers\AdminOrderController;
+ use App\Http\Controllers\AdminTaxSettingController;
+ use App\Http\Controllers\AdminComboProductController;
+ use App\Http\Controllers\AdminCouponController;
+ use App\Http\Controllers\AdminPaymentSettingController;
+ use Illuminate\Support\Facades\Route;
+ 
+ Route::get('/', function () {
+ Route::post('/variants', [AdminVariantController::class, 'store'])->name('variants.store');
+ Route::put('/variants/{variant}', [AdminVariantController::class, 'update'])->name('variants.update');
+ Route::delete('/variants/{variant}', [AdminVariantController::class, 'destroy'])->name('variants.destroy');
+     Route::get('/combo-products', [AdminComboProductController::class, 'index'])->name('combo-products.index');
+     Route::post('/combo-products', [AdminComboProductController::class, 'store'])->name('combo-products.store');
+     Route::put('/combo-products/{comboProduct}', [AdminComboProductController::class, 'update'])->name('combo-products.update');
+     Route::delete('/combo-products/{comboProduct}', [AdminComboProductController::class, 'destroy'])->name('combo-products.destroy');
+ Route::get('/home-page', [AdminHomeController::class, 'index'])->name('home-page.index');