mirror of
				https://github.com/crater-invoice/crater.git
				synced 2025-10-29 20:51:09 -04:00 
			
		
		
		
	Compare commits
	
		
			114 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 2e5cb58c39 | |||
| db622e7458 | |||
| 09bbf98e61 | |||
| ca90ff2767 | |||
| 368dd16c9b | |||
| 251648f53c | |||
| ffa5b6b2ad | |||
| bd9beaa343 | |||
| 3e4decdfb9 | |||
| 165907d144 | |||
| 6278417423 | |||
| dc37f565c4 | |||
| 532196a9b4 | |||
| 6a4009e13a | |||
| a8f98e51bb | |||
| 2b03bc798e | |||
| 482556d378 | |||
| deb525af6e | |||
| cb2bfbb91c | |||
| 654395a175 | |||
| e31b60bc48 | |||
| 183953f4c4 | |||
| 98d15143c2 | |||
| a24d8d3ebc | |||
| 4ca574c581 | |||
| c7ce8c87dd | |||
| f64d546672 | |||
| 96187870b4 | |||
| d4a1f1a784 | |||
| e07532961e | |||
| 450c265ded | |||
| f8502c3ca8 | |||
| 899da6990d | |||
| e7675f938e | |||
| b08138e9e0 | |||
| 5df4abdc4b | |||
| a2fa8afa72 | |||
| 7670cd67dc | |||
| 8446ac2b27 | |||
| 63a80e44d5 | |||
| 076df75322 | |||
| 11db99da73 | |||
| 050dca5a50 | |||
| 3c096f1386 | |||
| 0f3e8fce3b | |||
| 325f90bba5 | |||
| a739a938fc | |||
| b30e3a9b11 | |||
| fc1a7c7438 | |||
| 6046113cb1 | |||
| 611ffafec5 | |||
| c497b906df | |||
| c68fce19f9 | |||
| f8913531b6 | |||
| 30f76e2088 | |||
| 39556892cd | |||
| 2fd66bf748 | |||
| d4f1428d5f | |||
| 189141c84d | |||
| f8ccfece09 | |||
| 9a7c926d53 | |||
| c5c1674153 | |||
| 8562ee5414 | |||
| 06c66a756c | |||
| b66d07d21b | |||
| 05001b6a79 | |||
| f02f4ba9d3 | |||
| fbace98aac | |||
| 8f0af3dcd6 | |||
| e8e44c5dc8 | |||
| ac33164342 | |||
| 5c7c0d84ea | |||
| 7ca725ac37 | |||
| 510a4b3dbb | |||
| 0f130ab1b8 | |||
| 25114009e3 | |||
| 79c16d74ce | |||
| 742e1e445a | |||
| 386f96d60e | |||
| 82d85af672 | |||
| 4d1b267688 | |||
| bc99ad63a6 | |||
| 4bb44f8c93 | |||
| c72265ed50 | |||
| b8958c9eb6 | |||
| e33e314cb7 | |||
| 84cebee9da | |||
| 34d3cf7ae8 | |||
| 93d0da836a | |||
| fd51276948 | |||
| d6274854ba | |||
| ea4bd1a31d | |||
| 286e047963 | |||
| be16f48f3d | |||
| ebea1e0813 | |||
| cc8d08f829 | |||
| aacffc22eb | |||
| d71ca4ffb9 | |||
| 186004f7f8 | |||
| c2eb22d666 | |||
| af189b15b6 | |||
| 1c19be85c3 | |||
| 4bb4362d23 | |||
| f6f66b3ae6 | |||
| b4ccecbcf1 | |||
| 92f1f196bb | |||
| ee14070a7b | |||
| 8ce7e14a02 | |||
| 3401ca049e | |||
| 5dcc7b9efd | |||
| 406d098172 | |||
| f68e86e4cf | |||
| 0990ce4678 | |||
| 353c2479f1 | 
							
								
								
									
										12
									
								
								.eslintrc
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								.eslintrc
									
									
									
									
									
								
							| @ -2,9 +2,17 @@ | ||||
|   "root": true, | ||||
|   "extends": [ | ||||
|     "plugin:vue/recommended", | ||||
|     "standard" | ||||
|     "eslint:recommended", | ||||
|     "prettier/vue", | ||||
|     "plugin:prettier/recommended" | ||||
|   ], | ||||
|   "rules": { | ||||
|     "vue/max-attributes-per-line" : 3 | ||||
|     "vue/max-attributes-per-line": ["error", { | ||||
|       "singleline": 10, | ||||
|       "multiline": { | ||||
|         "max": 1, | ||||
|         "allowFirstLine": false | ||||
|       } | ||||
|     }]     | ||||
|   } | ||||
| } | ||||
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -11,5 +11,3 @@ Homestead.yaml | ||||
| .rnd | ||||
| /.expo | ||||
| /.vscode | ||||
| docker-compose.yml | ||||
| docker-compose.yaml | ||||
|  | ||||
							
								
								
									
										5
									
								
								.prettierrc.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								.prettierrc.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| { | ||||
|   "semi": false, | ||||
|   "singleQuote": true, | ||||
|   "tabWidth": 2 | ||||
| } | ||||
							
								
								
									
										73
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										73
									
								
								Dockerfile
									
									
									
									
									
								
							| @ -1,52 +1,39 @@ | ||||
| ##### STAGE 1 ##### | ||||
| FROM php:7.4-fpm | ||||
|  | ||||
| FROM composer as composer | ||||
| # Arguments defined in docker-compose.yml | ||||
| ARG user | ||||
| ARG uid | ||||
|  | ||||
| # Copy composer files from project root into composer container's working dir | ||||
| COPY composer.* /app/ | ||||
| # Install system dependencies | ||||
| RUN apt-get update && apt-get install -y \ | ||||
|     git \ | ||||
|     curl \ | ||||
|     libpng-dev \ | ||||
|     libonig-dev \ | ||||
|     libxml2-dev \ | ||||
|     zip \ | ||||
|     unzip \  | ||||
|     libzip-dev \  | ||||
|     libmagickwand-dev | ||||
|  | ||||
| # Copy database directory for autoloader optimization | ||||
| COPY database /app/database | ||||
| # Clear cache | ||||
| RUN apt-get clean && rm -rf /var/lib/apt/lists/* | ||||
|  | ||||
| # Run composer to build dependencies in vendor folder | ||||
| RUN composer install --no-scripts --no-suggest --no-interaction --prefer-dist --optimize-autoloader  | ||||
| RUN pecl install imagick \  | ||||
|     && docker-php-ext-enable imagick | ||||
|  | ||||
| # Copy everything from project root into composer container's working dir | ||||
| COPY . /app | ||||
|   | ||||
| RUN composer dump-autoload --optimize --classmap-authoritative | ||||
| # Install PHP extensions | ||||
| RUN docker-php-ext-install pdo_mysql mbstring zip exif pcntl bcmath gd  | ||||
|  | ||||
| ##### STAGE 2 ##### | ||||
| # Get latest Composer | ||||
| COPY --from=composer:latest /usr/bin/composer /usr/bin/composer | ||||
|  | ||||
| FROM php:7.3.12-fpm-alpine | ||||
| # Create system user to run Composer and Artisan Commands | ||||
| RUN useradd -G www-data,root -u $uid -d /home/$user $user | ||||
| RUN mkdir -p /home/$user/.composer && \ | ||||
|     chown -R $user:$user /home/$user | ||||
|  | ||||
| # Use the default production configuration | ||||
| RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" | ||||
|  | ||||
| RUN apk add --no-cache libpng-dev libxml2-dev oniguruma-dev libzip-dev && \ | ||||
|     docker-php-ext-install bcmath ctype json gd mbstring pdo pdo_mysql tokenizer xml zip | ||||
|  | ||||
| # Set container's working dir | ||||
| WORKDIR /app | ||||
|   | ||||
| # Copy everything from project root into php container's working dir | ||||
| COPY . /app | ||||
|  | ||||
| # Copy vendor folder from composer container into php container | ||||
| COPY --from=composer /app/vendor /app/vendor | ||||
|  | ||||
| RUN touch database/database.sqlite && \ | ||||
|     cp .env.example .env && \ | ||||
|     php artisan config:cache && \ | ||||
|     php artisan passport:keys && \ | ||||
|     php artisan key:generate && \ | ||||
|     chown -R www-data:www-data . && \ | ||||
|     chmod -R 755 . && \ | ||||
|     chmod -R 775 storage/framework/ && \ | ||||
|     chmod -R 775 storage/logs/ && \ | ||||
|     chmod -R 775 bootstrap/cache/   | ||||
|  | ||||
| EXPOSE 9000 | ||||
|  | ||||
| CMD ["php-fpm", "--nodaemonize"] | ||||
| # Set working directory | ||||
| WORKDIR /var/www | ||||
|  | ||||
| USER $user | ||||
|  | ||||
							
								
								
									
										190
									
								
								app/Console/Commands/UpdateCommand.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										190
									
								
								app/Console/Commands/UpdateCommand.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,190 @@ | ||||
| <?php | ||||
|  | ||||
| namespace Crater\Console\Commands; | ||||
|  | ||||
| use Illuminate\Console\Command; | ||||
| use Crater\Space\Updater; | ||||
| use Crater\Setting; | ||||
|  | ||||
| // Implementation taken from Akaunting - https://github.com/akaunting/akaunting | ||||
| class UpdateCommand extends Command | ||||
| { | ||||
|     public $installed; | ||||
|  | ||||
|     public $version; | ||||
|  | ||||
|     /** | ||||
|      * The name and signature of the console command. | ||||
|      * | ||||
|      * @var string | ||||
|      */ | ||||
|     protected $signature = 'crater:update'; | ||||
|  | ||||
|     /** | ||||
|      * The console command description. | ||||
|      * | ||||
|      * @var string | ||||
|      */ | ||||
|     protected $description = 'Automatically update your crater app'; | ||||
|  | ||||
|     /** | ||||
|      * Create a new command instance. | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Execute the console command. | ||||
|      */ | ||||
|     public function handle() | ||||
|     { | ||||
|         set_time_limit(3600); // 1 hour | ||||
|  | ||||
|         $this->installed = $this->getInstalledVersion(); | ||||
|         $this->version = $this->getLatestVersion(); | ||||
|  | ||||
|         if (!$this->version) { | ||||
|             $this->info('No Update Available! You are already on the latest version.'); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (!$this->confirm("Do you wish to update to {$this->version}?")) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (!$path = $this->download()) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (!$path = $this->unzip($path)) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (!$this->copyFiles($path)) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (!$this->migrateUpdate()) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (!$this->finish()) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         $this->info('Successfully updated to ' . $this->version); | ||||
|     } | ||||
|  | ||||
|     public function getInstalledVersion() | ||||
|     { | ||||
|         return Setting::getSetting('version'); | ||||
|     } | ||||
|  | ||||
|     public function getLatestVersion() | ||||
|     { | ||||
|         $this->info('Your currently installed version is ' . $this->installed); | ||||
|         $this->line(''); | ||||
|         $this->info('Checking for update...'); | ||||
|  | ||||
|         try { | ||||
|             $response = Updater::checkForUpdate($this->installed); | ||||
|  | ||||
|             if ($response->success) { | ||||
|                 return $response->version->version; | ||||
|             } | ||||
|  | ||||
|             return false; | ||||
|         } catch (\Exception $e) { | ||||
|             $this->error($e->getMessage()); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public function download() | ||||
|     { | ||||
|         $this->info('Downloading update...'); | ||||
|  | ||||
|         try { | ||||
|             $path = Updater::download($this->version); | ||||
|             if (!is_string($path)) { | ||||
|                 $this->error('Download exception'); | ||||
|                 return false; | ||||
|             } | ||||
|         } catch (\Exception $e) { | ||||
|             $this->error($e->getMessage()); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return $path; | ||||
|     } | ||||
|  | ||||
|     public function unzip($path) | ||||
|     { | ||||
|         $this->info('Unzipping update package...'); | ||||
|  | ||||
|         try { | ||||
|             $path = Updater::unzip($path); | ||||
|             if (!is_string($path)) { | ||||
|                 $this->error('Unzipping exception'); | ||||
|                 return false; | ||||
|             } | ||||
|         } catch (\Exception $e) { | ||||
|             $this->error($e->getMessage()); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return $path; | ||||
|     } | ||||
|  | ||||
|     public function copyFiles($path) | ||||
|     { | ||||
|         $this->info('Copying update files...'); | ||||
|  | ||||
|         try { | ||||
|             Updater::copyFiles($path); | ||||
|         } catch (\Exception $e) { | ||||
|             $this->error($e->getMessage()); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     public function migrateUpdate() | ||||
|     { | ||||
|         $this->info('Running Migrations...'); | ||||
|  | ||||
|         try { | ||||
|             Updater::migrateUpdate(); | ||||
|         } catch (\Exception $e) { | ||||
|             $this->error($e->getMessage()); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     public function finish() | ||||
|     { | ||||
|         $this->info('Finishing update...'); | ||||
|  | ||||
|         try { | ||||
|             Updater::finishUpdate($this->installed, $this->version); | ||||
|         } catch (\Exception $e) { | ||||
|             $this->error($e->getMessage()); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
| } | ||||
| @ -12,7 +12,8 @@ class Kernel extends ConsoleKernel | ||||
|      * @var array | ||||
|      */ | ||||
|     protected $commands = [ | ||||
|         Commands\ResetApp::class | ||||
|         Commands\ResetApp::class, | ||||
|         Commands\UpdateCommand::class | ||||
|     ]; | ||||
|  | ||||
|     /** | ||||
|  | ||||
| @ -25,7 +25,7 @@ class UpdateFinished | ||||
|      */ | ||||
|     public function __construct($old, $new) | ||||
|     { | ||||
|         $this->old   = $old; | ||||
|         $this->new   = $new; | ||||
|         $this->old = $old; | ||||
|         $this->new = $new; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -5,6 +5,7 @@ use Illuminate\Database\Eloquent\Model; | ||||
| use Spatie\MediaLibrary\HasMedia\HasMedia; | ||||
| use Spatie\MediaLibrary\HasMedia\HasMediaTrait; | ||||
| use Crater\ExpenseCategory; | ||||
| use Crater\User; | ||||
| use Carbon\Carbon; | ||||
| use Illuminate\Support\Facades\DB; | ||||
|  | ||||
| @ -16,6 +17,7 @@ class Expense extends Model implements HasMedia | ||||
|         'expense_category_id', | ||||
|         'amount', | ||||
|         'company_id', | ||||
|         'user_id', | ||||
|         'expense_date', | ||||
|         'notes', | ||||
|         'attachment_receipt' | ||||
| @ -32,6 +34,11 @@ class Expense extends Model implements HasMedia | ||||
|         return $this->belongsTo(ExpenseCategory::class, 'expense_category_id'); | ||||
|     } | ||||
|  | ||||
|     public function user() | ||||
|     { | ||||
|         return $this->belongsTo(User::class); | ||||
|     } | ||||
|  | ||||
|     public function getFormattedExpenseDateAttribute($value) | ||||
|     { | ||||
|         $dateFormat = CompanySetting::getSetting('carbon_date_format', $this->company_id); | ||||
| @ -81,6 +88,11 @@ class Expense extends Model implements HasMedia | ||||
|         return $query->where('expenses.expense_category_id', $categoryId); | ||||
|     } | ||||
|  | ||||
|     public function scopeWhereUser($query, $user_id) | ||||
|     { | ||||
|         return $query->where('expenses.user_id', $user_id); | ||||
|     } | ||||
|  | ||||
|     public function scopeApplyFilters($query, array $filters) | ||||
|     { | ||||
|         $filters = collect($filters); | ||||
| @ -89,6 +101,10 @@ class Expense extends Model implements HasMedia | ||||
|             $query->whereCategory($filters->get('expense_category_id')); | ||||
|         } | ||||
|  | ||||
|         if ($filters->get('user_id')) { | ||||
|             $query->whereUser($filters->get('user_id')); | ||||
|         } | ||||
|  | ||||
|         if ($filters->get('from_date') && $filters->get('to_date')) { | ||||
|             $start = Carbon::createFromFormat('d/m/Y', $filters->get('from_date')); | ||||
|             $end = Carbon::createFromFormat('d/m/Y', $filters->get('to_date')); | ||||
|  | ||||
| @ -143,13 +143,14 @@ class CompanyController extends Controller | ||||
|         $currency = CompanySetting::getSetting('currency', $request->header('company')); | ||||
|         $fiscal_year = CompanySetting::getSetting('fiscal_year', $request->header('company')); | ||||
|  | ||||
|         $languages = [ | ||||
|         $languages = [  // alphabetical order | ||||
|             ["code"=>"pt_BR", "name" => "Brazilian Portuguese"], | ||||
|             ["code"=>"en", "name" => "English"], | ||||
|             ["code"=>"fr", "name" => "French"], | ||||
|             ["code"=>"de", "name" => "German"], | ||||
|             ["code"=>"it", "name" => "Italian"], | ||||
|             ["code"=>"es", "name" => "Spanish"], | ||||
|             ["code"=>"ar", "name" => "العربية"], | ||||
|             ["code"=>"de", "name" => "German"], | ||||
|             ["code"=>"pt_BR", "name" => "Brazilian Portuguese"], | ||||
|         ]; | ||||
|  | ||||
|         return response()->json([ | ||||
|  | ||||
| @ -175,12 +175,6 @@ class EstimatesController extends Controller | ||||
|                 ]); | ||||
|             } | ||||
|  | ||||
|             if (!config('mail.from.name')) { | ||||
|                 return response()->json([ | ||||
|                     'error' => 'from_email_does_not_exist' | ||||
|                 ]); | ||||
|             } | ||||
|  | ||||
|             \Mail::to($email)->send(new EstimatePdf($data)); | ||||
|         } | ||||
|  | ||||
| @ -343,12 +337,6 @@ class EstimatesController extends Controller | ||||
|             ]); | ||||
|         } | ||||
|  | ||||
|         if (!config('mail.from.name')) { | ||||
|             return response()->json([ | ||||
|                 'error' => 'from_email_does_not_exist' | ||||
|             ]); | ||||
|         } | ||||
|  | ||||
|         \Mail::to($email)->send(new EstimatePdf($data)); | ||||
|  | ||||
|         if ($estimate->status == Estimate::STATUS_DRAFT) { | ||||
| @ -397,12 +385,12 @@ class EstimatesController extends Controller | ||||
|     public function estimateToInvoice(Request $request, $id) | ||||
|     { | ||||
|         $estimate = Estimate::with(['items', 'items.taxes', 'user', 'estimateTemplate', 'taxes'])->find($id); | ||||
|         $invoice_date = Carbon::parse($estimate->estimate_date); | ||||
|         $invoice_date = Carbon::now(); | ||||
|         $invoice_prefix = CompanySetting::getSetting( | ||||
|             'invoice_prefix', | ||||
|             $request->header('company') | ||||
|         ); | ||||
|         $due_date = Carbon::parse($estimate->estimate_date)->addDays(7); | ||||
|         $due_date = Carbon::now()->addDays(7); | ||||
|         $tax_per_item = CompanySetting::getSetting( | ||||
|                 'tax_per_item', | ||||
|                 $request->header('company') | ||||
|  | ||||
| @ -1,4 +1,5 @@ | ||||
| <?php | ||||
|  | ||||
| namespace Crater\Http\Controllers; | ||||
|  | ||||
| use Crater\Expense; | ||||
| @ -24,9 +25,11 @@ class ExpensesController extends Controller | ||||
|         $limit = $request->has('limit') ? $request->limit : 10; | ||||
|  | ||||
|         $expenses = Expense::with('category') | ||||
|             ->leftJoin('users', 'users.id', '=', 'expenses.user_id') | ||||
|             ->join('expense_categories', 'expense_categories.id', '=', 'expenses.expense_category_id') | ||||
|             ->applyFilters($request->only([ | ||||
|                 'expense_category_id', | ||||
|                 'user_id', | ||||
|                 'search', | ||||
|                 'from_date', | ||||
|                 'to_date', | ||||
| @ -34,11 +37,16 @@ class ExpensesController extends Controller | ||||
|                 'orderBy' | ||||
|             ])) | ||||
|             ->whereCompany($request->header('company')) | ||||
|             ->select('expenses.*', 'expense_categories.name') | ||||
|             ->select('expenses.*', 'expense_categories.name', 'users.name as user_name') | ||||
|             ->paginate($limit); | ||||
|  | ||||
|         $customers = User::customer() | ||||
|             ->whereCompany($request->header('company')) | ||||
|             ->get(); | ||||
|  | ||||
|         return response()->json([ | ||||
|             'expenses' => $expenses, | ||||
|             'customers' => $customers, | ||||
|             'currency' => Currency::findOrFail( | ||||
|                 CompanySetting::getSetting('currency', $request->header('company')) | ||||
|             ) | ||||
| @ -53,9 +61,13 @@ class ExpensesController extends Controller | ||||
|     public function create(Request $request) | ||||
|     { | ||||
|         $categories = ExpenseCategory::whereCompany($request->header('company'))->get(); | ||||
|         $customers = User::customer() | ||||
|             ->whereCompany($request->header('company')) | ||||
|             ->get(); | ||||
|  | ||||
|         return response()->json([ | ||||
|             'categories' => $categories | ||||
|             'categories' => $categories, | ||||
|             'customers' => $customers | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
| @ -72,6 +84,7 @@ class ExpensesController extends Controller | ||||
|         $expense = new Expense(); | ||||
|         $expense->notes = $request->notes; | ||||
|         $expense->expense_category_id = $request->expense_category_id; | ||||
|         $expense->user_id = $request->user_id; | ||||
|         $expense->amount = $request->amount; | ||||
|         $expense->company_id = $request->header('company'); | ||||
|         $expense->expense_date = $expense_date; | ||||
| @ -104,10 +117,12 @@ class ExpensesController extends Controller | ||||
|      * @param  $id | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function edit(Request $request,$id) | ||||
|     public function edit(Request $request, $id) | ||||
|     { | ||||
|         $categories = ExpenseCategory::whereCompany($request->header('company'))->get(); | ||||
|         $customers = User::where('role', 'customer')->whereCompany($request->header('company'))->get(); | ||||
|         $customers = User::customer() | ||||
|             ->whereCompany($request->header('company')) | ||||
|             ->get(); | ||||
|         $expense = Expense::with('category')->where('id', $id)->first(); | ||||
|  | ||||
|         return response()->json([ | ||||
| @ -132,6 +147,7 @@ class ExpensesController extends Controller | ||||
|         $expense->notes = $request->notes; | ||||
|         $expense->expense_category_id = $request->expense_category_id; | ||||
|         $expense->amount = $request->amount; | ||||
|         $expense->user_id = $request->user_id; | ||||
|         $expense->expense_date = $expense_date; | ||||
|         $expense->save(); | ||||
|  | ||||
| @ -181,11 +197,11 @@ class ExpensesController extends Controller | ||||
|     { | ||||
|         $data = json_decode($request->attachment_receipt); | ||||
|  | ||||
|         if($data) { | ||||
|         if ($data) { | ||||
|             $expense = Expense::find($id); | ||||
|  | ||||
|             if($expense) { | ||||
|                 if($request->type === 'edit') { | ||||
|             if ($expense) { | ||||
|                 if ($request->type === 'edit') { | ||||
|                     $expense->clearMediaCollection('receipts'); | ||||
|                 } | ||||
|  | ||||
| @ -205,15 +221,15 @@ class ExpensesController extends Controller | ||||
|      * Retrive details of an expense receipt from storage. | ||||
|      * @param   int $id | ||||
|      * @return  \Illuminate\Http\JsonResponse | ||||
|      */  | ||||
|      */ | ||||
|     public function showReceipt($id) | ||||
|     { | ||||
|         $expense = Expense::find($id); | ||||
|         $imagePath  = null; | ||||
|  | ||||
|         if($expense) { | ||||
|         if ($expense) { | ||||
|             $media = $expense->getFirstMedia('receipts'); | ||||
|             if($media) { | ||||
|             if ($media) { | ||||
|                 $imagePath = $media->getPath(); | ||||
|             } else { | ||||
|                 return response()->json([ | ||||
| @ -224,7 +240,7 @@ class ExpensesController extends Controller | ||||
|  | ||||
|         $type = \File::mimeType($imagePath); | ||||
|  | ||||
|         $image = 'data:'.$type.';base64,'.base64_encode(file_get_contents($imagePath)); | ||||
|         $image = 'data:' . $type . ';base64,' . base64_encode(file_get_contents($imagePath)); | ||||
|  | ||||
|         return response()->json([ | ||||
|             'image' => $image, | ||||
| @ -239,7 +255,7 @@ class ExpensesController extends Controller | ||||
|      * @param   int $id | ||||
|      * @param   strig $hash | ||||
|      * @return  \Symfony\Component\HttpFoundation\BinaryFileResponse | \Illuminate\Http\JsonResponse | ||||
|      */     | ||||
|      */ | ||||
|     public function downloadReceipt($id, $hash) | ||||
|     { | ||||
|         $company = Company::where('unique_hash', $hash)->first(); | ||||
| @ -249,17 +265,10 @@ class ExpensesController extends Controller | ||||
|             ->first(); | ||||
|         $imagePath  = null; | ||||
|  | ||||
|         if($expense) { | ||||
|         if ($expense) { | ||||
|             $media = $expense->getFirstMedia('receipts'); | ||||
|             if($media) { | ||||
|             if ($media) { | ||||
|                 $imagePath = $media->getPath(); | ||||
|                 $filename = $media->getPath(); | ||||
|                 $type = \File::mimeType($imagePath); | ||||
|  | ||||
|                 $headers = array( | ||||
|                     'Content-Type' => $type, | ||||
|                 ); | ||||
|  | ||||
|                 $response = \Response::download($imagePath, $media->file_name); | ||||
|                 ob_end_clean(); | ||||
|                 return $response; | ||||
| @ -271,4 +280,3 @@ class ExpensesController extends Controller | ||||
|         ]); | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -12,7 +12,7 @@ use Crater\Invoice; | ||||
| use Crater\InvoiceItem; | ||||
| use Carbon\Carbon; | ||||
| use Crater\Item; | ||||
| use Crater\Mail\invoicePdf; | ||||
| use Crater\Mail\InvoicePdf; | ||||
| use function MongoDB\BSON\toJSON; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| use Crater\User; | ||||
| @ -175,13 +175,7 @@ class InvoicesController extends Controller | ||||
|                 ]); | ||||
|             } | ||||
|  | ||||
|             if (!config('mail.from.name')) { | ||||
|                 return response()->json([ | ||||
|                     'error' => 'from_email_does_not_exist' | ||||
|                 ]); | ||||
|             } | ||||
|  | ||||
|             \Mail::to($email)->send(new invoicePdf($data)); | ||||
|             \Mail::to($email)->send(new InvoicePdf($data)); | ||||
|         } | ||||
|  | ||||
|         $invoice = Invoice::with(['items', 'user', 'invoiceTemplate', 'taxes'])->find($invoice->id); | ||||
| @ -410,13 +404,7 @@ class InvoicesController extends Controller | ||||
|             ]); | ||||
|         } | ||||
|  | ||||
|         if (!config('mail.from.name')) { | ||||
|             return response()->json([ | ||||
|                 'error' => 'from_email_does_not_exist' | ||||
|             ]); | ||||
|         } | ||||
|  | ||||
|         \Mail::to($email)->send(new invoicePdf($data)); | ||||
|         \Mail::to($email)->send(new InvoicePdf($data)); | ||||
|  | ||||
|         if ($invoice->status == Invoice::STATUS_DRAFT) { | ||||
|             $invoice->status = Invoice::STATUS_SENT; | ||||
|  | ||||
| @ -50,7 +50,8 @@ class OnboardingController extends Controller | ||||
|             ["code"=>"es", "name" => "Spanish"], | ||||
|             ["code"=>"ar", "name" => "العربية"], | ||||
|             ["code"=>"de", "name" => "German"], | ||||
|             ["code"=>"pt-br", "name" => "Portuguese (Brazilian)"] | ||||
|             ["code"=>"pt-br", "name" => "Portuguese (Brazilian)"], | ||||
|             ["code"=>"it", "name" => "Italian"], | ||||
|         ]; | ||||
|         $fiscal_years = [ | ||||
|             ['key' => 'january-december' , 'value' => '1-12'], | ||||
|  | ||||
| @ -305,10 +305,6 @@ class PaymentController extends Controller | ||||
|         $data['user'] = User::find($userId)->toArray(); | ||||
|         $data['company'] = Company::find($payment->company_id); | ||||
|         $email = $data['user']['email']; | ||||
|         $notificationEmail = CompanySetting::getSetting( | ||||
|             'notification_email', | ||||
|             $request->header('company') | ||||
|         ); | ||||
|  | ||||
|         if (!$email) { | ||||
|             return response()->json([ | ||||
| @ -316,13 +312,7 @@ class PaymentController extends Controller | ||||
|             ]); | ||||
|         } | ||||
|  | ||||
|         if (!$notificationEmail) { | ||||
|             return response()->json([ | ||||
|                 'error' => 'notification_email_does_not_exist' | ||||
|             ]); | ||||
|         } | ||||
|  | ||||
|         \Mail::to($email)->send(new PaymentPdf($data, $notificationEmail)); | ||||
|         \Mail::to($email)->send(new PaymentPdf($data)); | ||||
|  | ||||
|         return response()->json([ | ||||
|             'success' => true | ||||
|  | ||||
| @ -2,23 +2,81 @@ | ||||
|  | ||||
| namespace Crater\Http\Controllers; | ||||
|  | ||||
| use Crater\Setting; | ||||
| use Illuminate\Http\Request; | ||||
| use Crater\Space\Updater; | ||||
| use Crater\Space\SiteApi; | ||||
| use Illuminate\Support\Facades\Artisan; | ||||
|  | ||||
| class UpdateController extends Controller | ||||
| { | ||||
|     public function update(Request $request) | ||||
|  | ||||
|     public function download(Request $request) | ||||
|     { | ||||
|         set_time_limit(600); // 10 minutes | ||||
|         $request->validate([ | ||||
|             'version' => 'required', | ||||
|         ]); | ||||
|  | ||||
|         $json = Updater::update($request->installed, $request->version); | ||||
|         $path = Updater::download($request->version); | ||||
|  | ||||
|         return response()->json($json); | ||||
|         return response()->json([ | ||||
|             'success' => true, | ||||
|             'path' => $path | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function unzip(Request $request) | ||||
|     { | ||||
|         $request->validate([ | ||||
|             'path' => 'required', | ||||
|         ]); | ||||
|  | ||||
|         try { | ||||
|             $path = Updater::unzip($request->path); | ||||
|  | ||||
|             return response()->json([ | ||||
|                 'success' => true, | ||||
|                 'path' => $path | ||||
|             ]); | ||||
|  | ||||
|         } catch (\Exception $e) { | ||||
|             return response()->json([ | ||||
|                 'success' => false, | ||||
|                 'error' => $e->getMessage() | ||||
|             ], 500); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public function copyFiles(Request $request) | ||||
|     { | ||||
|         $request->validate([ | ||||
|             'path' => 'required', | ||||
|         ]); | ||||
|  | ||||
|         $path = Updater::copyFiles($request->path); | ||||
|  | ||||
|         return response()->json([ | ||||
|             'success' => true, | ||||
|             'path' => $path | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function migrate(Request $request) | ||||
|     { | ||||
|         Updater::migrateUpdate(); | ||||
|  | ||||
|         return response()->json([ | ||||
|             'success' => true | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function finishUpdate(Request $request) | ||||
|     { | ||||
|         $request->validate([ | ||||
|             'installed' => 'required', | ||||
|             'version' => 'required', | ||||
|         ]); | ||||
|  | ||||
|         $json = Updater::finishUpdate($request->installed, $request->version); | ||||
|  | ||||
|         return response()->json($json); | ||||
| @ -28,7 +86,7 @@ class UpdateController extends Controller | ||||
|     { | ||||
|         set_time_limit(600); // 10 minutes | ||||
|  | ||||
|         $json = Updater::checkForUpdate(); | ||||
|         $json = Updater::checkForUpdate(Setting::getSetting('version')); | ||||
|  | ||||
|         return response()->json($json); | ||||
|     } | ||||
|  | ||||
| @ -2,6 +2,7 @@ | ||||
|  | ||||
| namespace Crater\Listeners\Updates; | ||||
|  | ||||
| // Implementation taken from Akaunting - https://github.com/akaunting/akaunting | ||||
| class Listener | ||||
| { | ||||
|     const VERSION = ''; | ||||
|  | ||||
							
								
								
									
										52
									
								
								app/Listeners/Updates/v3/Version310.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								app/Listeners/Updates/v3/Version310.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,52 @@ | ||||
| <?php | ||||
|  | ||||
| namespace Crater\Listeners\Updates\v3; | ||||
|  | ||||
| use Illuminate\Contracts\Queue\ShouldQueue; | ||||
| use Illuminate\Queue\InteractsWithQueue; | ||||
| use Crater\Listeners\Updates\Listener; | ||||
| use Illuminate\Database\Schema\Blueprint; | ||||
| use Crater\Events\UpdateFinished; | ||||
| use Crater\Setting; | ||||
| use Crater\Currency; | ||||
| use Schema; | ||||
| use Artisan; | ||||
|  | ||||
| class Version310 extends Listener | ||||
| { | ||||
|     const VERSION = '3.1.0'; | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Handle the event. | ||||
|      * | ||||
|      * @param UpdateFinished $event | ||||
|      * @return void | ||||
|      */ | ||||
|     public function handle(UpdateFinished $event) | ||||
|     { | ||||
|         if ($this->isListenerFired($event)) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         Currency::firstOrCreate( | ||||
|             [ | ||||
|                 'name' => 'Kyrgyzstani som', | ||||
|                 'code' => 'KGS' | ||||
|             ], | ||||
|             [ | ||||
|                 'name' => 'Kyrgyzstani som', | ||||
|                 'code' => 'KGS', | ||||
|                 'symbol' => 'С̲ ', | ||||
|                 'precision' => '2', | ||||
|                 'thousand_separator' => '.', | ||||
|                 'decimal_separator' => ',' | ||||
|             ] | ||||
|         ); | ||||
|  | ||||
|         Artisan::call('migrate', ['--force' => true]); | ||||
|  | ||||
|         // Update Crater app version | ||||
|         Setting::setSetting('version', static::VERSION); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										32
									
								
								app/Listeners/Updates/v3/Version311.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								app/Listeners/Updates/v3/Version311.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | ||||
| <?php | ||||
|  | ||||
| namespace Crater\Listeners\Updates\v3; | ||||
|  | ||||
| use Crater\Listeners\Updates\Listener; | ||||
| use Crater\Events\UpdateFinished; | ||||
| use Crater\Setting; | ||||
| use Crater\Currency; | ||||
| use Artisan; | ||||
|  | ||||
| class Version311 extends Listener | ||||
| { | ||||
|     const VERSION = '3.1.1'; | ||||
|  | ||||
|     /** | ||||
|      * Handle the event. | ||||
|      * | ||||
|      * @param UpdateFinished $event | ||||
|      * @return void | ||||
|      */ | ||||
|     public function handle(UpdateFinished $event) | ||||
|     { | ||||
|         if ($this->isListenerFired($event)) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         Artisan::call('migrate', ['--force' => true]); | ||||
|  | ||||
|         // Update Crater app version | ||||
|         Setting::setSetting('version', static::VERSION); | ||||
|     } | ||||
| } | ||||
| @ -29,6 +29,9 @@ class EstimatePdf extends Mailable | ||||
|      */ | ||||
|     public function build() | ||||
|     { | ||||
|         return $this->markdown('emails.send.estimate', ['data', $this->data]); | ||||
|         $company = $this->data['company']['name']; | ||||
|  | ||||
|         return $this->subject("Estimate from $company") | ||||
|                     ->markdown('emails.send.estimate', ['data', $this->data]); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -31,6 +31,8 @@ class EstimateViewed extends Mailable | ||||
|     public function build() | ||||
|     { | ||||
|         $email = $this->data['user']['email']; | ||||
|         return $this->from($email)->markdown('emails.viewed.estimate', ['data', $this->data]); | ||||
|         $name = $this->data['user']['name']; | ||||
|         return $this->from($email, $name) | ||||
|                     ->markdown('emails.viewed.estimate', ['data', $this->data]); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -6,7 +6,7 @@ use Illuminate\Mail\Mailable; | ||||
| use Illuminate\Queue\SerializesModels; | ||||
| use Illuminate\Contracts\Queue\ShouldQueue; | ||||
| 
 | ||||
| class invoicePdf extends Mailable | ||||
| class InvoicePdf extends Mailable | ||||
| { | ||||
|     use Queueable, SerializesModels; | ||||
| 
 | ||||
| @ -29,6 +29,9 @@ class invoicePdf extends Mailable | ||||
|      */ | ||||
|     public function build() | ||||
|     { | ||||
|         return $this->markdown('emails.send.invoice', ['data', $this->data]); | ||||
|         $company = $this->data['company']['name']; | ||||
| 
 | ||||
|         return $this->subject("Invoice from $company") | ||||
|                     ->markdown('emails.send.invoice', ['data', $this->data]); | ||||
|     } | ||||
| } | ||||
| @ -31,6 +31,8 @@ class InvoiceViewed extends Mailable | ||||
|     public function build() | ||||
|     { | ||||
|         $email = $this->data['user']['email']; | ||||
|         return $this->from($email)->markdown('emails.viewed.invoice', ['data', $this->data]); | ||||
|         $name = $this->data['user']['name']; | ||||
|         return $this->from($email, $name) | ||||
|                     ->markdown('emails.viewed.invoice', ['data', $this->data]); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -13,17 +13,14 @@ class PaymentPdf extends Mailable | ||||
|  | ||||
|     public $data = []; | ||||
|  | ||||
|     public $notificationEmail = ''; | ||||
|  | ||||
|     /** | ||||
|      * Create a new message instance. | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function __construct($data, $notificationEmail) | ||||
|     public function __construct($data) | ||||
|     { | ||||
|         $this->data = $data; | ||||
|         $this->notificationEmail = $notificationEmail; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @ -33,6 +30,9 @@ class PaymentPdf extends Mailable | ||||
|      */ | ||||
|     public function build() | ||||
|     { | ||||
|         return $this->from($this->notificationEmail)->markdown('emails.send.payment', ['data', $this->data]); | ||||
|         $company = $this->data['company']['name']; | ||||
|  | ||||
|         return $this->subject("Payment from $company") | ||||
|                     ->markdown('emails.send.payment', ['data', $this->data]); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,4 +1,5 @@ | ||||
| <?php | ||||
|  | ||||
| namespace Crater\Providers; | ||||
|  | ||||
| use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; | ||||
| @ -11,6 +12,8 @@ use Crater\Listeners\Updates\v2\Version201; | ||||
| use Crater\Listeners\Updates\v2\Version202; | ||||
| use Crater\Listeners\Updates\v2\Version210; | ||||
| use Crater\Listeners\Updates\v3\Version300; | ||||
| use Crater\Listeners\Updates\v3\Version310; | ||||
| use Crater\Listeners\Updates\v3\Version311; | ||||
|  | ||||
| class EventServiceProvider extends ServiceProvider | ||||
| { | ||||
| @ -20,13 +23,15 @@ class EventServiceProvider extends ServiceProvider | ||||
|      * @var array | ||||
|      */ | ||||
|     protected $listen = [ | ||||
|         UpdateFinished::class=> [ | ||||
|         UpdateFinished::class => [ | ||||
|             Version110::class, | ||||
|             Version200::class, | ||||
|             Version201::class, | ||||
|             Version202::class, | ||||
|             Version210::class, | ||||
|             Version300::class, | ||||
|             Version310::class, | ||||
|             Version311::class, | ||||
|         ], | ||||
|         Registered::class => [ | ||||
|             SendEmailVerificationNotification::class, | ||||
|  | ||||
| @ -6,6 +6,7 @@ use GuzzleHttp\Client; | ||||
| use GuzzleHttp\Exception\RequestException; | ||||
| use Crater\Setting; | ||||
|  | ||||
| // Implementation taken from Akaunting - https://github.com/akaunting/akaunting | ||||
| trait SiteApi | ||||
| { | ||||
|  | ||||
|  | ||||
| @ -2,31 +2,46 @@ | ||||
| namespace Crater\Space; | ||||
|  | ||||
| use File; | ||||
| use ZipArchive; | ||||
| use Artisan; | ||||
| use GuzzleHttp\Exception\RequestException; | ||||
| use Crater\Space\SiteApi; | ||||
| use Crater\Events\UpdateFinished; | ||||
| use Crater\Setting; | ||||
| use Illuminate\Http\Request; | ||||
| use ZipArchive; | ||||
|  | ||||
| // Implementation taken from Akaunting - https://github.com/akaunting/akaunting | ||||
| class Updater | ||||
| { | ||||
|     use SiteApi; | ||||
|  | ||||
|     public static function update($installed, $version) | ||||
|     public static function checkForUpdate($installed_version) | ||||
|     { | ||||
|         $data = null; | ||||
|         if(env('APP_ENV') === 'development') | ||||
|         { | ||||
|             $url = 'https://craterapp.com/downloads/check/latest/'. $installed_version . '?type=update&is_dev=1'; | ||||
|         } else { | ||||
|             $url = 'https://craterapp.com/downloads/check/latest/'. $installed_version . '?type=update'; | ||||
|         } | ||||
|  | ||||
|         $response = static::getRemote($url, ['timeout' => 100, 'track_redirects' => true]); | ||||
|  | ||||
|         if ($response && ($response->getStatusCode() == 200)) { | ||||
|             $data = $response->getBody()->getContents(); | ||||
|         } | ||||
|  | ||||
|         return json_decode($data); | ||||
|     } | ||||
|  | ||||
|     public static function download($new_version) | ||||
|     { | ||||
|         $data = null; | ||||
|         $path = null; | ||||
|  | ||||
|         if(env('APP_ENV') === 'development') | ||||
|         { | ||||
|             $url = 'https://craterapp.com/downloads/file/'.$version.'?type=update&is_dev=1'; | ||||
|         if (env('APP_ENV') === 'development') { | ||||
|             $url = 'https://craterapp.com/downloads/file/' . $new_version . '?type=update&is_dev=1'; | ||||
|         } else { | ||||
|             $url = 'https://craterapp.com/downloads/file/'.$version.'?type=update'; | ||||
|             $url = 'https://craterapp.com/downloads/file/' . $new_version . '?type=update'; | ||||
|         } | ||||
|  | ||||
|  | ||||
|         $response = static::getRemote($url, ['timeout' => 100, 'track_redirects' => true]); | ||||
|  | ||||
|         // Exception | ||||
| @ -45,66 +60,68 @@ class Updater | ||||
|         } | ||||
|  | ||||
|         // Create temp directory | ||||
|         $path = 'temp-' . md5(mt_rand()); | ||||
|         $path2 = 'temp2-' . md5(mt_rand()); | ||||
|         $temp_path = storage_path('app') . '/' . $path; | ||||
|         $temp_path2 = storage_path('app') . '/' . $path2; | ||||
|         $temp_dir = storage_path('app/temp-' . md5(mt_rand())); | ||||
|  | ||||
|         if (!File::isDirectory($temp_path)) { | ||||
|             File::makeDirectory($temp_path); | ||||
|             File::makeDirectory($temp_path2); | ||||
|         if (!File::isDirectory($temp_dir)) { | ||||
|             File::makeDirectory($temp_dir); | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|         $zip_file_path = $temp_dir . '/upload.zip'; | ||||
|  | ||||
|             $file = $temp_path . '/upload.zip'; | ||||
|         // Add content to the Zip file | ||||
|         $uploaded = is_int(file_put_contents($zip_file_path, $data)) ? true : false; | ||||
|  | ||||
|             // Add content to the Zip file | ||||
|             $uploaded = is_int(file_put_contents($file, $data)) ? true : false; | ||||
|  | ||||
|             if (!$uploaded) { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             // Unzip the file | ||||
|             $zip = new ZipArchive(); | ||||
|  | ||||
|             if ($zip->open($file)) { | ||||
|                 $zip->extractTo($temp_path2); | ||||
|             } | ||||
|  | ||||
|             $zip->close(); | ||||
|  | ||||
|             // Delete zip file | ||||
|             File::delete($file); | ||||
|  | ||||
|             if (!File::copyDirectory($temp_path2.'/Crater', base_path())) { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             // Delete temp directory | ||||
|             File::deleteDirectory($temp_path); | ||||
|             File::deleteDirectory($temp_path2); | ||||
|  | ||||
|             return [ | ||||
|                 'success' => true, | ||||
|                 'error' => false, | ||||
|                 'data' => [] | ||||
|             ]; | ||||
|         } catch (\Exception $e) { | ||||
|  | ||||
|             if (File::isDirectory($temp_path)) { | ||||
|                 // Delete temp directory | ||||
|                 File::deleteDirectory($temp_path); | ||||
|                 File::deleteDirectory($temp_path2); | ||||
|             } | ||||
|  | ||||
|             return [ | ||||
|                 'success' => false, | ||||
|                 'error' => 'Update error', | ||||
|                 'data' => [] | ||||
|             ]; | ||||
|         if (!$uploaded) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return $zip_file_path; | ||||
|     } | ||||
|  | ||||
|     public static function unzip($zip_file_path) | ||||
|     { | ||||
|         if(!file_exists($zip_file_path)) { | ||||
|             throw new \Exception('Zip file not found'); | ||||
|         } | ||||
|  | ||||
|         $temp_extract_dir = storage_path('app/temp2-' . md5(mt_rand())); | ||||
|  | ||||
|         if (!File::isDirectory($temp_extract_dir)) { | ||||
|             File::makeDirectory($temp_extract_dir); | ||||
|         } | ||||
|         // Unzip the file | ||||
|         $zip = new ZipArchive(); | ||||
|  | ||||
|         if ($zip->open($zip_file_path)) { | ||||
|             $zip->extractTo($temp_extract_dir); | ||||
|         } | ||||
|  | ||||
|         $zip->close(); | ||||
|  | ||||
|         // Delete zip file | ||||
|         File::delete($zip_file_path); | ||||
|  | ||||
|         return $temp_extract_dir; | ||||
|     } | ||||
|  | ||||
|     public static function copyFiles($temp_extract_dir) | ||||
|     { | ||||
|  | ||||
|         if (!File::copyDirectory($temp_extract_dir . '/Crater', base_path())) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         // Delete temp directory | ||||
|         File::deleteDirectory($temp_extract_dir); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     public static function migrateUpdate() | ||||
|     { | ||||
|         Artisan::call('migrate --force'); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     public static function finishUpdate($installed, $version) | ||||
| @ -118,22 +135,4 @@ class Updater | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     public static function checkForUpdate() | ||||
|     { | ||||
|         $data = null; | ||||
|         if(env('APP_ENV') === 'development') | ||||
|         { | ||||
|             $url = 'https://craterapp.com/downloads/check/latest/'. Setting::getSetting('version') . '?type=update&is_dev=1'; | ||||
|         } else { | ||||
|             $url = 'https://craterapp.com/downloads/check/latest/'. Setting::getSetting('version') . '?type=update'; | ||||
|         } | ||||
|  | ||||
|         $response = static::getRemote($url, ['timeout' => 100, 'track_redirects' => true]); | ||||
|  | ||||
|         if ($response && ($response->getStatusCode() == 200)) { | ||||
|             $data = $response->getBody()->getContents(); | ||||
|         } | ||||
|  | ||||
|         return json_decode($data); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -9,6 +9,7 @@ use carbon\carbon; | ||||
| use Crater\MemberLoan; | ||||
| use Crater\Address; | ||||
| use Crater\Payment; | ||||
| use Crater\Expense; | ||||
| use Crater\Company; | ||||
| use Crater\Notifications\MailResetPasswordNotification; | ||||
| use Spatie\MediaLibrary\HasMedia\HasMedia; | ||||
| @ -105,6 +106,11 @@ class User extends Authenticatable implements HasMedia | ||||
|         return $this->hasMany(Address::class); | ||||
|     } | ||||
|  | ||||
|     public function expenses() | ||||
|     { | ||||
|         return $this->hasMany(Expense::class); | ||||
|     } | ||||
|  | ||||
|     public function billingAddress() | ||||
|     { | ||||
|         return $this->hasOne(Address::class)->where('type', Address::BILLING_TYPE); | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "laravel/laravel", | ||||
|     "description": "The Laravel Framework.", | ||||
|     "name": "bytefury/crater", | ||||
|     "description": "Free & Open Source Invoice App for Freelancers & Small Businesses. https://craterapp.com", | ||||
|     "keywords": [ | ||||
|         "framework", | ||||
|         "laravel" | ||||
| @ -9,6 +9,7 @@ | ||||
|     "type": "project", | ||||
|     "require": { | ||||
|         "php": "^7.2", | ||||
|         "aws/aws-sdk-php": "^3.137", | ||||
|         "barryvdh/laravel-dompdf": "^0.8.1", | ||||
|         "doctrine/dbal": "^2.10", | ||||
|         "fideloper/proxy": "^4.0", | ||||
|  | ||||
							
								
								
									
										1719
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1719
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -9,6 +9,6 @@ return [ | ||||
|     | | ||||
|     */ | ||||
|  | ||||
|     'version' => '3.0.0', | ||||
|     'version' => '3.1.1', | ||||
|  | ||||
| ]; | ||||
|  | ||||
| @ -13,13 +13,15 @@ class CreateUnitsTable extends Migration | ||||
|      */ | ||||
|     public function up() | ||||
|     { | ||||
|         Schema::create('units', function (Blueprint $table) { | ||||
|             $table->increments('id'); | ||||
|             $table->string('name'); | ||||
|             $table->integer('company_id')->unsigned()->nullable(); | ||||
|             $table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade'); | ||||
|             $table->timestamps(); | ||||
|         }); | ||||
|         if (!Schema::hasTable('units')) { | ||||
|             Schema::create('units', function (Blueprint $table) { | ||||
|                 $table->increments('id'); | ||||
|                 $table->string('name'); | ||||
|                 $table->integer('company_id')->unsigned()->nullable(); | ||||
|                 $table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade'); | ||||
|                 $table->timestamps(); | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|  | ||||
| @ -13,13 +13,15 @@ class CreatePaymentMethodsTable extends Migration | ||||
|      */ | ||||
|     public function up() | ||||
|     { | ||||
|         Schema::create('payment_methods', function (Blueprint $table) { | ||||
|             $table->increments('id'); | ||||
|             $table->string('name'); | ||||
|             $table->integer('company_id')->unsigned()->nullable(); | ||||
|             $table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade'); | ||||
|             $table->timestamps(); | ||||
|         }); | ||||
|         if (!Schema::hasTable('payment_methods')) { | ||||
|             Schema::create('payment_methods', function (Blueprint $table) { | ||||
|                 $table->increments('id'); | ||||
|                 $table->string('name'); | ||||
|                 $table->integer('company_id')->unsigned()->nullable(); | ||||
|                 $table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade'); | ||||
|                 $table->timestamps(); | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|  | ||||
| @ -0,0 +1,33 @@ | ||||
| <?php | ||||
|  | ||||
| use Illuminate\Database\Migrations\Migration; | ||||
| use Illuminate\Database\Schema\Blueprint; | ||||
| use Illuminate\Support\Facades\Schema; | ||||
|  | ||||
| class AddUserIdToExpensesTable extends Migration | ||||
| { | ||||
|     /** | ||||
|      * Run the migrations. | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function up() | ||||
|     { | ||||
|         Schema::table('expenses', function (Blueprint $table) { | ||||
|             $table->integer('user_id')->unsigned()->nullable(); | ||||
|             $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Reverse the migrations. | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function down() | ||||
|     { | ||||
|         Schema::table('expenses', function (Blueprint $table) { | ||||
|             $table->dropColumn('paid'); | ||||
|         }); | ||||
|     } | ||||
| } | ||||
| @ -532,6 +532,14 @@ class CurrenciesTableSeeder extends Seeder | ||||
|                 'thousand_separator' => '.', | ||||
|                 'decimal_separator' => ',' | ||||
|             ], | ||||
|             [ | ||||
|                 'name' => 'Kyrgyzstani som', | ||||
|                 'code' => 'KGS', | ||||
|                 'symbol' => 'С̲ ', | ||||
|                 'precision' => '2', | ||||
|                 'thousand_separator' => '.', | ||||
|                 'decimal_separator' => ',' | ||||
|             ], | ||||
|         ]; | ||||
|  | ||||
|         foreach ($currencies as $currency) { | ||||
|  | ||||
| @ -1,40 +0,0 @@ | ||||
| version: '3.1' | ||||
|  | ||||
| services: | ||||
|  | ||||
|   web: | ||||
|     image: nginx | ||||
|     depends_on: | ||||
|       - php | ||||
|     ports: | ||||
|       - 8080:80 | ||||
|     volumes: | ||||
|       - ./nginx.conf:/etc/nginx/nginx.conf:ro | ||||
|       - app:/app | ||||
|     restart: always  | ||||
|      | ||||
|   php: | ||||
|     build: . | ||||
|     depends_on: | ||||
|       - db | ||||
|     expose: | ||||
|       - 9000 | ||||
|     volumes: | ||||
|       - app:/app | ||||
|     restart: always | ||||
|  | ||||
|   db: | ||||
|     image: mariadb | ||||
|     restart: always | ||||
|     volumes: | ||||
|       - db:/var/lib/mysql | ||||
|     environment: | ||||
|       MYSQL_USER: crater | ||||
|       MYSQL_PASSWORD: crater | ||||
|       MYSQL_DATABASE: crater | ||||
|       MYSQL_ROOT_PASSWORD: crater | ||||
|  | ||||
| volumes: | ||||
|   app: | ||||
|   db: | ||||
|  | ||||
							
								
								
									
										50
									
								
								docker-compose.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								docker-compose.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,50 @@ | ||||
| version: '3.7' | ||||
|  | ||||
| services: | ||||
|   app: | ||||
|     build: | ||||
|       args: | ||||
|         user: crater-user | ||||
|         uid: 1000 | ||||
|       context: ./ | ||||
|       dockerfile: Dockerfile | ||||
|     image: crater-php | ||||
|     restart: unless-stopped | ||||
|     working_dir: /var/www/ | ||||
|     volumes: | ||||
|       - ./:/var/www | ||||
|     networks: | ||||
|       - crater | ||||
|  | ||||
|   db: | ||||
|     image: mariadb | ||||
|     restart: always | ||||
|     volumes: | ||||
|       - db:/var/lib/mysql | ||||
|     environment: | ||||
|       MYSQL_USER: crater | ||||
|       MYSQL_PASSWORD: crater | ||||
|       MYSQL_DATABASE: crater | ||||
|       MYSQL_ROOT_PASSWORD: crater | ||||
|     ports: | ||||
|       - '33006:3306' | ||||
|     networks: | ||||
|       - crater | ||||
|  | ||||
|   nginx: | ||||
|     image: nginx:1.17-alpine | ||||
|     restart: unless-stopped | ||||
|     ports: | ||||
|       - 80:80 | ||||
|     volumes: | ||||
|       - ./:/var/www | ||||
|       - ./docker-compose/nginx:/etc/nginx/conf.d/ | ||||
|     networks: | ||||
|       - crater | ||||
|  | ||||
| volumes: | ||||
|   db: | ||||
|  | ||||
| networks: | ||||
|   crater: | ||||
|     driver: bridge | ||||
							
								
								
									
										20
									
								
								docker-compose/nginx/nginx.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								docker-compose/nginx/nginx.conf
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| server { | ||||
|     listen 80; | ||||
|     index index.php index.html; | ||||
|     error_log  /var/log/nginx/error.log; | ||||
|     access_log /var/log/nginx/access.log; | ||||
|     root /var/www/public; | ||||
|     location ~ \.php$ { | ||||
|         try_files $uri =404; | ||||
|         fastcgi_split_path_info ^(.+\.php)(/.+)$; | ||||
|         fastcgi_pass app:9000; | ||||
|         fastcgi_index index.php; | ||||
|         include fastcgi_params; | ||||
|         fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; | ||||
|         fastcgi_param PATH_INFO $fastcgi_path_info; | ||||
|     } | ||||
|     location / { | ||||
|         try_files $uri $uri/ /index.php?$query_string; | ||||
|         gzip_static on; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										7
									
								
								docker-compose/setup.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										7
									
								
								docker-compose/setup.sh
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,7 @@ | ||||
| #!/bin/sh | ||||
|  | ||||
| docker-compose exec app composer install --no-interaction --prefer-dist --optimize-autoloader | ||||
|  | ||||
| docker-compose exec app php artisan storage:link || true | ||||
| docker-compose exec app php artisan key:generate | ||||
| docker-compose exec app php artisan passport:keys || true | ||||
							
								
								
									
										53
									
								
								nginx.conf
									
									
									
									
									
								
							
							
						
						
									
										53
									
								
								nginx.conf
									
									
									
									
									
								
							| @ -1,53 +0,0 @@ | ||||
| worker_processes  8; | ||||
|  | ||||
| error_log  /var/log/nginx/error.log warn; | ||||
| pid        /var/run/nginx.pid; | ||||
|  | ||||
| events { | ||||
|     worker_connections  4096; | ||||
| } | ||||
|  | ||||
| http { | ||||
|     include       /etc/nginx/mime.types; | ||||
|     default_type  application/octet-stream; | ||||
|  | ||||
|     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" ' | ||||
|                       '$status $body_bytes_sent "$http_referer" ' | ||||
|                       '"$http_user_agent" "$http_x_forwarded_for"'; | ||||
|  | ||||
|     access_log  /var/log/nginx/access.log  main; | ||||
|  | ||||
|     sendfile        on; | ||||
|  | ||||
|     keepalive_timeout  65; | ||||
|  | ||||
|     server { | ||||
|         listen 80 default_server; | ||||
|  | ||||
|         root /app/public; | ||||
|         index index.php; | ||||
|         charset utf-8; | ||||
|  | ||||
|         access_log off; | ||||
|  | ||||
|         location / { | ||||
|             try_files $uri $uri/ /index.php?$query_string; | ||||
|         } | ||||
|  | ||||
|         location = /favicon.ico { access_log off; log_not_found off; } | ||||
|         location = /robots.txt  { access_log off; log_not_found off; } | ||||
|  | ||||
|         add_header X-Content-Type-Options nosniff; | ||||
|         add_header X-XSS-Protection "1; mode=block"; | ||||
|         add_header X-Robots-Tag none; | ||||
|         add_header Content-Security-Policy "frame-ancestors 'self'"; | ||||
|  | ||||
|         location ~ \.php$ { | ||||
|             fastcgi_pass php:9000; | ||||
|             fastcgi_index index.php; | ||||
|             include fastcgi_params; | ||||
|             fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; | ||||
|             include /etc/nginx/fastcgi_params; | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										5005
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										5005
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										23
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								package.json
									
									
									
									
									
								
							| @ -8,19 +8,16 @@ | ||||
|     "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "babel-eslint": "^8.2.3", | ||||
|     "browser-sync": "^2.26.7", | ||||
|     "browser-sync-webpack-plugin": "^2.0.1", | ||||
|     "babel-eslint": "^8.2.6", | ||||
|     "cross-env": "^5.1", | ||||
|     "css-loader": "^0.28.8", | ||||
|     "eslint": "^4.14.0", | ||||
|     "eslint-config-standard": "^11.0.0-beta.0", | ||||
|     "eslint-plugin-import": "^2.11.0", | ||||
|     "eslint-plugin-node": "^5.2.1", | ||||
|     "eslint-plugin-promise": "^3.6.0", | ||||
|     "eslint-plugin-standard": "^3.0.1", | ||||
|     "eslint-plugin-vue": "^4.0.1", | ||||
|     "eslint": "^4.19.1", | ||||
|     "eslint-config-prettier": "^6.10.1", | ||||
|     "eslint-loader": "^3.0.3", | ||||
|     "eslint-plugin-prettier": "^3.1.2", | ||||
|     "eslint-plugin-vue": "^4.7.1", | ||||
|     "laravel-mix": "^5.0.0", | ||||
|     "prettier": "^2.0.2", | ||||
|     "resolve-url-loader": "3.1.0", | ||||
|     "sass": "^1.22.9", | ||||
|     "sass-loader": "7.*", | ||||
| @ -35,18 +32,12 @@ | ||||
|     "axios": "^0.19", | ||||
|     "bootstrap": "^4.1.0", | ||||
|     "chart.js": "^2.7.3", | ||||
|     "cross-env": "^5.1.4", | ||||
|     "easy-pie-chart": "^2.1.7", | ||||
|     "fs": "0.0.1-security", | ||||
|     "guid": "0.0.12", | ||||
|     "lodash": "^4.17.13", | ||||
|     "moment": "^2.18.1", | ||||
|     "npm": "^6.4.1", | ||||
|     "popper.js": "^1.12.9", | ||||
|     "sweet-modal-vue": "^2.0.0", | ||||
|     "sweetalert": "^2.1.2", | ||||
|     "toastr": "^2.1.4", | ||||
|     "upgrade": "^1.1.0", | ||||
|     "v-money": "^0.8.1", | ||||
|     "v-tooltip": "^2.0.2", | ||||
|     "vue": "^2.5.17", | ||||
|  | ||||
							
								
								
									
										4
									
								
								public/assets/css/crater.css
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								public/assets/css/crater.css
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -1,4 +1,4 @@ | ||||
| { | ||||
|     "/assets/js/app.js": "/assets/js/app.js?id=397e57d36ef22a2e14fc", | ||||
|     "/assets/css/crater.css": "/assets/css/crater.css?id=616996a79c1df69d18de" | ||||
|     "/assets/js/app.js": "/assets/js/app.js?id=3c9e7bf904dd1bcdf67f", | ||||
|     "/assets/css/crater.css": "/assets/css/crater.css?id=f5a1617422acad8e44a1" | ||||
| } | ||||
|  | ||||
| @ -63,6 +63,7 @@ Crater is a product of [Bytefury](https://bytefury.com) | ||||
| **Special thanks to:** | ||||
| * [Birkhoff Lee](https://github.com/BirkhoffLee) | ||||
| * [Hassan A. Ba Abdullah](https://github.com/hsnapps) | ||||
| * [Akaunting](https://github.com/akaunting/akaunting) | ||||
|  | ||||
| ## Translate | ||||
| Help us translate or suggest changes to existing languages if you find any mistakes by creating a new PR.  | ||||
|  | ||||
							
								
								
									
										22
									
								
								resources/assets/js/bootstrap.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								resources/assets/js/bootstrap.js
									
									
									
									
										vendored
									
									
								
							| @ -88,17 +88,27 @@ window.axios.interceptors.request.use(function (config) { | ||||
|  | ||||
| global.axios.interceptors.response.use(undefined, function (err) { | ||||
|   // Do something with request error | ||||
|   return new Promise((resolve, reject) => { | ||||
|   if (!err.response) { | ||||
|     window.toastr['error']('Network error: Please check your internet connection or wait until servers are back online') | ||||
|     console.log('Network error: Please check your internet connection.') | ||||
|   } else { | ||||
|     console.log(err.response) | ||||
|     if (err.response.data.error === 'invalid_credentials') { | ||||
|       window.toastr['error']('Invalid Credentials') | ||||
|     } | ||||
|     if (err.response.data && (err.response.statusText === 'Unauthorized' || err.response.data === ' Unauthorized.')) { | ||||
|       // Unauthorized and log out | ||||
|       window.toastr['error']((err.response.data.message) ? err.response.data.message : 'Unauthorized') | ||||
|       store.dispatch('auth/logout', true) | ||||
|     } else if (err.response.data.errors) { | ||||
|       // Show a notification per error | ||||
|       const errors = JSON.parse(JSON.stringify(err.response.data.errors)) | ||||
|       for (const i in errors) { | ||||
|         window.toastr['error'](errors[i]) | ||||
|       } | ||||
|     } else { | ||||
|       throw err | ||||
|       // Unknown error | ||||
|       window.toastr['error']((err.response.data.message) ? err.response.data.message : 'Unknown error occurred') | ||||
|     } | ||||
|   }) | ||||
|   } | ||||
|   return Promise.reject(err) | ||||
| }) | ||||
|  | ||||
| /** | ||||
|  | ||||
| @ -9,7 +9,7 @@ | ||||
|       :readonly="readOnly" | ||||
|       :name="name" | ||||
|       :tabindex="tabIndex" | ||||
|       :class="[{'input-field-left-icon': icon && isAlignLeftIcon ,'input-field-right-icon': icon && !isAlignLeftIcon ,'invalid': isFieldValid, 'disabled': disabled, 'small-input': small}, inputClass]" | ||||
|       :class="[{ 'input-field-left-icon': icon && isAlignLeftIcon, 'input-field-right-icon': (icon && !isAlignLeftIcon) || isInputGroup, invalid: isFieldValid, disabled: disabled, 'small-input': small}, inputClass]" | ||||
|       :placeholder="placeholder" | ||||
|       :autocomplete="autocomplete" | ||||
|       class="input-field" | ||||
| @ -23,6 +23,9 @@ | ||||
|       <font-awesome-icon :icon="!showPass ?'eye': 'eye-slash'" class="right-icon" /> | ||||
|     </div> | ||||
|     <font-awesome-icon v-if="icon && !isAlignLeftIcon" :icon="icon" class="right-icon" /> | ||||
|     <span v-if="isInputGroup" class="right-input-group-text"> | ||||
|       {{ inputGroupText }} | ||||
|     </span> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| @ -84,6 +87,14 @@ export default { | ||||
|     showPassword: { | ||||
|       type: Boolean, | ||||
|       default: false | ||||
|     }, | ||||
|     isInputGroup: { | ||||
|       type: Boolean, | ||||
|       default: false, | ||||
|     }, | ||||
|     inputGroupText: { | ||||
|       type: String, | ||||
|       default: null, | ||||
|     } | ||||
|   }, | ||||
|   data () { | ||||
|  | ||||
| @ -1,69 +0,0 @@ | ||||
| <template> | ||||
|   <div class="graph-container"> | ||||
|     <canvas | ||||
|       id="graph" | ||||
|       ref="graph" | ||||
|     /> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import Chart from 'chart.js' | ||||
|  | ||||
| export default { | ||||
|   props: { | ||||
|     labels: { | ||||
|       type: Array, | ||||
|       require: true, | ||||
|       default: Array | ||||
|     }, | ||||
|     values: { | ||||
|       type: Array, | ||||
|       require: true, | ||||
|       default: Array | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   mounted () { | ||||
|     let context = this.$refs.graph.getContext('2d') | ||||
|     let options = { | ||||
|       responsive: true, | ||||
|       maintainAspectRatio: false, | ||||
|       legend: { | ||||
|         display: false | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     let data = { | ||||
|       labels: this.labels, | ||||
|       datasets: [ | ||||
|         { | ||||
|           label: 'My First dataset', | ||||
|           backgroundColor: 'rgba(79, 196, 127,0.2)', | ||||
|           borderColor: 'rgba(79, 196, 127,1)', | ||||
|           borderWidth: 1, | ||||
|           hoverBackgroundColor: 'rgba(79, 196, 127,0.4)', | ||||
|           hoverBorderColor: 'rgba(79, 196, 127,1)', | ||||
|           data: this.values | ||||
|         } | ||||
|       ] | ||||
|     } | ||||
|  | ||||
|     this.myBarChart = new Chart(context, { | ||||
|       type: 'bar', | ||||
|       data: data, | ||||
|       options: options | ||||
|     }) | ||||
|   }, | ||||
|  | ||||
|   beforeDestroy () { | ||||
|     this.myBarChart.destroy() | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
| .graph-container { | ||||
|   height: 300px; | ||||
| } | ||||
| </style> | ||||
| @ -1,71 +0,0 @@ | ||||
| <template> | ||||
|   <div class="graph-container"> | ||||
|     <canvas | ||||
|       id="graph" | ||||
|       ref="graph"/> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import Chart from 'chart.js' | ||||
|  | ||||
| export default { | ||||
|   props: { | ||||
|     labels: { | ||||
|       type: Array, | ||||
|       require: true, | ||||
|       default: Array | ||||
|     }, | ||||
|     values: { | ||||
|       type: Array, | ||||
|       require: true, | ||||
|       default: Array | ||||
|     }, | ||||
|     bgColors: { | ||||
|       type: Array, | ||||
|       require: true, | ||||
|       default: Array | ||||
|     }, | ||||
|     hoverBgColors: { | ||||
|       type: Array, | ||||
|       require: true, | ||||
|       default: Array | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   mounted () { | ||||
|     let context = this.$refs.graph.getContext('2d') | ||||
|     let options = { | ||||
|       responsive: true, | ||||
|       maintainAspectRatio: false | ||||
|     } | ||||
|  | ||||
|     let data = { | ||||
|       labels: this.labels, | ||||
|       datasets: [ | ||||
|         { | ||||
|           data: this.values, | ||||
|           backgroundColor: this.bgColors, | ||||
|           hoverBackgroundColor: this.hoverBgColors | ||||
|         } | ||||
|       ] | ||||
|     } | ||||
|  | ||||
|     this.myDoughnutChart = new Chart(context, { | ||||
|       type: 'doughnut', | ||||
|       data: data, | ||||
|       options: options | ||||
|     }) | ||||
|   }, | ||||
|  | ||||
|   beforeDestroy () { | ||||
|     this.myDoughnutChart.destroy() | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
| .graph-container { | ||||
|   height: 300px; | ||||
| } | ||||
| </style> | ||||
| @ -1,8 +1,6 @@ | ||||
| <template> | ||||
|   <div class="graph-container"> | ||||
|     <canvas | ||||
|       id="graph" | ||||
|       ref="graph" /> | ||||
|     <canvas id="graph" ref="graph" /> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| @ -16,58 +14,56 @@ export default { | ||||
|     labels: { | ||||
|       type: Array, | ||||
|       require: true, | ||||
|       default: Array | ||||
|       default: Array, | ||||
|     }, | ||||
|     values: { | ||||
|       type: Array, | ||||
|       require: true, | ||||
|       default: Array | ||||
|       default: Array, | ||||
|     }, | ||||
|     invoices: { | ||||
|       type: Array, | ||||
|       require: true, | ||||
|       default: Array | ||||
|       default: Array, | ||||
|     }, | ||||
|     expenses: { | ||||
|       type: Array, | ||||
|       require: true, | ||||
|       default: Array | ||||
|       default: Array, | ||||
|     }, | ||||
|     receipts: { | ||||
|       type: Array, | ||||
|       require: true, | ||||
|       default: Array | ||||
|       default: Array, | ||||
|     }, | ||||
|     income: { | ||||
|       type: Array, | ||||
|       require: true, | ||||
|       default: Array | ||||
|       default: Array, | ||||
|     }, | ||||
|     formatMoney: { | ||||
|       type: Function, | ||||
|       require: false, | ||||
|       default: Function | ||||
|       default: Function, | ||||
|     }, | ||||
|     FormatGraphMoney: { | ||||
|       type: Function, | ||||
|       require: false, | ||||
|       default: Function | ||||
|     } | ||||
|       default: Function, | ||||
|     }, | ||||
|   }, | ||||
|  | ||||
|   computed: { | ||||
|     ...mapGetters('currency', [ | ||||
|       'defaultCurrency' | ||||
|     ]) | ||||
|     ...mapGetters('currency', ['defaultCurrency']), | ||||
|   }, | ||||
|  | ||||
|   watch: { | ||||
|     labels (val) { | ||||
|     labels(val) { | ||||
|       this.update() | ||||
|     } | ||||
|     }, | ||||
|   }, | ||||
|  | ||||
|   mounted () { | ||||
|   mounted() { | ||||
|     let self = this | ||||
|     let context = this.$refs.graph.getContext('2d') | ||||
|     let options = { | ||||
| @ -77,13 +73,16 @@ export default { | ||||
|         enabled: true, | ||||
|         callbacks: { | ||||
|           label: function (tooltipItem, data) { | ||||
|             return self.FormatGraphMoney(tooltipItem.value, self.defaultCurrency) | ||||
|           } | ||||
|         } | ||||
|             return self.FormatGraphMoney( | ||||
|               tooltipItem.value * 100, | ||||
|               self.defaultCurrency | ||||
|             ) | ||||
|           }, | ||||
|         }, | ||||
|       }, | ||||
|       legend: { | ||||
|         display: false | ||||
|       } | ||||
|         display: false, | ||||
|       }, | ||||
|     } | ||||
|     let data = { | ||||
|       labels: this.labels, | ||||
| @ -107,7 +106,7 @@ export default { | ||||
|           pointHoverBorderWidth: 2, | ||||
|           pointRadius: 4, | ||||
|           pointHitRadius: 10, | ||||
|           data: this.invoices | ||||
|           data: this.invoices.map((invoice) => invoice / 100), | ||||
|         }, | ||||
|         { | ||||
|           label: 'Receipts', | ||||
| @ -128,7 +127,7 @@ export default { | ||||
|           pointHoverBorderWidth: 2, | ||||
|           pointRadius: 4, | ||||
|           pointHitRadius: 10, | ||||
|           data: this.receipts | ||||
|           data: this.receipts.map((receipt) => receipt / 100), | ||||
|         }, | ||||
|         { | ||||
|           label: 'Expenses', | ||||
| @ -149,7 +148,7 @@ export default { | ||||
|           pointHoverBorderWidth: 2, | ||||
|           pointRadius: 4, | ||||
|           pointHitRadius: 10, | ||||
|           data: this.expenses | ||||
|           data: this.expenses.map((expense) => expense / 100), | ||||
|         }, | ||||
|         { | ||||
|           label: 'Net Income', | ||||
| @ -170,34 +169,40 @@ export default { | ||||
|           pointHoverBorderWidth: 2, | ||||
|           pointRadius: 4, | ||||
|           pointHitRadius: 10, | ||||
|           data: this.income | ||||
|         } | ||||
|       ] | ||||
|           data: this.income.map((_i) => _i / 100), | ||||
|         }, | ||||
|       ], | ||||
|     } | ||||
|  | ||||
|     this.myLineChart = new Chart(context, { | ||||
|       type: 'line', | ||||
|       data: data, | ||||
|       options: options | ||||
|       options: options, | ||||
|     }) | ||||
|   }, | ||||
|  | ||||
|   methods: { | ||||
|     update () { | ||||
|     update() { | ||||
|       this.myLineChart.data.labels = this.labels | ||||
|       this.myLineChart.data.datasets[0].data = this.invoices | ||||
|       this.myLineChart.data.datasets[1].data = this.receipts | ||||
|       this.myLineChart.data.datasets[2].data = this.expenses | ||||
|       this.myLineChart.data.datasets[3].data = this.income | ||||
|       this.myLineChart.data.datasets[0].data = this.invoices.map( | ||||
|         (invoice) => invoice / 100 | ||||
|       ) | ||||
|       this.myLineChart.data.datasets[1].data = this.receipts.map( | ||||
|         (receipt) => receipt / 100 | ||||
|       ) | ||||
|       this.myLineChart.data.datasets[2].data = this.expenses.map( | ||||
|         (expense) => expense / 100 | ||||
|       ) | ||||
|       this.myLineChart.data.datasets[3].data = this.income.map((_i) => _i / 100) | ||||
|       this.myLineChart.update({ | ||||
|         lazy: true | ||||
|         lazy: true, | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     beforeDestroy () { | ||||
|     beforeDestroy() { | ||||
|       this.myLineChart.destroy() | ||||
|     } | ||||
|   } | ||||
|     }, | ||||
|   }, | ||||
| } | ||||
| </script> | ||||
|  | ||||
|  | ||||
| @ -1,72 +0,0 @@ | ||||
| <template> | ||||
|   <div class="graph-container"> | ||||
|     <canvas | ||||
|       id="graph" | ||||
|       ref="graph" /> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import Chart from 'chart.js' | ||||
|  | ||||
| export default { | ||||
|   props: { | ||||
|     labels: { | ||||
|       type: Array, | ||||
|       require: true, | ||||
|       default: Array | ||||
|     }, | ||||
|     values: { | ||||
|       type: Array, | ||||
|       require: true, | ||||
|       default: Array | ||||
|     }, | ||||
|     bgColors: { | ||||
|       type: Array, | ||||
|       require: true, | ||||
|       default: Array | ||||
|     }, | ||||
|     hoverBgColors: { | ||||
|       type: Array, | ||||
|       require: true, | ||||
|       default: Array | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   mounted () { | ||||
|     let context = this.$refs.graph.getContext('2d') | ||||
|  | ||||
|     let options = { | ||||
|       responsive: true, | ||||
|       maintainAspectRatio: false | ||||
|     } | ||||
|  | ||||
|     let data = { | ||||
|       labels: this.labels, | ||||
|       datasets: [ | ||||
|         { | ||||
|           data: this.values, | ||||
|           backgroundColor: this.bgColors, | ||||
|           hoverBackgroundColor: this.hoverBgColors | ||||
|         } | ||||
|       ] | ||||
|     } | ||||
|  | ||||
|     this.pieChart = new Chart(context, { | ||||
|       type: 'pie', | ||||
|       data: data, | ||||
|       options: options | ||||
|     }) | ||||
|   }, | ||||
|  | ||||
|   beforeDestroy () { | ||||
|     this.pieChart.destroy() | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
| .graph-container { | ||||
|   height: 300px; | ||||
| } | ||||
| </style> | ||||
| @ -1,95 +0,0 @@ | ||||
| <template> | ||||
|   <div class="graph-container easy-pie-chart"> | ||||
|     <svg width="100%" height="100%" viewBox="0 0 34 34" class="donut"> | ||||
|       <circle :stroke-width="strokeWidth" class="donut-segment" cx="17" cy="17" r="15.91549430918954" fill="transparent" :stroke="strokeColor" stroke-dasharray="100 0" /> | ||||
|       <circle :stroke-width="strokeWidth" :stroke="color" :stroke-dasharray="successProgress" class="donut-segment" cx="17" cy="17" r="15.91549430918954" fill="transparent" /> | ||||
|       <!-- <g class="chart-text"> | ||||
|         <text :style="'fill:' + color" x="48%" y="50%" class="chart-number" > | ||||
|           {{ progress }} | ||||
|         </text> | ||||
|         <text :style="'fill:' + color" x="73%" y="50%" class="chart-label" > | ||||
|           % | ||||
|         </text> | ||||
|       </g> --> | ||||
|     </svg> | ||||
|   </div> | ||||
| </template> | ||||
| <script> | ||||
| export default { | ||||
|   props: { | ||||
|     values: { | ||||
|       type: Number, | ||||
|       require: true, | ||||
|       default: 100 | ||||
|     }, | ||||
|     strokeWidth: { | ||||
|       type: Number, | ||||
|       require: false, | ||||
|       default: 1.2 | ||||
|     }, | ||||
|     strokeColor: { | ||||
|       type: String, | ||||
|       require: true, | ||||
|       default: '#eeeeee' | ||||
|     }, | ||||
|     color: { | ||||
|       type: String, | ||||
|       require: true, | ||||
|       default: '#007dcc' | ||||
|     } | ||||
|   }, | ||||
|   data () { | ||||
|     return { | ||||
|       progress: 0 | ||||
|     } | ||||
|   }, | ||||
|   watch: { | ||||
|     values (newvalue, oldvalue) { | ||||
|       if (newvalue !== oldvalue) { | ||||
|         this.setProgress() | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     successProgress () { | ||||
|       return this.progress + ' ' + (100 - this.progress) | ||||
|     }, | ||||
|     remainProgress () { | ||||
|       return 100 - this.progress + ' ' + this.progress | ||||
|     }, | ||||
|   }, | ||||
|   mounted () { | ||||
|     this.setProgress() | ||||
|   }, | ||||
|   methods: { | ||||
|     setProgress () { | ||||
|       let self = this | ||||
|       for (let i = 0; i < this.values; i++) { | ||||
|         setTimeout(function () { | ||||
|           ++self.progress | ||||
|         }, 15 * i) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
| <style scoped> | ||||
| .chart-text { | ||||
|   font: 6px "Montserrat", Arial, sans-serif; | ||||
|   fill: #000; | ||||
|   -moz-transform: translateY(0.25em); | ||||
|   -ms-transform: translateY(0.25em); | ||||
|   -webkit-transform: translateY(0.25em); | ||||
|   transform: translateY(0.5em); | ||||
| } | ||||
| .chart-number { | ||||
|   font-size: 8px; | ||||
|   line-height: 1; | ||||
|   text-anchor: middle; | ||||
| } | ||||
| .chart-label { | ||||
|   font-size: 5px; | ||||
|   text-transform: uppercase; | ||||
|   text-anchor: middle; | ||||
| } | ||||
| </style> | ||||
| @ -1,16 +1,16 @@ | ||||
| export default { | ||||
|   toggleSidebar () { | ||||
|   toggleSidebar() { | ||||
|     let icon = document.getElementsByClassName('hamburger')[0] | ||||
|     document.body.classList.toggle('sidebar-open') | ||||
|     icon.classList.toggle('is-active') | ||||
|   }, | ||||
|  | ||||
|   addClass (el, className) { | ||||
|   addClass(el, className) { | ||||
|     if (el.classList) el.classList.add(className) | ||||
|     else el.className += ' ' + className | ||||
|   }, | ||||
|  | ||||
|   hasClass (el, className) { | ||||
|   hasClass(el, className) { | ||||
|     const hasClass = el.classList | ||||
|       ? el.classList.contains(className) | ||||
|       : new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className) | ||||
| @ -18,33 +18,38 @@ export default { | ||||
|     return hasClass | ||||
|   }, | ||||
|  | ||||
|   reset (prefix) { | ||||
|   reset(prefix) { | ||||
|     let regx = new RegExp('\\b' + prefix + '(.*)?\\b', 'g') | ||||
|     document.body.className = document.body.className.replace(regx, '') | ||||
|   }, | ||||
|  | ||||
|   setLayout (layoutName) { | ||||
|   setLayout(layoutName) { | ||||
|     this.reset('layout-') | ||||
|     document.body.classList.add('layout-' + layoutName) | ||||
|   }, | ||||
|  | ||||
|   setSkin (skinName) { | ||||
|   setSkin(skinName) { | ||||
|     this.reset('skin-') | ||||
|     document.body.classList.add('skin-' + skinName) | ||||
|   }, | ||||
|  | ||||
|   setLogo (logoSrc) { | ||||
|   setLogo(logoSrc) { | ||||
|     document.getElementById('logo-desk').src = logoSrc | ||||
|   }, | ||||
|  | ||||
|   formatMoney (amount, currency = 0) { | ||||
|   formatMoney(amount, currency = 0) { | ||||
|     if (!currency) { | ||||
|       currency = {precision: 2, thousand_separator: ',', decimal_separator: '.', symbol: '$'} | ||||
|       currency = { | ||||
|         precision: 2, | ||||
|         thousand_separator: ',', | ||||
|         decimal_separator: '.', | ||||
|         symbol: '$', | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     amount = amount / 100 | ||||
|  | ||||
|     let {precision, decimal_separator, thousand_separator, symbol} = currency | ||||
|     let { precision, decimal_separator, thousand_separator, symbol } = currency | ||||
|  | ||||
|     try { | ||||
|       precision = Math.abs(precision) | ||||
| @ -52,25 +57,44 @@ export default { | ||||
|  | ||||
|       const negativeSign = amount < 0 ? '-' : '' | ||||
|  | ||||
|       let i = parseInt(amount = Math.abs(Number(amount) || 0).toFixed(precision)).toString() | ||||
|       let j = (i.length > 3) ? i.length % 3 : 0 | ||||
|       let i = parseInt( | ||||
|         (amount = Math.abs(Number(amount) || 0).toFixed(precision)) | ||||
|       ).toString() | ||||
|       let j = i.length > 3 ? i.length % 3 : 0 | ||||
|  | ||||
|       let moneySymbol = `<span style="font-family: sans-serif">${symbol}</span>` | ||||
|  | ||||
|       return moneySymbol + ' ' + negativeSign + (j ? i.substr(0, j) + thousand_separator : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, '$1' + thousand_separator) + (precision ? decimal_separator + Math.abs(amount - i).toFixed(precision).slice(2) : '') | ||||
|       return ( | ||||
|         moneySymbol + | ||||
|         ' ' + | ||||
|         negativeSign + | ||||
|         (j ? i.substr(0, j) + thousand_separator : '') + | ||||
|         i.substr(j).replace(/(\d{3})(?=\d)/g, '$1' + thousand_separator) + | ||||
|         (precision | ||||
|           ? decimal_separator + | ||||
|             Math.abs(amount - i) | ||||
|               .toFixed(precision) | ||||
|               .slice(2) | ||||
|           : '') | ||||
|       ) | ||||
|     } catch (e) { | ||||
|       console.log(e) | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   formatGraphMoney (amount, currency = 0) { | ||||
|   formatGraphMoney(amount, currency = 0) { | ||||
|     if (!currency) { | ||||
|       currency = {precision: 2, thousand_separator: ',', decimal_separator: '.', symbol: '$'} | ||||
|       currency = { | ||||
|         precision: 2, | ||||
|         thousand_separator: ',', | ||||
|         decimal_separator: '.', | ||||
|         symbol: '$', | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     amount = amount / 100 | ||||
|  | ||||
|     let {precision, decimal_separator, thousand_separator, symbol} = currency | ||||
|     let { precision, decimal_separator, thousand_separator, symbol } = currency | ||||
|  | ||||
|     try { | ||||
|       precision = Math.abs(precision) | ||||
| @ -78,25 +102,84 @@ export default { | ||||
|  | ||||
|       const negativeSign = amount < 0 ? '-' : '' | ||||
|  | ||||
|       let i = parseInt(amount = Math.abs(Number(amount) || 0).toFixed(precision)).toString() | ||||
|       let j = (i.length > 3) ? i.length % 3 : 0 | ||||
|       let i = parseInt( | ||||
|         (amount = Math.abs(Number(amount) || 0).toFixed(precision)) | ||||
|       ).toString() | ||||
|       let j = i.length > 3 ? i.length % 3 : 0 | ||||
|  | ||||
|       let moneySymbol = `${symbol}` | ||||
|  | ||||
|       return moneySymbol + ' ' + negativeSign + (j ? i.substr(0, j) + thousand_separator : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, '$1' + thousand_separator) + (precision ? decimal_separator + Math.abs(amount - i).toFixed(precision).slice(2) : '') | ||||
|       return ( | ||||
|         moneySymbol + | ||||
|         ' ' + | ||||
|         negativeSign + | ||||
|         (j ? i.substr(0, j) + thousand_separator : '') + | ||||
|         i.substr(j).replace(/(\d{3})(?=\d)/g, '$1' + thousand_separator) + | ||||
|         (precision | ||||
|           ? decimal_separator + | ||||
|             Math.abs(amount - i) | ||||
|               .toFixed(precision) | ||||
|               .slice(2) | ||||
|           : '') | ||||
|       ) | ||||
|     } catch (e) { | ||||
|       console.log(e) | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   checkValidUrl (url) { | ||||
|     let pattern = new RegExp('^(https?:\\/\\/)?' + // protocol | ||||
|   checkValidUrl(url) { | ||||
|     if ( | ||||
|       url.includes('http://localhost') || | ||||
|       url.includes('http://127.0.0.1') || | ||||
|       url.includes('https://localhost') || | ||||
|       url.includes('https://127.0.0.1') | ||||
|     ) { | ||||
|       return true | ||||
|     } | ||||
|     let pattern = new RegExp( | ||||
|       '^(https?:\\/\\/)?' + // protocol | ||||
|       '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name | ||||
|       '((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address | ||||
|       '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path | ||||
|       '(\\?[;&a-z\\d%_.~+=-]*)?' + // query string | ||||
|       '(\\#[-a-z\\d_]*)?$', 'i') // fragment locator | ||||
|         '(\\#[-a-z\\d_]*)?$', | ||||
|       'i' | ||||
|     ) // fragment locator | ||||
|  | ||||
|     return !!pattern.test(url) | ||||
|   } | ||||
|   }, | ||||
|  | ||||
|   fallbackCopyTextToClipboard(text) { | ||||
|     var textArea = document.createElement('textarea') | ||||
|     textArea.value = text | ||||
|     // Avoid scrolling to bottom | ||||
|     textArea.style.top = '0' | ||||
|     textArea.style.left = '0' | ||||
|     textArea.style.position = 'fixed' | ||||
|     document.body.appendChild(textArea) | ||||
|     textArea.focus() | ||||
|     textArea.select() | ||||
|     try { | ||||
|       var successful = document.execCommand('copy') | ||||
|       var msg = successful ? 'successful' : 'unsuccessful' | ||||
|       console.log('Fallback: Copying text command was ' + msg) | ||||
|     } catch (err) { | ||||
|       console.error('Fallback: Oops, unable to copy', err) | ||||
|     } | ||||
|     document.body.removeChild(textArea) | ||||
|   }, | ||||
|   copyTextToClipboard(text) { | ||||
|     if (!navigator.clipboard) { | ||||
|       this.fallbackCopyTextToClipboard(text) | ||||
|       return | ||||
|     } | ||||
|     navigator.clipboard.writeText(text).then( | ||||
|       function () { | ||||
|         return true | ||||
|       }, | ||||
|       function (err) { | ||||
|         return false | ||||
|       } | ||||
|     ) | ||||
|   }, | ||||
| } | ||||
|  | ||||
| @ -22,6 +22,11 @@ | ||||
|     "to_date": "إلى تاريخ", | ||||
|     "from": "من", | ||||
|     "to": "إلى", | ||||
|     "sort_by": "ترتيب حسب", | ||||
|     "ascending": "تصاعدي", | ||||
|     "descending": "تنازلي", | ||||
|     "subject": "موضوع", | ||||
|     "message": "رسالة", | ||||
|     "go_back": "إلى الخلف", | ||||
|     "back_to_login": "العودة إلى تسجيل الدخول؟", | ||||
|     "home": "الرئيسية", | ||||
| @ -62,14 +67,14 @@ | ||||
|     "four_zero_four": "404", | ||||
|     "you_got_lost": "عفواً! يبدو أنك قد تهت!", | ||||
|     "go_home": "عودة إلى الرئيسية", | ||||
|  | ||||
|     "setting_updated": "تم تحديث الإعدادات بنجاح", | ||||
|     "select_state": "اختر الولاية/المنطقة", | ||||
|     "select_country": "اختر الدولة", | ||||
|     "select_city": "اختر المدينة", | ||||
|     "street_1": "عنوان الشارع 1", | ||||
|     "street_2": "عنوان الشارع 2", | ||||
|     "action_failed": "فشلت العملية" | ||||
|     "action_failed": "فشلت العملية", | ||||
|     "retry": "أعد المحاولة" | ||||
|   }, | ||||
|   "dashboard": { | ||||
|     "select_year": "اختر السنة", | ||||
| @ -112,8 +117,8 @@ | ||||
|   "tax_types": { | ||||
|     "name": "الاسم", | ||||
|     "description": "الوصف", | ||||
|     "percent": "Percent", | ||||
|     "compound_tax": "Compound Tax" | ||||
|     "percent": "نسبه مئويه", | ||||
|     "compound_tax": "الضريبة المركبة" | ||||
|   }, | ||||
|   "customers": { | ||||
|     "title": "العملاء", | ||||
| @ -155,7 +160,7 @@ | ||||
|     "select_a_customer": "اختر العميل", | ||||
|     "type_or_click": "اكتب أو اضغط للاختيار", | ||||
|  | ||||
|     "confirm_delete": "لن تكون قادراً على استرجاع هذا العميل | لن تكون قادراً على استرجاع هؤلاء العملاء", | ||||
|     "confirm_delete": "لن تتمكن من استرداد هذا العميل وجميع الفواتير والتقديرات والمدفوعات ذات الصلة. | لن تتمكن من استرداد هؤلاء العملاء وجميع الفواتير والتقديرات والمدفوعات ذات الصلة.", | ||||
|     "created_message": "تم إنشاء العملاء بنجاح", | ||||
|     "updated_message": "تم تحديث العملاء بنجاح", | ||||
|     "deleted_message": "تم حذف العملاء بنجاح | تم حذف العميل بنجاح" | ||||
| @ -329,6 +334,9 @@ | ||||
|     "no_matching_invoices": "لا يوجد فواتير مطابقة!", | ||||
|     "mark_as_sent_successfully": "تم تحديد الفاتورة كمرسلة بنجاح", | ||||
|     "send_invoice_successfully": "تم إرسال الفاتورة بنجاح", | ||||
|     "cloned_successfully": "تم استنساخ الفاتورة بنجاح", | ||||
|     "clone_invoice": "استنساخ الفاتورة", | ||||
|     "confirm_clone": "سيتم استنساخ هذه الفاتورة في فاتورة جديدة", | ||||
|     "item": { | ||||
|       "title": "اسم الصنف", | ||||
|       "description": "الوصف", | ||||
| @ -370,7 +378,7 @@ | ||||
|       "description": "الوصف", | ||||
|       "quantity": "الكمية", | ||||
|       "price": "السعر", | ||||
|           "discount": "الخصم", | ||||
|       "discount": "الخصم", | ||||
|       "total": "الإجمالي", | ||||
|       "total_discount": "إجمالي الخصم", | ||||
|       "sub_total": "حاصل الجمع", | ||||
| @ -412,6 +420,8 @@ | ||||
|     "title": "النفقات", | ||||
|     "expenses_list": "قائمة النفقات", | ||||
|     "expense_title": "Title", | ||||
|     "select_a_customer": "حدد عميلاً", | ||||
|     "customer": "العميل", | ||||
|     "contact": "تواصل", | ||||
|     "category": "الفئة", | ||||
|     "from_date": "من تاريخ", | ||||
| @ -601,65 +611,87 @@ | ||||
|       "updated_message": "تم تحديث معلومات الشركة بنجاح" | ||||
|     }, | ||||
|     "customization": { | ||||
|         "customization": "التخصيص", | ||||
|         "save": "حفظ", | ||||
|         "addresses": { | ||||
|             "title": "العنوان", | ||||
|             "section_description": "يمكنك ضبط عنوان إرسال فواتير العملاء وتنسيق عنوان شحن العملاء (معروض في PDF فقط).", | ||||
|             "customer_billing_address": "عنوان فواتير العميل", | ||||
|             "customer_shipping_address": "عنوان الشحن للعميل", | ||||
|             "company_address": "عنوان الشركة", | ||||
|             "insert_fields": "أضف حقل", | ||||
|             "contact": "تواصل", | ||||
|             "address": "العنوان", | ||||
|             "display_name": "الاسم الظاهر", | ||||
|             "primary_contact_name": "مسؤول التواصل الرئيسي", | ||||
|             "email": "البريد الإلكتروني", | ||||
|             "website": "موقع الإنترنت", | ||||
|             "name": "الاسم", | ||||
|             "country": "الدولة", | ||||
|             "state": "الولاية/المنطقة", | ||||
|             "city": "المدينة", | ||||
|             "company_name": "اسم الشركة", | ||||
|             "address_street_1": "عنوان الشارع 1", | ||||
|             "address_street_2": "عنوان الشارع 2", | ||||
|             "phone": "الهاتف", | ||||
|             "zip_code": "الرمز البريدي", | ||||
|             "address_setting_updated": "تم تحديث العنوان بنجاح" | ||||
|         }, | ||||
|         "updated_message": "تم تحديث معلومات الشركة بنجاح", | ||||
|       "customization": "التخصيص", | ||||
|       "save": "حفظ", | ||||
|       "addresses": { | ||||
|         "title": "العنوان", | ||||
|         "section_description": "يمكنك ضبط عنوان إرسال فواتير العملاء وتنسيق عنوان شحن العملاء (معروض في PDF فقط).", | ||||
|         "customer_billing_address": "عنوان فواتير العميل", | ||||
|         "customer_shipping_address": "عنوان الشحن للعميل", | ||||
|         "company_address": "عنوان الشركة", | ||||
|         "insert_fields": "أضف حقل", | ||||
|         "contact": "تواصل", | ||||
|         "address": "العنوان", | ||||
|         "display_name": "الاسم الظاهر", | ||||
|         "primary_contact_name": "مسؤول التواصل الرئيسي", | ||||
|         "email": "البريد الإلكتروني", | ||||
|         "website": "موقع الإنترنت", | ||||
|         "name": "الاسم", | ||||
|         "country": "الدولة", | ||||
|         "state": "الولاية/المنطقة", | ||||
|         "city": "المدينة", | ||||
|         "company_name": "اسم الشركة", | ||||
|         "address_street_1": "عنوان الشارع 1", | ||||
|         "address_street_2": "عنوان الشارع 2", | ||||
|         "phone": "الهاتف", | ||||
|         "zip_code": "الرمز البريدي", | ||||
|         "address_setting_updated": "تم تحديث العنوان بنجاح" | ||||
|       }, | ||||
|       "updated_message": "تم تحديث معلومات الشركة بنجاح", | ||||
|  | ||||
|         "invoices": { | ||||
|             "title": "الفواتير", | ||||
|             "notes": "ملاحظات", | ||||
|             "invoice_prefix": "بادئة رقم الفاتورة", | ||||
|             "invoice_settings": "إعدادات الفاتورة", | ||||
|             "autogenerate_invoice_number": "ترقيم آلي للفاتورة", | ||||
|             "invoice_setting_description": "تعطيل الترقيم الآلي ، إذا كنت لا ترغب في إنشاء أرقام الفاتورة تلقائيًا في كل مرة تقوم فيها بإنشاء فاتورة جديدة.", | ||||
|             "enter_invoice_prefix": "أدخل بادئة رقم الفاتورة", | ||||
|             "terms_and_conditions": "الأحكام والشروط", | ||||
|             "invoice_setting_updated": "تم تحديث إعداد الفاتورة بنجاح" | ||||
|         }, | ||||
|       "invoices": { | ||||
|         "title": "الفواتير", | ||||
|         "notes": "ملاحظات", | ||||
|         "invoice_prefix": "بادئة رقم الفاتورة", | ||||
|         "invoice_settings": "إعدادات الفاتورة", | ||||
|         "autogenerate_invoice_number": "ترقيم آلي للفاتورة", | ||||
|         "invoice_setting_description": "تعطيل الترقيم الآلي ، إذا كنت لا ترغب في إنشاء أرقام الفاتورة تلقائيًا في كل مرة تقوم فيها بإنشاء فاتورة جديدة.", | ||||
|         "enter_invoice_prefix": "أدخل بادئة رقم الفاتورة", | ||||
|         "terms_and_conditions": "الأحكام والشروط", | ||||
|         "invoice_setting_updated": "تم تحديث إعداد الفاتورة بنجاح" | ||||
|       }, | ||||
|  | ||||
|         "estimates": { | ||||
|             "title": "التقديرات", | ||||
|             "estimate_prefix": "بادئة رقم التقدير", | ||||
|             "estimate_settings": "إعدادت التقدير", | ||||
|             "autogenerate_estimate_number": "ترقيم آلي للتقدير", | ||||
|             "estimate_setting_description": "تعطيل الترقيم الآلي ، إذا كنت لا ترغب في إنشاء أرقام التقديرات تلقائيًا في كل مرة تقوم فيها بإنشاء تقدير جديد.", | ||||
|             "enter_estimate_prefix": "أدخل بادئة رقم التقدير", | ||||
|             "estimate_setting_updated": "تم تحديث إعدادات التقدير بنجاح" | ||||
|         }, | ||||
|       "estimates": { | ||||
|         "title": "التقديرات", | ||||
|         "estimate_prefix": "بادئة رقم التقدير", | ||||
|         "estimate_settings": "إعدادت التقدير", | ||||
|         "autogenerate_estimate_number": "ترقيم آلي للتقدير", | ||||
|         "estimate_setting_description": "تعطيل الترقيم الآلي ، إذا كنت لا ترغب في إنشاء أرقام التقديرات تلقائيًا في كل مرة تقوم فيها بإنشاء تقدير جديد.", | ||||
|         "enter_estimate_prefix": "أدخل بادئة رقم التقدير", | ||||
|         "estimate_setting_updated": "تم تحديث إعدادات التقدير بنجاح" | ||||
|       }, | ||||
|  | ||||
|         "payments": { | ||||
|             "title": "المدفوعات", | ||||
|             "payment_prefix": "بادئة رقم الدفعة", | ||||
|             "payment_settings": "إعدادات الدفعة", | ||||
|             "autogenerate_payment_number": "ترقيم آلي للمدفوعات", | ||||
|             "payment_setting_description": "تعطيل الترقيم الآلي ، إذا كنت لا ترغب في إنشاء أرقام الدفعة تلقائيًا في كل مرة تقوم فيها بإنشاء دفعة جديدة.", | ||||
|             "enter_payment_prefix": "أدخل بادئة رقم الدفعة", | ||||
|             "payment_setting_updated": "تم تحديث إعدادات الدفعة بنجاح" | ||||
|         } | ||||
|       "payments": { | ||||
|         "title": "المدفوعات", | ||||
|         "payment_prefix": "بادئة رقم الدفعة", | ||||
|         "payment_settings": "إعدادات الدفعة", | ||||
|         "autogenerate_payment_number": "ترقيم آلي للمدفوعات", | ||||
|         "payment_setting_description": "تعطيل الترقيم الآلي ، إذا كنت لا ترغب في إنشاء أرقام الدفعة تلقائيًا في كل مرة تقوم فيها بإنشاء دفعة جديدة.", | ||||
|         "enter_payment_prefix": "أدخل بادئة رقم الدفعة", | ||||
|         "payment_setting_updated": "تم تحديث إعدادات الدفعة بنجاح", | ||||
|         "payment_mode": "طريقة الدفع", | ||||
|         "add_payment_mode": "أضف وضع الدفع", | ||||
|         "edit_payment_mode": "تحرير وضع الدفع", | ||||
|         "mode_name": "اسم الوضع", | ||||
|         "payment_mode_added": "تمت إضافة وضع الدفع", | ||||
|         "payment_mode_updated": "تم تحديث وضع الدفع", | ||||
|         "payment_mode_confirm_delete": "لن تتمكن من استعادة وضع الدفع هذا", | ||||
|         "already_in_use": "وضع الدفع قيد الاستخدام بالفعل", | ||||
|         "deleted_message": "تم حذف وضع الدفع بنجاح" | ||||
|       }, | ||||
|  | ||||
|       "items": { | ||||
|         "title": "العناصر", | ||||
|         "units": "الوحدات", | ||||
|         "add_item_unit": "إضافة وحدة عنصر", | ||||
|         "edit_item_unit": "تحرير وحدة العناصر", | ||||
|         "unit_name": "إسم الوحدة", | ||||
|         "item_unit_added": "تمت إضافة وحدة العنصر", | ||||
|         "item_unit_updated": "تم تحديث وحدة العنصر", | ||||
|         "item_unit_confirm_delete": "لن تتمكن من استرداد وحدة العنصر هذه", | ||||
|         "already_in_use": "وحدة العنصر قيد الاستخدام بالفعل", | ||||
|         "deleted_message": "تم حذف وحدة العنصر بنجاح" | ||||
|       } | ||||
|     }, | ||||
|     "account_settings": { | ||||
|       "profile_picture": "صورة الملف الشخصي", | ||||
| @ -693,6 +725,7 @@ | ||||
|     "tax_types": { | ||||
|       "title": "أنواع الضرائب", | ||||
|       "add_tax": "أضف ضريبة", | ||||
|       "edit_tax": "تحرير الضريبة", | ||||
|       "description": "يمكنك إضافة أو إزالة الضرائب كما يحلو لك. النظام يدعم الضرائب على العناصر الفردية وكذلك على الفاتورة.", | ||||
|       "add_new_tax": "إضافة ضريبة جديدة", | ||||
|       "tax_settings": "إعدادات الضريبة", | ||||
| @ -713,6 +746,8 @@ | ||||
|       "action": "إجراء", | ||||
|       "description": "الفئات مطلوبة لإضافة إدخالات النفقات. يمكنك إضافة أو إزالة هذه الفئات وفقًا لتفضيلاتك.", | ||||
|       "add_new_category": "إضافة فئة جديدة", | ||||
|       "add_category": "إضافة فئة", | ||||
|       "edit_category": "تحرير الفئة", | ||||
|       "category_name": "اسم الفئة", | ||||
|       "category_description": "الوصف", | ||||
|       "created_message": "تم إنشاء نوع النفقات بنجاح", | ||||
| @ -750,7 +785,14 @@ | ||||
|       "progress_text": "سوف يستغرق التحديث بضع دقائق. يرجى عدم تحديث الشاشة أو إغلاق النافذة قبل انتهاء التحديث", | ||||
|       "update_success": "تم تحديث النظام! يرجى الانتظار حتى يتم إعادة تحميل نافذة المتصفح تلقائيًا.", | ||||
|       "latest_message": "لا يوجد تحديثات متوفرة! لديك حالياً أحدث نسخة.", | ||||
|       "current_version": "النسخة الحالية" | ||||
|       "current_version": "النسخة الحالية", | ||||
|       "download_zip_file": "تنزيل ملف ZIP", | ||||
|       "unzipping_package": "حزمة فك الضغط", | ||||
|       "copying_files": "نسخ الملفات", | ||||
|       "running_migrations": "إدارة عمليات الترحيل", | ||||
|       "finishing_update": "تحديث التشطيب", | ||||
|       "update_failed": "فشل التحديث", | ||||
|       "update_failed_text": "آسف! فشل التحديث الخاص بك في: {step} خطوة"      | ||||
|     } | ||||
|   }, | ||||
|   "wizard": { | ||||
| @ -804,22 +846,22 @@ | ||||
|       "permission_desc": "فيما يلي قائمة أذونات المجلد المطلوبة حتى يعمل التطبيق. في حالة فشل فحص الإذن ، تأكد من تحديث أذونات المجلد." | ||||
|     }, | ||||
|     "mail": { | ||||
|         "host": "خادم البريد", | ||||
|         "port": "منفذ البريد", | ||||
|         "driver": "مشغل البريد", | ||||
|         "secret": "سري", | ||||
|         "mailgun_secret": "الرمز السري لـ Mailgun", | ||||
|         "mailgun_domain": "المجال", | ||||
|         "mailgun_endpoint": "النهاية الطرفية لـ Mailgun", | ||||
|         "ses_secret": "SES الرمز السري", | ||||
|         "ses_key": "SES مفتاح", | ||||
|         "password": "كلمة مرور البريد الالكتروني", | ||||
|         "username": "اسم المستخدم للبريد الإلكتروني", | ||||
|         "mail_config": "إعدادات البريد الالكتروني", | ||||
|         "from_name": "اسم المرسل", | ||||
|         "from_mail": "عنوان البريد الالكتروني للمرسل", | ||||
|         "encryption": "صيغة ا لتشفير", | ||||
|         "mail_config_desc": "أدناه هو نموذج لتكوين برنامج تشغيل البريد الإلكتروني لإرسال رسائل البريد الإلكتروني من التطبيق. يمكنك أيضًا تهيئة موفري الجهات الخارجية مثل Sendgrid و SES إلخ." | ||||
|       "host": "خادم البريد", | ||||
|       "port": "منفذ البريد", | ||||
|       "driver": "مشغل البريد", | ||||
|       "secret": "سري", | ||||
|       "mailgun_secret": "الرمز السري لـ Mailgun", | ||||
|       "mailgun_domain": "المجال", | ||||
|       "mailgun_endpoint": "النهاية الطرفية لـ Mailgun", | ||||
|       "ses_secret": "SES الرمز السري", | ||||
|       "ses_key": "SES مفتاح", | ||||
|       "password": "كلمة مرور البريد الالكتروني", | ||||
|       "username": "اسم المستخدم للبريد الإلكتروني", | ||||
|       "mail_config": "إعدادات البريد الالكتروني", | ||||
|       "from_name": "اسم المرسل", | ||||
|       "from_mail": "عنوان البريد الالكتروني للمرسل", | ||||
|       "encryption": "صيغة ا لتشفير", | ||||
|       "mail_config_desc": "أدناه هو نموذج لتكوين برنامج تشغيل البريد الإلكتروني لإرسال رسائل البريد الإلكتروني من التطبيق. يمكنك أيضًا تهيئة موفري الجهات الخارجية مثل Sendgrid و SES إلخ." | ||||
|     }, | ||||
|     "req": { | ||||
|       "system_req": "متطلبات النظام", | ||||
|  | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -13,6 +13,7 @@ | ||||
|   }, | ||||
|   "general": { | ||||
|     "view_pdf": "View PDF", | ||||
|     "copy_pdf_url": "Copy PDF Url", | ||||
|     "download_pdf": "Download PDF", | ||||
|     "save": "Save", | ||||
|     "cancel": "Cancel", | ||||
| @ -70,14 +71,14 @@ | ||||
|     "go_home": "Go Home", | ||||
|     "test_mail_conf": "Test Mail Configuration", | ||||
|     "send_mail_successfully": "Mail sent successfully", | ||||
|  | ||||
|     "setting_updated": "Setting updated successfully", | ||||
|     "select_state": "Select state", | ||||
|     "select_country": "Select Country", | ||||
|     "select_city": "Select City", | ||||
|     "street_1": "Street 1", | ||||
|     "street_2": "Street 2", | ||||
|     "action_failed": "Action Failed" | ||||
|     "action_failed": "Action Failed", | ||||
|     "retry": "Retry" | ||||
|   }, | ||||
|   "dashboard": { | ||||
|     "select_year": "Select year", | ||||
| @ -163,7 +164,7 @@ | ||||
|     "select_a_customer": "Select a customer", | ||||
|     "type_or_click": "Type or click to select", | ||||
|  | ||||
|     "confirm_delete": "You will not be able to recover this Customer | You will not be able to recover these Customers", | ||||
|     "confirm_delete": "You will not be able to recover this customer and all the related Invoices, Estimates and Payments. | You will not be able to recover these customers and all the related Invoices, Estimates and Payments.", | ||||
|     "created_message": "Customer created successfully", | ||||
|     "updated_message": "Customer updated successfully", | ||||
|     "deleted_message": "Customer deleted successfully | Customers deleted successfully" | ||||
| @ -230,6 +231,7 @@ | ||||
|     "convert_to_invoice": "Convert to Invoice", | ||||
|     "mark_as_sent": "Mark as Sent", | ||||
|     "send_estimate": "Send Estimate", | ||||
|     "resend_estimate": "Resend Estimate", | ||||
|     "record_payment": "Record Payment", | ||||
|     "add_estimate": "Add Estimate", | ||||
|     "save_estimate": "Save Estimate", | ||||
| @ -316,6 +318,7 @@ | ||||
|     "notes": "Notes", | ||||
|     "view": "View", | ||||
|     "send_invoice": "Send Invoice", | ||||
|     "resend_invoice": "Resend Invoice", | ||||
|     "invoice_template": "Invoice Template", | ||||
|     "template": "Template", | ||||
|     "mark_as_sent": "Mark as sent", | ||||
| @ -426,7 +429,9 @@ | ||||
|   "expenses": { | ||||
|     "title": "Expenses", | ||||
|     "expenses_list": "Expenses List", | ||||
|     "select_a_customer": "Select a customer", | ||||
|     "expense_title": "Title", | ||||
|     "customer": "Customer", | ||||
|     "contact": "Contact", | ||||
|     "category": "Category", | ||||
|     "from_date": "From Date", | ||||
| @ -616,85 +621,87 @@ | ||||
|       "updated_message": "Company information updated successfully" | ||||
|     }, | ||||
|     "customization": { | ||||
|         "customization": "customization", | ||||
|         "save": "Save", | ||||
|         "addresses": { | ||||
|             "title": "Addresses", | ||||
|             "section_description": "You can set Customer Billing Address and Customer Shipping Address Format (Displayed in PDF only). ", | ||||
|             "customer_billing_address": "Customer Billing Address", | ||||
|             "customer_shipping_address": "Customer Shipping Address", | ||||
|             "company_address": "Company Address", | ||||
|             "insert_fields": "Insert Fields", | ||||
|             "contact": "Contact", | ||||
|             "address": "Address", | ||||
|             "display_name": "Display Name", | ||||
|             "primary_contact_name": "Primary Contact Name", | ||||
|             "email": "Email", | ||||
|             "website": "Website", | ||||
|             "name": "Name", | ||||
|             "country": "Country", | ||||
|             "state": "State", | ||||
|             "city": "City", | ||||
|             "company_name": "Company Name", | ||||
|             "address_street_1": "Address Street 1", | ||||
|             "address_street_2": "Address Street 2", | ||||
|             "phone": "Phone", | ||||
|             "zip_code": "Zip Code", | ||||
|             "address_setting_updated": "Address Setting updated successfully" | ||||
|         }, | ||||
|         "updated_message": "Company information updated successfully", | ||||
|       "customization": "customization", | ||||
|       "save": "Save", | ||||
|       "addresses": { | ||||
|         "title": "Addresses", | ||||
|         "section_description": "You can set Customer Billing Address and Customer Shipping Address Format (Displayed in PDF only). ", | ||||
|         "customer_billing_address": "Customer Billing Address", | ||||
|         "customer_shipping_address": "Customer Shipping Address", | ||||
|         "company_address": "Company Address", | ||||
|         "insert_fields": "Insert Fields", | ||||
|         "contact": "Contact", | ||||
|         "address": "Address", | ||||
|         "display_name": "Display Name", | ||||
|         "primary_contact_name": "Primary Contact Name", | ||||
|         "email": "Email", | ||||
|         "website": "Website", | ||||
|         "name": "Name", | ||||
|         "country": "Country", | ||||
|         "state": "State", | ||||
|         "city": "City", | ||||
|         "company_name": "Company Name", | ||||
|         "address_street_1": "Address Street 1", | ||||
|         "address_street_2": "Address Street 2", | ||||
|         "phone": "Phone", | ||||
|         "zip_code": "Zip Code", | ||||
|         "address_setting_updated": "Address Setting updated successfully" | ||||
|       }, | ||||
|       "updated_message": "Company information updated successfully", | ||||
|  | ||||
|         "invoices": { | ||||
|             "title": "Invoices", | ||||
|             "notes": "Notes", | ||||
|             "invoice_prefix": "Invoice Prefix", | ||||
|             "invoice_settings": "Invoice Settings", | ||||
|             "autogenerate_invoice_number": "Auto-generate Invoice Number", | ||||
|             "invoice_setting_description": "Disable this, If you don't wish to auto-generate invoice numbers each time you create a new invoice.", | ||||
|             "enter_invoice_prefix": "Enter invoice prefix", | ||||
|             "terms_and_conditions": "Terms and Conditions", | ||||
|             "invoice_setting_updated": "Invoice Setting updated successfully" | ||||
|         }, | ||||
|       "invoices": { | ||||
|         "title": "Invoices", | ||||
|         "notes": "Notes", | ||||
|         "invoice_prefix": "Invoice Prefix", | ||||
|         "invoice_settings": "Invoice Settings", | ||||
|         "autogenerate_invoice_number": "Auto-generate Invoice Number", | ||||
|         "invoice_setting_description": "Disable this, If you don't wish to auto-generate invoice numbers each time you create a new invoice.", | ||||
|         "enter_invoice_prefix": "Enter invoice prefix", | ||||
|         "terms_and_conditions": "Terms and Conditions", | ||||
|         "invoice_setting_updated": "Invoice Setting updated successfully" | ||||
|       }, | ||||
|  | ||||
|         "estimates": { | ||||
|             "title": "Estimates", | ||||
|             "estimate_prefix": "Estimate Prefix", | ||||
|             "estimate_settings": "Estimate Settings", | ||||
|             "autogenerate_estimate_number": "Auto-generate Estimate Number", | ||||
|             "estimate_setting_description": "Disable this, If you don't wish to auto-generate estimate numbers each time you create a new estimate.", | ||||
|             "enter_estimate_prefix": "Enter estmiate prefix", | ||||
|             "estimate_setting_updated": "Estimate Setting updated successfully" | ||||
|         }, | ||||
|       "estimates": { | ||||
|         "title": "Estimates", | ||||
|         "estimate_prefix": "Estimate Prefix", | ||||
|         "estimate_settings": "Estimate Settings", | ||||
|         "autogenerate_estimate_number": "Auto-generate Estimate Number", | ||||
|         "estimate_setting_description": "Disable this, If you don't wish to auto-generate estimate numbers each time you create a new estimate.", | ||||
|         "enter_estimate_prefix": "Enter estmiate prefix", | ||||
|         "estimate_setting_updated": "Estimate Setting updated successfully" | ||||
|       }, | ||||
|  | ||||
|         "payments": { | ||||
|             "title": "Payments", | ||||
|             "payment_prefix": "Payment Prefix", | ||||
|             "payment_settings": "Payment Settings", | ||||
|             "autogenerate_payment_number": "Auto-generate Payment Number", | ||||
|             "payment_setting_description": "Disable this, If you don't wish to auto-generate payment numbers each time you create a new payment.", | ||||
|             "enter_payment_prefix": "Enter Payment Prefix", | ||||
|             "payment_setting_updated": "Payment Setting updated successfully", | ||||
|             "payment_mode": "Payment Mode", | ||||
|             "add_payment_mode": "Add Payment Mode", | ||||
|             "mode_name": "Mode Name", | ||||
|             "payment_mode_added": "Payment Mode Added", | ||||
|             "payment_mode_updated": "Payment Mode Updated", | ||||
|             "payment_mode_confirm_delete":"You will not be able to recover this Payment Mode", | ||||
|             "already_in_use": "Payment Mode is already in use", | ||||
|             "deleted_message": "Payment Mode deleted successfully" | ||||
|         }, | ||||
|       "payments": { | ||||
|         "title": "Payments", | ||||
|         "payment_prefix": "Payment Prefix", | ||||
|         "payment_settings": "Payment Settings", | ||||
|         "autogenerate_payment_number": "Auto-generate Payment Number", | ||||
|         "payment_setting_description": "Disable this, If you don't wish to auto-generate payment numbers each time you create a new payment.", | ||||
|         "enter_payment_prefix": "Enter Payment Prefix", | ||||
|         "payment_setting_updated": "Payment Setting updated successfully", | ||||
|         "payment_mode": "Payment Mode", | ||||
|         "add_payment_mode": "Add Payment Mode", | ||||
|         "edit_payment_mode": "Edit Payment Mode", | ||||
|         "mode_name": "Mode Name", | ||||
|         "payment_mode_added": "Payment Mode Added", | ||||
|         "payment_mode_updated": "Payment Mode Updated", | ||||
|         "payment_mode_confirm_delete": "You will not be able to recover this Payment Mode", | ||||
|         "already_in_use": "Payment Mode is already in use", | ||||
|         "deleted_message": "Payment Mode deleted successfully" | ||||
|       }, | ||||
|  | ||||
|         "items": { | ||||
|             "title": "Items", | ||||
|             "units": "units", | ||||
|             "add_item_unit": "Add Item Unit", | ||||
|             "unit_name": "Unit Name", | ||||
|             "item_unit_added": "Item Unit Added", | ||||
|             "item_unit_updated": "Item Unit Updated", | ||||
|             "item_unit_confirm_delete":"You will not be able to recover this Item unit", | ||||
|             "already_in_use": "Item Unit is already in use", | ||||
|             "deleted_message": "Item Unit deleted successfully" | ||||
|         } | ||||
|       "items": { | ||||
|         "title": "Items", | ||||
|         "units": "units", | ||||
|         "add_item_unit": "Add Item Unit", | ||||
|         "edit_item_unit": "Edit Item Unit", | ||||
|         "unit_name": "Unit Name", | ||||
|         "item_unit_added": "Item Unit Added", | ||||
|         "item_unit_updated": "Item Unit Updated", | ||||
|         "item_unit_confirm_delete": "You will not be able to recover this Item unit", | ||||
|         "already_in_use": "Item Unit is already in use", | ||||
|         "deleted_message": "Item Unit deleted successfully" | ||||
|       } | ||||
|     }, | ||||
|     "account_settings": { | ||||
|       "profile_picture": "Profile Picture", | ||||
| @ -728,6 +735,7 @@ | ||||
|     "tax_types": { | ||||
|       "title": "Tax Types", | ||||
|       "add_tax": "Add Tax", | ||||
|       "edit_tax": "Edit Tax", | ||||
|       "description": "You can add or Remove Taxes as you please. Crater supports Taxes on Individual Items as well as on the invoice.", | ||||
|       "add_new_tax": "Add New Tax", | ||||
|       "tax_settings": "Tax Settings", | ||||
| @ -748,6 +756,8 @@ | ||||
|       "action": "Action", | ||||
|       "description": "Categories are required for adding expense entries. You can Add or Remove these categories according to your preference.", | ||||
|       "add_new_category": "Add New Category", | ||||
|       "add_category": "Add Category", | ||||
|       "edit_category": "Edit Category", | ||||
|       "category_name": "Category Name", | ||||
|       "category_description": "Description", | ||||
|       "created_message": "Expense Category created successfully", | ||||
| @ -785,7 +795,14 @@ | ||||
|       "progress_text": "It will just take a few minutes. Please do not refresh the screen or close the window before the update finishes", | ||||
|       "update_success": "App has been updated! Please wait while your browser window gets reloaded automatically.", | ||||
|       "latest_message": "No update available! You are on the latest version.", | ||||
|       "current_version": "Current Version" | ||||
|       "current_version": "Current Version", | ||||
|       "download_zip_file": "Download ZIP file", | ||||
|       "unzipping_package": "Unzipping Package", | ||||
|       "copying_files": "Copying Files", | ||||
|       "running_migrations": "Running Migrations", | ||||
|       "finishing_update": "Finishing Update", | ||||
|       "update_failed": "Update Failed", | ||||
|       "update_failed_text": "Sorry! Your update failed on : {step} step"    | ||||
|     } | ||||
|   }, | ||||
|   "wizard": { | ||||
|  | ||||
| @ -22,6 +22,11 @@ | ||||
|     "to_date": "Hasta la fecha", | ||||
|     "from": "De", | ||||
|     "to": "A", | ||||
|     "sort_by": "Ordenar por", | ||||
|     "ascending": "Ascendente", | ||||
|     "descending": "Descendente", | ||||
|     "subject": "Sujeta", | ||||
|     "message": "Mensaje", | ||||
|     "go_back": "Volver", | ||||
|     "back_to_login": "¿Volver al inicio de sesión?", | ||||
|     "home": "Inicio", | ||||
| @ -62,14 +67,16 @@ | ||||
|     "four_zero_four": "404", | ||||
|     "you_got_lost": "Whoops! ¡Te perdiste!", | ||||
|     "go_home": "Volver al Inicio", | ||||
|  | ||||
|     "test_mail_conf": "Probar configuración de correo", | ||||
|     "send_mail_successfully": "El correo enviado con éxito", | ||||
|     "setting_updated": "Configuración actualizada con éxito", | ||||
|     "select_state": "Seleccionar estado", | ||||
|     "select_country": "Seleccionar país", | ||||
|     "select_city": "Seleccionar ciudad", | ||||
|     "street_1": "Calle 1", | ||||
|     "street_2": "Calle 2", | ||||
|     "action_failed": "Accion Fallida" | ||||
|     "action_failed": "Accion Fallida", | ||||
|     "retry": "Procesar de nuevo" | ||||
|   }, | ||||
|   "dashboard": { | ||||
|     "select_year": "Seleccionar año", | ||||
| @ -155,7 +162,7 @@ | ||||
|     "select_a_customer": "Selecciona un cliente", | ||||
|     "type_or_click": "Escriba o haga clic para seleccionar", | ||||
|  | ||||
|     "confirm_delete": "No podrá recuperar este cliente | No podrá recuperar estos clientes", | ||||
|     "confirm_delete": "No podrá recuperar este cliente y todas las facturas, estimaciones y pagos relacionados. | No podrá recuperar estos clientes y todas las facturas, estimaciones y pagos relacionados.", | ||||
|     "created_message": "Cliente creado con éxito", | ||||
|     "updated_message": "Cliente actualizado con éxito", | ||||
|     "deleted_message": "Cliente eliminado correctamente | Clientes eliminados exitosamente" | ||||
| @ -180,7 +187,7 @@ | ||||
|     "no_items": "¡Aún no hay artículos!", | ||||
|     "list_of_items": "Esta sección contendrá la lista de artículos.", | ||||
|     "select_a_unit": "seleccionar unidad", | ||||
|  | ||||
|     "taxes": "Impuestos", | ||||
|     "item_attached_message": "No se puede eliminar un elemento que ya está en uso.", | ||||
|     "confirm_delete": "No podrá recuperar este artículo | No podrás recuperar estos elementos", | ||||
|     "created_message": "Artículo creado con éxito", | ||||
| @ -329,6 +336,9 @@ | ||||
|     "no_matching_invoices": "¡No hay facturas coincidentes con la selección!", | ||||
|     "mark_as_sent_successfully": "Factura marcada como enviada con éxito", | ||||
|     "send_invoice_successfully": "Factura enviada exitosamente", | ||||
|     "cloned_successfully": "Factura clonada exitosamente", | ||||
|     "clone_invoice": "Factura de clonación", | ||||
|     "confirm_clone": "Esta factura se clonará en una nueva factura.", | ||||
|     "item": { | ||||
|       "title": "Título del artículo", | ||||
|       "description": "Descripción", | ||||
| @ -393,6 +403,7 @@ | ||||
|     "edit_payment": "Editar pago", | ||||
|     "view_payment": "Ver pago", | ||||
|     "add_new_payment": "Agregar nuevo pago", | ||||
|     "send_payment_receipt": "Enviar recibo de pago", | ||||
|     "save_payment": "Guardar pago", | ||||
|     "update_payment": "Actualizar pago", | ||||
|     "payment": "Pago | Pagos", | ||||
| @ -412,6 +423,8 @@ | ||||
|     "expenses_list": "Lista de gastos", | ||||
|     "expense_title": "Título", | ||||
|     "contact": "Contacto", | ||||
|     "customer": "Cliente", | ||||
|     "select_a_customer": "Selecciona un cliente", | ||||
|     "category": "Categoría", | ||||
|     "from_date": "Desde la fecha", | ||||
|     "to_date": "Hasta la fecha", | ||||
| @ -600,65 +613,87 @@ | ||||
|       "updated_message": "Información de la empresa actualizada con éxito" | ||||
|     }, | ||||
|     "customization": { | ||||
|         "customization": "Personalización", | ||||
|         "save": "Guardar", | ||||
|         "addresses": { | ||||
|             "title": "Direcciones", | ||||
|             "section_description": "Puede configurar la Dirección de facturación del cliente y el Formato de dirección de envío del cliente (solo se muestra en PDF).", | ||||
|             "customer_billing_address": "Dirección de facturación del cliente", | ||||
|             "customer_shipping_address": "Dirección de envío del cliente", | ||||
|             "company_address": "Dirección de la compañia", | ||||
|             "insert_fields": "Insertar campos", | ||||
|             "contact": "Contacto", | ||||
|             "address": "Dirección", | ||||
|             "display_name": "Nombre para mostrar", | ||||
|             "primary_contact_name": "Nombre de contacto principal", | ||||
|             "email": "Email", | ||||
|             "website": "Sitio web", | ||||
|             "name": "Nombre", | ||||
|             "country": "País", | ||||
|             "state": "Estado", | ||||
|             "city": "Ciudad", | ||||
|             "company_name": "Nombre de la compañia", | ||||
|             "address_street_1": "Dirección de la calle 1", | ||||
|             "address_street_2": "Dirección de la calle 2", | ||||
|             "phone": "Telefono", | ||||
|             "zip_code": "Codigo postal", | ||||
|             "address_setting_updated": "Configuración de dirección actualizada correctamente" | ||||
|         }, | ||||
|         "updated_message": "Información de la empresa actualizada con éxito", | ||||
|       "customization": "Personalización", | ||||
|       "save": "Guardar", | ||||
|       "addresses": { | ||||
|         "title": "Direcciones", | ||||
|         "section_description": "Puede configurar la Dirección de facturación del cliente y el Formato de dirección de envío del cliente (solo se muestra en PDF).", | ||||
|         "customer_billing_address": "Dirección de facturación del cliente", | ||||
|         "customer_shipping_address": "Dirección de envío del cliente", | ||||
|         "company_address": "Dirección de la compañia", | ||||
|         "insert_fields": "Insertar campos", | ||||
|         "contact": "Contacto", | ||||
|         "address": "Dirección", | ||||
|         "display_name": "Nombre para mostrar", | ||||
|         "primary_contact_name": "Nombre de contacto principal", | ||||
|         "email": "Email", | ||||
|         "website": "Sitio web", | ||||
|         "name": "Nombre", | ||||
|         "country": "País", | ||||
|         "state": "Estado", | ||||
|         "city": "Ciudad", | ||||
|         "company_name": "Nombre de la compañia", | ||||
|         "address_street_1": "Dirección de la calle 1", | ||||
|         "address_street_2": "Dirección de la calle 2", | ||||
|         "phone": "Telefono", | ||||
|         "zip_code": "Codigo postal", | ||||
|         "address_setting_updated": "Configuración de dirección actualizada correctamente" | ||||
|       }, | ||||
|       "updated_message": "Información de la empresa actualizada con éxito", | ||||
|  | ||||
|         "invoices": { | ||||
|             "title": "Facturas", | ||||
|             "notes": "Notas", | ||||
|             "invoice_prefix": "Prefijo de las facturas", | ||||
|             "invoice_settings": "Ajustes de facturas", | ||||
|             "autogenerate_invoice_number": "Autogenerar número de factura", | ||||
|             "invoice_setting_description": "Desactive esto, si no desea generar automáticamente números de factura cada vez que cree una nueva factura.", | ||||
|             "enter_invoice_prefix": "Introduzca el prefijo de factura", | ||||
|             "terms_and_conditions": "Términos y Condiciones", | ||||
|             "invoice_setting_updated": "Configuración de factura actualizada correctamente" | ||||
|         }, | ||||
|       "invoices": { | ||||
|         "title": "Facturas", | ||||
|         "notes": "Notas", | ||||
|         "invoice_prefix": "Prefijo de las facturas", | ||||
|         "invoice_settings": "Ajustes de facturas", | ||||
|         "autogenerate_invoice_number": "Autogenerar número de factura", | ||||
|         "invoice_setting_description": "Desactive esto, si no desea generar automáticamente números de factura cada vez que cree una nueva factura.", | ||||
|         "enter_invoice_prefix": "Introduzca el prefijo de factura", | ||||
|         "terms_and_conditions": "Términos y Condiciones", | ||||
|         "invoice_setting_updated": "Configuración de factura actualizada correctamente" | ||||
|       }, | ||||
|  | ||||
|         "estimates": { | ||||
|             "title": "Estimaciones", | ||||
|             "estimate_prefix": "Prefijo de los presupuestos", | ||||
|             "estimate_settings": "Ajustes de presupuestos", | ||||
|             "autogenerate_estimate_number": "Autogenerar número de presupuesto", | ||||
|             "estimate_setting_description": "Desactive esto, si no desea generar automáticamente números de presupuesto cada vez que cree un nuevo presupuesto.", | ||||
|             "enter_estimate_prefix": "Introduzca el prefijo de presupuesto", | ||||
|             "estimate_setting_updated": "Configuración de presupuestos actualizada correctamente" | ||||
|         }, | ||||
|       "estimates": { | ||||
|         "title": "Estimaciones", | ||||
|         "estimate_prefix": "Prefijo de los presupuestos", | ||||
|         "estimate_settings": "Ajustes de presupuestos", | ||||
|         "autogenerate_estimate_number": "Autogenerar número de presupuesto", | ||||
|         "estimate_setting_description": "Desactive esto, si no desea generar automáticamente números de presupuesto cada vez que cree un nuevo presupuesto.", | ||||
|         "enter_estimate_prefix": "Introduzca el prefijo de presupuesto", | ||||
|         "estimate_setting_updated": "Configuración de presupuestos actualizada correctamente" | ||||
|       }, | ||||
|  | ||||
|         "payments": { | ||||
|             "title": "Payments", | ||||
|             "payment_prefix": "Prefijo de los pagos", | ||||
|             "payment_settings": "Ajustes de pagos", | ||||
|             "autogenerate_payment_number": "Autogenerar número de pago", | ||||
|             "payment_setting_description": "Desactive esto, si no desea generar automáticamente números de pago cada vez que cree un nuevo pago.", | ||||
|             "enter_payment_prefix": "Introduzca el prefijo de pago", | ||||
|             "payment_setting_updated": "Configuración de pagos actualizada correctamente" | ||||
|         } | ||||
|       "payments": { | ||||
|         "title": "Pagos", | ||||
|         "payment_prefix": "Prefijo de los pagos", | ||||
|         "payment_settings": "Ajustes de pagos", | ||||
|         "autogenerate_payment_number": "Autogenerar número de pago", | ||||
|         "payment_setting_description": "Desactive esto, si no desea generar automáticamente números de pago cada vez que cree un nuevo pago.", | ||||
|         "enter_payment_prefix": "Introduzca el prefijo de pago", | ||||
|         "payment_setting_updated": "Configuración de pagos actualizada correctamente", | ||||
|         "payment_mode": "Modo de pago", | ||||
|         "add_payment_mode": "Agregar modo de pago", | ||||
|         "edit_payment_mode": "Editar modo de pago", | ||||
|         "mode_name": "Nombre del modo", | ||||
|         "payment_mode_added": "Modo de pago agregado", | ||||
|         "payment_mode_updated": "Modo de pago actualizado", | ||||
|         "payment_mode_confirm_delete": "No podrá recuperar este modo de pago", | ||||
|         "already_in_use": "El modo de pago ya está en uso", | ||||
|         "deleted_message": "Modo de pago eliminado correctamente" | ||||
|       }, | ||||
|  | ||||
|       "items": { | ||||
|         "title": "Artículos", | ||||
|         "units": "unidades", | ||||
|         "add_item_unit": "Agregar unidad de artículo", | ||||
|         "edit_item_unit": "Editar unidad de artículo", | ||||
|         "unit_name": "Nombre de la unidad", | ||||
|         "item_unit_added": "Unidad de artículo agregada", | ||||
|         "item_unit_updated": "Unidad de artículo actualizada", | ||||
|         "item_unit_confirm_delete": "No podrás recuperar esta unidad de artículo", | ||||
|         "already_in_use": "Unidad de artículo ya está en uso", | ||||
|         "deleted_message": "Unidad de elemento eliminada correctamente" | ||||
|       } | ||||
|     }, | ||||
|     "account_settings": { | ||||
|       "profile_picture": "Foto de perfil", | ||||
| @ -692,6 +727,7 @@ | ||||
|     "tax_types": { | ||||
|       "title": "Tipos de impuestos", | ||||
|       "add_tax": "Agregar impuesto", | ||||
|       "edit_tax": "Editar impuesto", | ||||
|       "description": "Puede agregar o eliminar impuestos a su gusto. Crater admite impuestos sobre artículos individuales, así como sobre la factura.", | ||||
|       "add_new_tax": "Agregar nuevo impuesto", | ||||
|       "tax_settings": "Configuraciones de impuestos", | ||||
| @ -712,6 +748,8 @@ | ||||
|       "action": "Acción", | ||||
|       "description": "Se requieren categorías para agregar entradas de gastos. Puede Agregar o Eliminar estas categorías según su preferencia.", | ||||
|       "add_new_category": "Añadir nueva categoria", | ||||
|       "add_category": "Añadir categoría", | ||||
|       "edit_category": "Editar categoria", | ||||
|       "category_name": "nombre de la categoría", | ||||
|       "category_description": "Descripción", | ||||
|       "created_message": "Categoría de gastos creada con éxito", | ||||
| @ -749,7 +787,14 @@ | ||||
|       "progress_text": "Solo tomará unos minutos. No actualice la pantalla ni cierre la ventana antes de que finalice la actualización.", | ||||
|       "update_success": "¡La aplicación ha sido actualizada! Espere mientras la ventana de su navegador se vuelve a cargar automáticamente.", | ||||
|       "latest_message": "¡Actualización no disponible! Estás en la última versión.", | ||||
|       "current_version": "Versión actual" | ||||
|       "current_version": "Versión actual", | ||||
|       "download_zip_file": "Descargar archivo ZIP", | ||||
|       "unzipping_package": "Descomprimir paquete", | ||||
|       "copying_files": "Copiando documentos", | ||||
|       "running_migrations": "Ejecutar migraciones", | ||||
|       "finishing_update": "Actualización final", | ||||
|       "update_failed": "Actualización fallida", | ||||
|       "update_failed_text": "¡Lo siento! Su actualización falló el: {step} paso"  | ||||
|     } | ||||
|   }, | ||||
|   "wizard": { | ||||
|  | ||||
| @ -17,6 +17,7 @@ | ||||
|     "save": "Sauvegarder", | ||||
|     "cancel": "Annuler", | ||||
|     "update": "Mise à jour", | ||||
|     "deselect": "Retirer", | ||||
|     "download": "Télécharger", | ||||
|     "from_date": "A partir de la date", | ||||
|     "to_date": "À ce jour", | ||||
| @ -28,7 +29,7 @@ | ||||
|     "filter": "Filtre", | ||||
|     "delete": "Effacer", | ||||
|     "edit": "Modifier", | ||||
|     "view": "Vue", | ||||
|     "view": "Voir", | ||||
|     "add_new_item": "Ajoute un nouvel objet", | ||||
|     "clear_all": "Tout effacer", | ||||
|     "showing": "Montrant", | ||||
| @ -62,14 +63,21 @@ | ||||
|     "four_zero_four": "404", | ||||
|     "you_got_lost": "Oups! Vous vous êtes perdus!", | ||||
|     "go_home": "Rentrer chez soi", | ||||
|  | ||||
|     "test_mail_conf": "Tester la configuration", | ||||
|     "send_mail_successfully": "Mail envoyé avec succès", | ||||
|     "setting_updated": "Réglage mis à jour avec succès", | ||||
|     "select_state": "Sélectionnez l'état", | ||||
|     "select_country": "Choisissez le pays", | ||||
|     "select_city": "Sélectionnez une ville", | ||||
|     "street_1": "Rue 1", | ||||
|     "street_2": "Rue # 2", | ||||
|     "action_failed": "Action : échoué" | ||||
|     "action_failed": "Action : échoué", | ||||
|     "sort_by": "Trier par", | ||||
|     "ascending": "Ascendant", | ||||
|     "descending": "Descendant", | ||||
|     "subject": "matière", | ||||
|     "message": "Message", | ||||
|     "retry": "Réessayez" | ||||
|   }, | ||||
|   "dashboard": { | ||||
|     "select_year": "Sélectionnez l'année", | ||||
| @ -160,7 +168,7 @@ | ||||
|     "select_a_customer": "Sélectionnez un client", | ||||
|     "type_or_click": "Tapez ou cliquez pour sélectionner", | ||||
|  | ||||
|     "confirm_delete": "Vous ne pourrez pas récupérer ce client | Vous ne pourrez pas récupérer ces clients", | ||||
|     "confirm_delete": "Vous ne pourrez pas récupérer ce client et toutes les factures, devis et paiements associés. | Vous ne serez pas en mesure de récupérer ces clients et toutes les factures, devis et paiements associés.", | ||||
|     "created_message": "Client créé avec succès", | ||||
|     "updated_message": "Client mis à jour avec succès", | ||||
|     "deleted_message": "Client supprimé avec succès | Les clients supprimés avec succès" | ||||
| @ -185,7 +193,7 @@ | ||||
|     "no_items": "Aucun article pour le moment!", | ||||
|     "list_of_items": "Cette section contiendra la liste des éléments.", | ||||
|     "select_a_unit": "Sélectionnez l'unité", | ||||
|  | ||||
|     "taxes": "Les taxes", | ||||
|     "item_attached_message": "Impossible de supprimer un élément déjà utilisé", | ||||
|     "confirm_delete": "Vous ne pourrez pas récupérer cet article | Vous ne pourrez pas récupérer ces objets", | ||||
|     "created_message": "Article créé avec succès", | ||||
| @ -202,24 +210,24 @@ | ||||
|     "all": "Tout", | ||||
|     "paid": "Payé", | ||||
|     "unpaid": "Non payé", | ||||
|     "customer": "CLIENT CLIENT", | ||||
|     "ref_no": "REF NO.", | ||||
|     "number": "NOMBRE", | ||||
|     "customer": "Client", | ||||
|     "ref_no": "Réf.", | ||||
|     "number": "N°", | ||||
|     "amount_due": "MONTANT DÛ", | ||||
|     "partially_paid": "Partiellement payé", | ||||
|     "total": "Totale", | ||||
|     "total": "Total", | ||||
|     "discount": "Remise", | ||||
|     "sub_total": "Total partiel", | ||||
|     "estimate_number": "Numéro destimation", | ||||
|     "estimate_number": "N°", | ||||
|     "ref_number": "Numéro de ref", | ||||
|     "contact": "Contact", | ||||
|     "add_item": "Ajouter un article", | ||||
|     "date": "Date", | ||||
|     "due_date": "Date déchéance", | ||||
|     "due_date": "Date d'échéance", | ||||
|     "expiry_date": "Date dexpiration", | ||||
|     "status": "Statut", | ||||
|     "add_tax": "Ajouter une taxe", | ||||
|     "amount": "Montante", | ||||
|     "amount": "Montant", | ||||
|     "action": "action", | ||||
|     "notes": "Remarques", | ||||
|     "tax": "Impôt", | ||||
| @ -227,7 +235,7 @@ | ||||
|     "convert_to_invoice": "Convertir en facture", | ||||
|     "mark_as_sent": "Marquer comme envoyé", | ||||
|     "send_estimate": "Envoyer un devis", | ||||
|     "record_payment": "Record de paiement", | ||||
|     "record_payment": "Enregistrer un paiement", | ||||
|     "add_estimate": "Ajouter un devis", | ||||
|     "save_estimate": "Sauvegarder le devis", | ||||
|     "confirm_conversion": "Vous souhaitez convertir ce devis en facture?", | ||||
| @ -269,14 +277,17 @@ | ||||
|       "quantity": "Quantité", | ||||
|       "price": "Prix", | ||||
|       "discount": "Remise", | ||||
|       "total": "Totale", | ||||
|       "total": "Total", | ||||
|       "total_discount": "Remise totale", | ||||
|       "sub_total": "Total partiel", | ||||
|       "tax": "Impôt", | ||||
|       "amount": "Montante", | ||||
|       "amount": "Montant", | ||||
|       "select_an_item": "Tapez ou cliquez pour sélectionner un élément", | ||||
|       "type_item_description": "Type Item Description (optionnel)" | ||||
|     } | ||||
|     }, | ||||
|     "no_matching_estimates": "Aucune estimation correspondante!", | ||||
|     "user_email_does_not_exist": "L'e-mail de l'utilisateur n'existe pas", | ||||
|     "something_went_wrong": "quelque chose a mal tourné" | ||||
|   }, | ||||
|   "invoices": { | ||||
|     "title": "Factures", | ||||
| @ -287,13 +298,13 @@ | ||||
|     "all": "Toute", | ||||
|     "paid": "Payé", | ||||
|     "unpaid": "Non payé", | ||||
|     "customer": "CLIENTE CLIENT", | ||||
|     "paid_status": "Statut payé", | ||||
|     "customer": "CLIENT", | ||||
|     "paid_status": "Paiement", | ||||
|     "ref_no": "REF NO.", | ||||
|     "number": "NOMBRE", | ||||
|     "number": "N°", | ||||
|     "amount_due": "MONTANT DÛ", | ||||
|     "partially_paid": "Partiellement payé", | ||||
|     "total": "Totale Total", | ||||
|     "total": "Total", | ||||
|     "discount": "Remise", | ||||
|     "sub_total": "Total partiel", | ||||
|     "invoice": "Facture | Factures", | ||||
| @ -302,21 +313,23 @@ | ||||
|     "contact": "Contact", | ||||
|     "add_item": "Ajouter un article", | ||||
|     "date": "Date", | ||||
|     "due_date": "Date déchéance", | ||||
|     "due_date": "Date d'échéance", | ||||
|     "status": "Statut", | ||||
|     "add_tax": "Ajouter une taxe", | ||||
|     "amount": "Montante Montant", | ||||
|     "amount": "Montant", | ||||
|     "action": "action", | ||||
|     "notes": "Remarques", | ||||
|     "view": "Vue", | ||||
|     "view": "Voir", | ||||
|     "send_invoice": "Envoyer une facture", | ||||
|     "cloned_successfully": "Facture clonée avec succès", | ||||
|     "clone_invoice": "Cloner", | ||||
|     "invoice_template": "Modèle de facture", | ||||
|     "template": "Modèle", | ||||
|     "mark_as_sent": "Marquer comme envoyé", | ||||
|     "invoice_mark_as_sent": "Cette facture sera marquée comme envoyé", | ||||
|     "confirm_send": "Cette facture sera envoyée par courrier électronique au client.", | ||||
|     "invoice_date": "Date de facturation", | ||||
|     "record_payment": "Record de paiement", | ||||
|     "record_payment": "Enregister un paiement", | ||||
|     "add_new_invoice": "Ajouter une nouvelle facture", | ||||
|     "update_expense": "Frais de mise à jour", | ||||
|     "edit_invoice": "Modifier la facture", | ||||
| @ -335,11 +348,11 @@ | ||||
|       "quantity": "Quantité", | ||||
|       "price": "Prix", | ||||
|       "discount": "Remise", | ||||
|       "total": "Totale Total", | ||||
|       "total": "Total", | ||||
|       "total_discount": "Remise totale", | ||||
|       "sub_total": "Total partiel", | ||||
|       "tax": "Impôt", | ||||
|       "amount": "Montante Montant", | ||||
|       "amount": "Montant", | ||||
|       "select_an_item": "Tapez ou cliquez pour sélectionner un élément", | ||||
|       "type_item_description": "Type Item Description (optionnel)" | ||||
|     }, | ||||
| @ -349,7 +362,12 @@ | ||||
|     "updated_message": "Facture mise à jour avec succès", | ||||
|     "deleted_message": "La Facture a été supprimée ! | Les Factures ont été supprimées !", | ||||
|     "marked_as_sent_message": "Facture supprimée avec succès | Factures supprimées avec succès", | ||||
|     "invalid_due_amount_message": "Le paiement entré est supérieur au montant total dû pour cette facture. Veuillez vérifier et réessayer" | ||||
|     "invalid_due_amount_message": "Le paiement entré est supérieur au montant total dû pour cette facture. Veuillez vérifier et réessayer", | ||||
|     "confirm_send_invoice": "Cette facture sera envoyée par email au client", | ||||
|     "no_matching_invoices": "Aucune facture correspondante!", | ||||
|     "confirm_clone": "Cette facture sera clonée dans une nouvelle facture", | ||||
|     "user_email_does_not_exist": "L'e-mail de l'utilisateur n'existe pas", | ||||
|     "something_went_wrong": "quelque chose a mal tourné" | ||||
|   }, | ||||
|   "credit_notes": { | ||||
|     "title": "Notes de crédit", | ||||
| @ -357,7 +375,7 @@ | ||||
|     "credit_notes": "Notes de crédit", | ||||
|     "contact": "Contact", | ||||
|     "date": "Date", | ||||
|     "amount": "Montante Montant", | ||||
|     "amount": "Montant Montant", | ||||
|     "action": "action", | ||||
|     "credit_number": "Numéro de crédit", | ||||
|     "notes": "Remarques", | ||||
| @ -368,7 +386,7 @@ | ||||
|       "quantity": "Quantité", | ||||
|       "price": "Prix", | ||||
|       "discount": "Remise", | ||||
|       "total": "Totale Total", | ||||
|       "total": "Total", | ||||
|       "total_discount": "Remise totale", | ||||
|       "sub_total": "Total partiel", | ||||
|       "tax": "Impôt" | ||||
| @ -377,12 +395,12 @@ | ||||
|   "payments": { | ||||
|     "title": "Paiements", | ||||
|     "payments_list": "Liste de paiements", | ||||
|     "record_payment": "Record de paiement", | ||||
|     "customer": "Client Client", | ||||
|     "record_payment": "Enregistrer un paiement", | ||||
|     "customer": "Client", | ||||
|     "date": "Date", | ||||
|     "amount": "Montant Montant", | ||||
|     "amount": "Montant", | ||||
|     "action": "action", | ||||
|     "payment_number": "Numéro de paiement", | ||||
|     "payment_number": "N°", | ||||
|     "payment_mode": "Mode de paiement", | ||||
|     "invoice": "Facture dachat", | ||||
|     "note": "Remarque", | ||||
| @ -391,6 +409,7 @@ | ||||
|     "edit_payment": "Modifier le paiement", | ||||
|     "view_payment": "Voir le paiement", | ||||
|     "add_new_payment": "Ajouter un nouveau paiement", | ||||
|     "send_payment_receipt": "Envoyer le reçu", | ||||
|     "save_payment": "Enregistrer le paiement", | ||||
|     "update_payment": "Mettre à jour le paiement", | ||||
|     "payment": "Paiement | Paiements", | ||||
| @ -403,13 +422,19 @@ | ||||
|     "created_message": "Paiement créé avec succès", | ||||
|     "updated_message": "Paiement mis à jour avec succès", | ||||
|     "deleted_message": "Paiement supprimé avec succès | Paiements supprimés avec succès", | ||||
|     "invalid_amount_message": "Le montant du paiement est invalide" | ||||
|     "invalid_amount_message": "Le montant du paiement est invalide", | ||||
|     "confirm_send_payment": "Ce paiement sera envoyé par e-mail au client", | ||||
|     "send_payment_successfully": "Paiement envoyé avec succès", | ||||
|     "user_email_does_not_exist": "L'e-mail de l'utilisateur n'existe pas", | ||||
|     "something_went_wrong": "quelque chose a mal tourné" | ||||
|   }, | ||||
|   "expenses": { | ||||
|     "title": "Dépenses", | ||||
|     "expenses_list": "Liste des dépenses", | ||||
|     "expense_title": "Titre", | ||||
|     "contact": "Contact", | ||||
|     "customer": "Client Client", | ||||
|     "select_a_customer": "Sélectionnez un client", | ||||
|     "category": "Catégorie", | ||||
|     "from_date": "A partir de la date", | ||||
|     "to_date": "À ce jour", | ||||
| @ -423,7 +448,7 @@ | ||||
|     "date": "Date de dépense", | ||||
|     "add_expense": "Ajouter une dépense", | ||||
|     "add_new_expense": "Ajouter une nouvelle dépense", | ||||
|     "save_expense": "Économiser des dépenses", | ||||
|     "save_expense": "Enregistrer la dépense", | ||||
|     "update_expense": "Frais de mise à jour", | ||||
|     "download_receipt": "Télécharger le reçu", | ||||
|     "edit_expense": "Modifier les dépenses", | ||||
| @ -447,7 +472,8 @@ | ||||
|       "new_category": "Nouvelle catégorie", | ||||
|       "category": "Catégorie | Les catégories", | ||||
|       "select_a_category": "choisissez une catégorie" | ||||
|     } | ||||
|     }, | ||||
|     "customer": "Client" | ||||
|   }, | ||||
|   "login": { | ||||
|     "email": "Email", | ||||
| @ -460,7 +486,8 @@ | ||||
|     "enter_email": "Entrer email", | ||||
|     "enter_password": "Entrer le mot de passe", | ||||
|     "retype_password": "Retaper le mot de passe", | ||||
|     "login_placeholder": "mail@example.com" | ||||
|     "login_placeholder": "mail@example.com", | ||||
|     "password_reset_successfully": "Réinitialisation du mot de passe réussie" | ||||
|   }, | ||||
|   "reports": { | ||||
|     "title": "rapport", | ||||
| @ -499,7 +526,7 @@ | ||||
|       "invoice": "Facture d'achat", | ||||
|       "invoice_date": "Date de facturation", | ||||
|       "due_date": "Date déchéance", | ||||
|       "amount": "Montante ", | ||||
|       "amount": "Montant ", | ||||
|       "contact_name": "Nom du contact", | ||||
|       "status": "Statut" | ||||
|     }, | ||||
| @ -507,7 +534,7 @@ | ||||
|       "estimate": "Devis", | ||||
|       "estimate_date": "Date du devis", | ||||
|       "due_date": "Date d'échéance", | ||||
|       "estimate_number": "Numéro d'estimation", | ||||
|       "estimate_number": "N°", | ||||
|       "ref_number": "Numéro de ref", | ||||
|       "amount": "Montant", | ||||
|       "contact_name": "Nom du contact", | ||||
| @ -527,6 +554,7 @@ | ||||
|     "menu_title": { | ||||
|       "account_settings": "Paramètres du compte", | ||||
|       "company_information": "Informations sur la société", | ||||
|       "customization": "Personnalisation", | ||||
|       "preferences": "Préférences", | ||||
|       "notifications": "Les notifications", | ||||
|       "tax_types": "Types de taxe", | ||||
| @ -591,10 +619,92 @@ | ||||
|       "state": "Etat", | ||||
|       "city": "Ville", | ||||
|       "address": "Adresse", | ||||
|       "zip": "Zip", | ||||
|       "save": "sauver", | ||||
|       "zip": "Code postal", | ||||
|       "save": "Sauvegarder", | ||||
|       "updated_message": "Informations sur la société mises à jour avec succès" | ||||
|     }, | ||||
|  | ||||
|     "customization": { | ||||
|       "customization": "Personnalisation", | ||||
|       "save": "Sauvegarder", | ||||
|       "addresses": { | ||||
|         "title": "Adresses", | ||||
|         "section_description": "You can set Customer Billing Address and Customer Shipping Address Format (Displayed in PDF only). ", | ||||
|         "customer_billing_address": "Adresse de paiement", | ||||
|         "customer_shipping_address": "Adresse de livraison", | ||||
|         "company_address": "Adresse de l'entreprise", | ||||
|         "insert_fields": "Ajouter des champs", | ||||
|         "contact": "Contact", | ||||
|         "address": "Addresse", | ||||
|         "display_name": "Nom", | ||||
|         "primary_contact_name": "Nom du contact principal", | ||||
|         "email": "Email", | ||||
|         "website": "Website", | ||||
|         "name": "Nom", | ||||
|         "country": "Pays", | ||||
|         "state": "State", | ||||
|         "city": "Ville", | ||||
|         "company_name": "Nom de l'entreprise", | ||||
|         "address_street_1": "Rue", | ||||
|         "address_street_2": "Complément", | ||||
|         "phone": "Téléphone", | ||||
|         "zip_code": "Code postal", | ||||
|         "address_setting_updated": "Adresse mise à jour avec succès" | ||||
|       }, | ||||
|       "updated_message": "Informations de l'entreprise mises à jour", | ||||
|  | ||||
|       "invoices": { | ||||
|         "title": "Factures", | ||||
|         "notes": "Notes", | ||||
|         "invoice_prefix": "Préfixe", | ||||
|         "invoice_settings": "Paramètre", | ||||
|         "autogenerate_invoice_number": "Générer automatiquement le numéro de facture", | ||||
|         "invoice_setting_description": "Désactivez cette option si vous ne souhaitez pas générer automatiquement les numéros de facture à chaque fois que vous en créez une nouvelle.", | ||||
|         "enter_invoice_prefix": "Ajouter le préfixe de facture", | ||||
|         "terms_and_conditions": "Termes et conditions", | ||||
|         "invoice_setting_updated": "Paramètres de facturation mis à jour" | ||||
|       }, | ||||
|  | ||||
|       "estimates": { | ||||
|         "title": "Devis", | ||||
|         "estimate_prefix": "Préfixe", | ||||
|         "estimate_settings": "Paramètre", | ||||
|         "autogenerate_estimate_number": "Générer automatiquement le numéro de devis", | ||||
|         "estimate_setting_description": "Désactivez cette option si vous ne souhaitez pas générer automatiquement les numéros de devis à chaque fois que vous en créez un nouveau.", | ||||
|         "estimate_setting_updated": "Paramètres de devis mis à jour" | ||||
|       }, | ||||
|  | ||||
|       "payments": { | ||||
|         "title": "Paiements", | ||||
|         "payment_prefix": "Préfixe", | ||||
|         "payment_settings": "Paramètre", | ||||
|         "autogenerate_payment_number": "Générer automatiquement le numéro de paiement", | ||||
|         "payment_setting_description": "Désactivez cette option si vous ne souhaitez pas générer automatiquement les numéros de paiement à chaque fois que vous en créez un nouveau.", | ||||
|         "payment_setting_updated": "Les paramètres de paiement ont bien été mis à jour", | ||||
|         "payment_mode": "Mode de paiement", | ||||
|         "add_payment_mode": "Ajouter un mode de paiement", | ||||
|         "edit_payment_mode": "Modifier le mode de paiement", | ||||
|         "mode_name": "Nom", | ||||
|         "payment_mode_added": "Mode de paiement ajouté", | ||||
|         "payment_mode_updated": "Mode de paiement mis à jour", | ||||
|         "payment_mode_confirm_delete": "Êtes-vous sur de supprimer ce mode de paiement ?", | ||||
|         "already_in_use": "Ce mode de paiement existe déjà.", | ||||
|         "deleted_message": "Mode de paiement supprimé avec succès" | ||||
|       }, | ||||
|  | ||||
|       "items": { | ||||
|         "title": "Articles", | ||||
|         "units": "Unités", | ||||
|         "add_item_unit": "Ajouter une unité", | ||||
|         "edit_item_unit": "Modifier l'unité d'élément", | ||||
|         "unit_name": "Nom", | ||||
|         "item_unit_added": "Unité ajouté", | ||||
|         "item_unit_updated": "Unité mis à jour", | ||||
|         "item_unit_confirm_delete": "Êtes-vous sur de supprimer cette unité ?", | ||||
|         "already_in_use": "Cette unité existe déjà", | ||||
|         "deleted_message": "Unité supprimé avec succès" | ||||
|       } | ||||
|     }, | ||||
|     "account_settings": { | ||||
|       "profile_picture": "Image de profil", | ||||
|       "name": "Nom", | ||||
| @ -602,7 +712,7 @@ | ||||
|       "password": "Mot de passe", | ||||
|       "confirm_password": "Confirmez le mot de passe", | ||||
|       "account_settings": "Paramètres du compte", | ||||
|       "save": "sauver", | ||||
|       "save": "Sauvegarder", | ||||
|       "section_description": "Vous pouvez mettre à jour votre nom, votre email et votre mot de passe en utilisant le formulaire ci-dessous.", | ||||
|       "updated_message": "Paramètres du compte mis à jour avec succès" | ||||
|     }, | ||||
| @ -617,10 +727,10 @@ | ||||
|       "email": "Envoyer des notifications à", | ||||
|       "description": "Quelles notifications par courrier électronique souhaitez-vous recevoir lorsque quelque chose change?", | ||||
|       "invoice_viewed": "Facture consultée", | ||||
|       "invoice_viewed_desc": "Lorsque votre client visualise la facture envoyée via le tableau de bord du cratère.", | ||||
|       "estimate_viewed": "Estimation vue", | ||||
|       "estimate_viewed_desc": "Lorsque votre client visualise le devis envoyé via le tableau de bord du cratère.", | ||||
|       "save": "sauver", | ||||
|       "invoice_viewed_desc": "Lorsque le client visualise la facture envoyée via le tableau de bord de Neptune.", | ||||
|       "estimate_viewed": "Devis consulté", | ||||
|       "estimate_viewed_desc": "Lorsque le client visualise le devis envoyé via le tableau de bord de Neptune.", | ||||
|       "save": "Sauvegarder", | ||||
|       "email_save_message": "Email enregistré avec succès", | ||||
|       "invoice_viewed_message": "Facture consultée", | ||||
|       "estimate_viewed_message": "Estimation vue", | ||||
| @ -629,6 +739,7 @@ | ||||
|     "tax_types": { | ||||
|       "title": "Types de taxe", | ||||
|       "add_tax": "Ajouter une taxe", | ||||
|       "edit_tax": "Modifier la taxe", | ||||
|       "description": "Vous pouvez ajouter ou supprimer des taxes à votre guise. Crater prend en charge les taxes sur les articles individuels ainsi que sur la facture.", | ||||
|       "add_new_tax": "Ajouter une nouvelle taxe", | ||||
|       "tax_settings": "Paramètres de taxe", | ||||
| @ -649,8 +760,10 @@ | ||||
|       "action": "action", | ||||
|       "description": "Des catégories sont requises pour ajouter des entrées de dépenses. Vous pouvez ajouter ou supprimer ces catégories selon vos préférences.", | ||||
|       "add_new_category": "Ajouter une nouvelle catégorie", | ||||
|       "add_category": "Adicionar categoria", | ||||
|       "edit_category": "Editar categoria", | ||||
|       "category_name": "Nom de catégorie", | ||||
|       "category_description": "La description", | ||||
|       "category_description": "Description", | ||||
|       "created_message": "Catégorie de dépenses créée avec succès", | ||||
|       "deleted_message": "La catégorie de dépenses a été supprimée avec succès", | ||||
|       "updated_message": "Catégorie de dépenses mise à jour avec succès", | ||||
| @ -666,7 +779,7 @@ | ||||
|       "discount_setting": "Réglage de remise", | ||||
|       "discount_per_item": "Remise par article", | ||||
|       "discount_setting_description": "Activez cette option si vous souhaitez ajouter une remise à des postes de facture individuels. Par défaut, les remises sont ajoutées directement à la facture.", | ||||
|       "save": "sauver", | ||||
|       "save": "Sauvegarder", | ||||
|       "preference": "Préférence | Préférences", | ||||
|       "general_settings": "Préférences par défaut pour le système.", | ||||
|       "updated_message": "Préférences mises à jour avec succès", | ||||
| @ -687,7 +800,14 @@ | ||||
|       "progress_text": "Cela ne prendra que quelques minutes. S'il vous plaît ne pas actualiser l'écran ou fermer la fenêtre avant la fin de la mise à jour", | ||||
|       "update_success": "App a été mis à jour! Veuillez patienter pendant le rechargement automatique de la fenêtre de votre navigateur.", | ||||
|       "latest_message": "Pas de mise a jour disponible! Vous êtes sur la dernière version.", | ||||
|       "current_version": "Version actuelle" | ||||
|       "current_version": "Version actuelle", | ||||
|       "download_zip_file": "Télécharger le fichier ZIP", | ||||
|       "unzipping_package": "Dézipper le package", | ||||
|       "copying_files": "Copie de fichiers", | ||||
|       "running_migrations": "Exécution de migrations", | ||||
|       "finishing_update": "Mise à jour de finition", | ||||
|       "update_failed": "Mise à jour a échoué", | ||||
|       "update_failed_text": "Désolé! Votre mise à jour a échoué à: {step} étape" | ||||
|     } | ||||
|   }, | ||||
|   "wizard": { | ||||
| @ -772,7 +892,8 @@ | ||||
|     "success": { | ||||
|       "mail_variables_save_successfully": "Email configuré avec succès", | ||||
|       "database_variables_save_successfully": "Base de données configurée avec succès." | ||||
|     } | ||||
|     }, | ||||
|     "skip": "sauter" | ||||
|   }, | ||||
|   "layout_login": { | ||||
|     "copyright_crater": "Copyright @ Crater - 2020", | ||||
| @ -781,7 +902,6 @@ | ||||
|     "small_businesses": "Petites entreprises ", | ||||
|     "crater_help": "Crater vous aide à suivre vos dépenses, à enregistrer vos paiements et à générer de belles", | ||||
|     "invoices_and_estimates": "factures et devis avec possibilité de choisir plusieurs modèles." | ||||
|  | ||||
|   }, | ||||
|   "validation": { | ||||
|     "invalid_url": "URL invalide (ex: http://www.crater.com)", | ||||
| @ -812,6 +932,7 @@ | ||||
|     "maximum_options_error": "Maximum de {max} options sélectionnées. Commencez par supprimer une option sélectionnée pour en sélectionner une autre.", | ||||
|     "notes_maxlength": "Les notes ne doivent pas dépasser 255 caractères.", | ||||
|     "address_maxlength": "L'adresse ne doit pas dépasser 255 caractères.", | ||||
|     "ref_number_maxlength": "Le numéro de référence ne doit pas dépasser 255 caractères." | ||||
|     "ref_number_maxlength": "Le numéro de référence ne doit pas dépasser 255 caractères.", | ||||
|     "email_already_taken": "Un compte est déjà associé à cette adresse e-mail." | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -6,6 +6,7 @@ import es from './es.json' | ||||
| import ar from './ar.json' | ||||
| import de from './de.json' | ||||
| import pt_BR from './pt-br.json' | ||||
| import it from './it.json' | ||||
|  | ||||
| Vue.use(VueI18n) | ||||
|  | ||||
| @ -17,8 +18,9 @@ const i18n = new VueI18n({ | ||||
|     es, | ||||
|     ar, | ||||
|     de, | ||||
|     pt_BR | ||||
|   } | ||||
|     pt_BR, | ||||
|     it, | ||||
|   }, | ||||
| }) | ||||
|  | ||||
| export default i18n | ||||
|  | ||||
							
								
								
									
										935
									
								
								resources/assets/js/plugins/it.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										935
									
								
								resources/assets/js/plugins/it.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,935 @@ | ||||
| { | ||||
|   "_comment": "Italian - IT translation - by Alessandro Fuda - Milan, Italy - 20/03/2020 - Coronavirus's times But towards spring :-) ", | ||||
|   "navigation": { | ||||
|     "dashboard": "Dashboard", | ||||
|     "customers": "Clienti", | ||||
|     "items": "Commesse", | ||||
|     "invoices": "Fatture", | ||||
|     "expenses": "Spese", | ||||
|     "estimates": "Preventivi", | ||||
|     "payments": "Pagamenti", | ||||
|     "reports": "Reports", | ||||
|     "settings": "Configurazione", | ||||
|     "logout": "Logout" | ||||
|   }, | ||||
|   "general": { | ||||
|     "view_pdf": "Vedi PDF", | ||||
|     "download_pdf": "Download PDF", | ||||
|     "save": "Salva", | ||||
|     "cancel": "Elimina", | ||||
|     "update": "Aggiorna", | ||||
|     "deselect": "Deseleziona", | ||||
|     "download": "Download", | ||||
|     "from_date": "Dalla Data", | ||||
|     "to_date": "Alla Data", | ||||
|     "from": "Da", | ||||
|     "to": "A", | ||||
|     "sort_by": "Ordina per", | ||||
|     "ascending": "Crescente", | ||||
|     "descending": "Decrescente", | ||||
|     "subject": "Oggetto", | ||||
|     "message": "Messaggio", | ||||
|     "go_back": "Torna indietro", | ||||
|     "back_to_login": "Torna al Login?", | ||||
|     "home": "Home", | ||||
|     "filter": "Filtro", | ||||
|     "delete": "Elimina", | ||||
|     "edit": "Modifica", | ||||
|     "view": "Visualizza", | ||||
|     "add_new_item": "Aggiungi nuova Commessa", | ||||
|     "clear_all": "Pulisci tutto", | ||||
|     "showing": "Showing", | ||||
|     "of": "di", | ||||
|     "actions": "Azioni", | ||||
|     "subtotal": "SUBTOTALE", | ||||
|     "discount": "SCONTO", | ||||
|     "fixed": "Fissato", | ||||
|     "percentage": "Percentuale", | ||||
|     "tax": "TASSA", | ||||
|     "total_amount": "AMMONTARE TOTALE", | ||||
|     "bill_to": "Fattura a", | ||||
|     "ship_to": "Invia a", | ||||
|     "due": "Dovuto", | ||||
|     "draft": "Bozza", | ||||
|     "sent": "Inviata", | ||||
|     "all": "Tutte", | ||||
|     "select_all": "Seleziona tutto", | ||||
|     "choose_file": "Clicca per selezionare un file", | ||||
|     "choose_template": "Scegli un modello", | ||||
|     "choose": "Scegli", | ||||
|     "remove": "Rimuovi", | ||||
|     "powered_by": "Prodotto da", | ||||
|     "bytefury": "Bytefury", | ||||
|     "select_a_status": "Seleziona uno Stato", | ||||
|     "select_a_tax": "Seleziona una Tassa", | ||||
|     "search": "Cerca", | ||||
|     "are_you_sure": "Sei sicuro/a?", | ||||
|     "list_is_empty": "La lista è vuota.", | ||||
|     "no_tax_found": "Nessuna Tassa trovata!", | ||||
|     "four_zero_four": "404", | ||||
|     "you_got_lost": "Hoops! Ti sei perso", | ||||
|     "go_home": "Vai alla Home", | ||||
|     "test_mail_conf": "Configurazione della mail di test", | ||||
|     "send_mail_successfully": "Mail inviata con successo", | ||||
|     "setting_updated": "Configurazioni aggiornate con successo", | ||||
|     "select_state": "Seleziona lo Stato", | ||||
|     "select_country": "Seleziona Paese", | ||||
|     "select_city": "Seleziona Città", | ||||
|     "street_1": "Indirizzo 1", | ||||
|     "street_2": "Indirizzo 2", | ||||
|     "action_failed": "Errore", | ||||
|     "retry": "Retry" | ||||
|   }, | ||||
|   "dashboard": { | ||||
|     "select_year": "Seleziona anno", | ||||
|     "cards": { | ||||
|       "due_amount": "Somma dovuta", | ||||
|       "customers": "Clienti", | ||||
|       "invoices": "Fatture", | ||||
|       "estimates": "Preventivi" | ||||
|     }, | ||||
|     "chart_info": { | ||||
|       "total_sales": "Vendite", | ||||
|       "total_receipts": "Ricevute", | ||||
|       "total_expense": "Uscite", | ||||
|       "net_income": "Guadagno netto", | ||||
|       "year": "Seleziona anno" | ||||
|     }, | ||||
|     "weekly_invoices": { | ||||
|       "title": "Fatture a settimana" | ||||
|     }, | ||||
|     "monthly_chart": { | ||||
|       "title": "Entrate & Uscite" | ||||
|     }, | ||||
|     "recent_invoices_card": { | ||||
|       "title": "Fatture insolute", | ||||
|       "due_on": "Data di scadenza", | ||||
|       "customer": "Cliente", | ||||
|       "amount_due": "Ammontare dovuto", | ||||
|       "actions": "Azioni", | ||||
|       "view_all": "Vedi tutto" | ||||
|     }, | ||||
|     "recent_estimate_card": { | ||||
|       "title": "Preventivi recenti", | ||||
|       "date": "Data", | ||||
|       "customer": "Cliente", | ||||
|       "amount_due": "Ammontare dovuto", | ||||
|       "actions": "Azioni", | ||||
|       "view_all": "Vedi tutto" | ||||
|     } | ||||
|   }, | ||||
|   "tax_types": { | ||||
|     "name": "Nome", | ||||
|     "description": "Descrizione", | ||||
|     "percent": "Percento", | ||||
|     "compound_tax": "Tassa composta" | ||||
|   }, | ||||
|   "customers": { | ||||
|     "title": "Clienti", | ||||
|     "add_customer": "Aggiungi cliente", | ||||
|     "contacts_list": "Lista clienti", | ||||
|     "name": "Nome", | ||||
|     "display_name": "Mostra nome", | ||||
|     "primary_contact_name": "Riferimento", | ||||
|     "contact_name": "Nome Contatto", | ||||
|     "amount_due": "Ammontare dovuto", | ||||
|     "email": "Email", | ||||
|     "address": "Indirizzo", | ||||
|     "phone": "Telefono", | ||||
|     "website": "Sito web", | ||||
|     "country": "Paese", | ||||
|     "state": "Stato", | ||||
|     "city": "Città", | ||||
|     "zip_code": "Codice Postale", | ||||
|     "added_on": "Aggiunto il", | ||||
|     "action": "Azione", | ||||
|     "password": "Password", | ||||
|     "street_number": "Numero Civico", | ||||
|     "primary_currency": "Valùta Principale", | ||||
|     "add_new_customer": "Aggiungi nuovo Cliente", | ||||
|     "save_customer": "Salva Cliente", | ||||
|     "update_customer": "Aggiorna Cliente", | ||||
|     "customer": "Cliente | Clienti", | ||||
|     "new_customer": "Nuovo cliente", | ||||
|     "edit_customer": "Modifica Cliente", | ||||
|     "basic_info": "Informazioni", | ||||
|     "billing_address": "Indirizzo di Fatturazione", | ||||
|     "shipping_address": "Indirizzo di Spedizione", | ||||
|     "copy_billing_address": "Copia da Fatturazione", | ||||
|     "no_customers": "Ancora nessun Cliente!", | ||||
|     "no_customers_found": "Nessun cliente trovato!", | ||||
|     "list_of_customers": "Qui ci sarà la lista dei tuoi clienti", | ||||
|     "primary_display_name": "Mostra il Nome Principale", | ||||
|     "select_currency": "Selezione Valùta", | ||||
|     "select_a_customer": "Seleziona Cliente", | ||||
|     "type_or_click": "Scrivi o clicca per selezionare", | ||||
|  | ||||
|     "confirm_delete": "Non sarai in grado di recuperare questo cliente e tutte le relative fatture, stime e pagamenti. | Non sarai in grado di recuperare questi clienti e tutte le relative fatture, stime e pagamenti.", | ||||
|     "created_message": "Cliente creato con successo", | ||||
|     "updated_message": "Cliente aggiornato con successo", | ||||
|     "deleted_message": "Cliente cancellato con successo | Clienti cancellati con successo" | ||||
|   }, | ||||
|   "items": { | ||||
|     "title": "Commesse", | ||||
|     "items_list": "Lista Commesse", | ||||
|     "name": "Nome", | ||||
|     "unit": "Unità/Tipo", | ||||
|     "description": "Descrizione", | ||||
|     "added_on": "Aggiunto il", | ||||
|     "price": "Prezzo", | ||||
|     "date_of_creation": "Data di creazione", | ||||
|     "action": "Azione", | ||||
|     "add_item": "Aggiungi Commessa", | ||||
|     "save_item": "Salva", | ||||
|     "update_item": "Aggiorna", | ||||
|     "item": "Commessa | Commesse", | ||||
|     "add_new_item": "Aggiungi nuova Commessa", | ||||
|     "new_item": "Nuova Commessa", | ||||
|     "edit_item": "Modifica Commessa", | ||||
|     "no_items": "Ancora nessuna commessa!", | ||||
|     "list_of_items": "Qui ci sarà la lista delle commesse.", | ||||
|     "select_a_unit": "Seleziona", | ||||
|     "taxes": "Imposte", | ||||
|     "item_attached_message": "Non puoi eliminare una Commessa che è già attiva", | ||||
|     "confirm_delete": "Non potrai ripristinare la Commessa | Non potrai ripristinare le Commesse", | ||||
|     "created_message": "Commessa creata con successo", | ||||
|     "updated_message": "Commessa aggiornata con successo", | ||||
|     "deleted_message": "Commessa eliminata con successo | Commesse eliminate con successo" | ||||
|   }, | ||||
|   "estimates": { | ||||
|     "title": "Preventivi", | ||||
|     "estimate": "Preventivo | Preventivi", | ||||
|     "estimates_list": "Lista Preventivi", | ||||
|     "days": "{days} Giorni", | ||||
|     "months": "{months} Mese", | ||||
|     "years": "{years} Anno", | ||||
|     "all": "Tutti", | ||||
|     "paid": "Pagato", | ||||
|     "unpaid": "Non pagato", | ||||
|     "customer": "CLIENTE", | ||||
|     "ref_no": "RIF N.", | ||||
|     "number": "NUMERO", | ||||
|     "amount_due": "AMMONTARE DOVUTO", | ||||
|     "partially_paid": "Pagamento Parziale", | ||||
|     "total": "Totale", | ||||
|     "discount": "Sconto", | ||||
|     "sub_total": "Sub Totale", | ||||
|     "estimate_number": "Preventivo Numero", | ||||
|     "ref_number": "Numero di Rif.", | ||||
|     "contact": "Contatto", | ||||
|     "add_item": "Aggiungi un item", | ||||
|     "date": "Data", | ||||
|     "due_date": "Data di pagamento", | ||||
|     "expiry_date": "Data di scadenza", | ||||
|     "status": "Status", | ||||
|     "add_tax": "Aggiungi Imposta", | ||||
|     "amount": "Ammontare", | ||||
|     "action": "Azione", | ||||
|     "notes": "Note", | ||||
|     "tax": "Imposta", | ||||
|     "estimate_template": "Modello", | ||||
|     "convert_to_invoice": "Converti in Fattura", | ||||
|     "mark_as_sent": "Segna come Inviata", | ||||
|     "send_estimate": "Invia preventivo", | ||||
|     "record_payment": "Registra Pagamento", | ||||
|     "add_estimate": "Aggiungi Preventivo", | ||||
|     "save_estimate": "Salva Preventivo", | ||||
|     "confirm_conversion": "Questo preventivo verrà usato per generare una nuova fattura.", | ||||
|     "conversion_message": "Fattura creata", | ||||
|     "confirm_send_estimate": "Questo preventivo verrà inviato al cliente via mail", | ||||
|     "confirm_mark_as_sent": "Questo preventivo verrà contrassegnato come inviato", | ||||
|     "confirm_mark_as_accepted": "Questo preventivo verrà contrassegnato come Accettato", | ||||
|     "confirm_mark_as_rejected": "Questo preventivo verrà contrassegnato come Rifiutato", | ||||
|     "no_matching_estimates": "Nessun preventivo trovato!", | ||||
|     "mark_as_sent_successfully": "Preventivo contrassegnato come inviato con successo", | ||||
|     "send_estimate_successfully": "Preventivo inviato con successo", | ||||
|     "errors": { | ||||
|       "required": "Campo obbligatorio" | ||||
|     }, | ||||
|     "accepted": "Accettato", | ||||
|     "sent": "Inviato", | ||||
|     "draft": "Bozza", | ||||
|     "declined": "Rifiutato", | ||||
|     "new_estimate": "Nuovo Preventivo", | ||||
|     "add_new_estimate": "Crea Nuovo Preventivo", | ||||
|     "update_Estimate": "Aggiorna preventivo", | ||||
|     "edit_estimate": "Modifica Preventivo", | ||||
|     "items": "Commesse", | ||||
|     "Estimate": "Preventivo | Preventivi", | ||||
|     "add_new_tax": "Aggiungi una nuova tassa/imposta", | ||||
|     "no_estimates": "Ancora nessun preventivo!", | ||||
|     "list_of_estimates": "Questa sezione conterrà la lista dei preventivi.", | ||||
|     "mark_as_rejected": "Segna come Rifiutato", | ||||
|     "mark_as_accepted": "Segna come Accettato", | ||||
|  | ||||
|     "marked_as_accepted_message": "Preventivo contrassegnato come accettato", | ||||
|     "marked_as_rejected_message": "Preventivo contrassegnato come rifiutato", | ||||
|     "confirm_delete": "Non potrai più recuperare questo preventivo | Non potrai più recuperare questi preventivi", | ||||
|     "created_message": "Preventivo creato con successo", | ||||
|     "updated_message": "Preventivo modificato con successo", | ||||
|     "deleted_message": "Preventivo eliminato con successo | Preventivi eliminati con successo", | ||||
|     "user_email_does_not_exist": "La Email utente non esiste", | ||||
|     "something_went_wrong": "Si è verificato un errore", | ||||
|     "item": { | ||||
|       "title": "Titolo Commessa", | ||||
|       "description": "Descrizione", | ||||
|       "quantity": "Quantità", | ||||
|       "price": "Prezzo", | ||||
|       "discount": "Sconto", | ||||
|       "total": "Totale", | ||||
|       "total_discount": "Sconto Totale", | ||||
|       "sub_total": "Sub Totale", | ||||
|       "tax": "Tasse", | ||||
|       "amount": "Ammontare", | ||||
|       "select_an_item": "Scrivi o clicca per selezionare un item", | ||||
|       "type_item_description": "Scrivi una Descrizione (opzionale)" | ||||
|     } | ||||
|   }, | ||||
|   "invoices": { | ||||
|     "title": "Fatture", | ||||
|     "invoices_list": "Lista Fatture", | ||||
|     "days": "{days} Giorni", | ||||
|     "months": "{months} Mese", | ||||
|     "years": "{years} Anno", | ||||
|     "all": "Tutti", | ||||
|     "paid": "Pagato", | ||||
|     "unpaid": "Insoluto", | ||||
|     "customer": "CLIENTE", | ||||
|     "paid_status": "STATO DI PAGAMENTO", | ||||
|     "ref_no": "RIF N.", | ||||
|     "number": "NUMERO", | ||||
|     "amount_due": "AMMONTARE DOVUTO", | ||||
|     "partially_paid": "Parzialmente Pagata", | ||||
|     "total": "Totale", | ||||
|     "discount": "Sconto", | ||||
|     "sub_total": "Sub Totale", | ||||
|     "invoice": "Fattura | Fatture", | ||||
|     "invoice_number": "Numero Fattura", | ||||
|     "ref_number": "Rif Numero", | ||||
|     "contact": "Contatto", | ||||
|     "add_item": "Aggiungi Commessa/Item", | ||||
|     "date": "Data", | ||||
|     "due_date": "Data di pagamento", | ||||
|     "status": "Stato", | ||||
|     "add_tax": "Aggiungi Imposta", | ||||
|     "amount": "Ammontare", | ||||
|     "action": "Azione", | ||||
|     "notes": "Note", | ||||
|     "view": "Vedi", | ||||
|     "send_invoice": "Invia Fattura", | ||||
|     "invoice_template": "Modello Fattura", | ||||
|     "template": "Modello", | ||||
|     "mark_as_sent": "Segna come inviata", | ||||
|     "confirm_send_invoice": "Questa fattura sarà inviata via Mail al Cliente", | ||||
|     "invoice_mark_as_sent": "Questa fattura sarà contrassegnata come inviata", | ||||
|     "confirm_send": "Questa fattura sarà inviata via Mail al Cliente", | ||||
|     "invoice_date": "Data fattura", | ||||
|     "record_payment": "Registra Pagamento", | ||||
|     "add_new_invoice": "Aggiungi nuova Fattura", | ||||
|     "update_expense": "Aggiorna Costo", | ||||
|     "edit_invoice": "Modifica Fattura", | ||||
|     "new_invoice": "Nuova Fattura", | ||||
|     "save_invoice": "Salva fattura", | ||||
|     "update_invoice": "Aggiorna Fattura", | ||||
|     "add_new_tax": "Aggiungi tassa/imposta", | ||||
|     "no_invoices": "Ancora nessuna fattura!", | ||||
|     "list_of_invoices": "Questa sezione conterrà la lista delle Fatture.", | ||||
|     "select_invoice": "Seleziona Fattura", | ||||
|     "no_matching_invoices": "Nessuna fattura trovata!", | ||||
|     "mark_as_sent_successfully": "Fattura contassegnata come inviata con successo", | ||||
|     "send_invoice_successfully": "Fattura inviata con successo", | ||||
|     "cloned_successfully": "Fattura copiata con successo", | ||||
|     "clone_invoice": "Clona Fattura", | ||||
|     "confirm_clone": "Questa fattura verrà clonata in una nuova fattura", | ||||
|     "item": { | ||||
|       "title": "Titolo Commessa", | ||||
|       "description": "Descrizione", | ||||
|       "quantity": "Quantità", | ||||
|       "price": "Prezzo", | ||||
|       "discount": "Sconto", | ||||
|       "total": "Totale", | ||||
|       "total_discount": "Sconto Totale", | ||||
|       "sub_total": "Sub Totale", | ||||
|       "tax": "Tassa", | ||||
|       "amount": "Ammontare", | ||||
|       "select_an_item": "Scrivi o clicca per selezionare un item", | ||||
|       "type_item_description": "Scrivi una descrizione (opzionale)" | ||||
|     }, | ||||
|     "payment_attached_message": "Una delle fatture selezionate ha già associato un pagamento. Assicurati di eliminare il pagamento associato prima di procedere con la rimozione", | ||||
|     "confirm_delete": "Non potrai recuperare la Fattura cancellata | Non potrai recuperare le Fatture cancellate", | ||||
|     "created_message": "Fattura creata con successo", | ||||
|     "updated_message": "Fattura aggiornata con successo", | ||||
|     "deleted_message": "Fattura cancellata con successo | Fatture cancellate con successo", | ||||
|     "marked_as_sent_message": "Fattura contrassegnata come inviata con successo", | ||||
|     "user_email_does_not_exist": "La Email utente non esiste", | ||||
|     "something_went_wrong": "Si è verificato un errore", | ||||
|     "invalid_due_amount_message": "L'ammontare totale della fattura non può essere inferiore all'ammontare totale pagato per questa fattura. Modifica la fattura o cancella i pagamenti associati per continuare." | ||||
|   }, | ||||
|   "credit_notes": { | ||||
|     "title": "Note di Credito", | ||||
|     "credit_notes_list": "Lista Note di Credito", | ||||
|     "credit_notes": "Note di Credito", | ||||
|     "contact": "Contatta", | ||||
|     "date": "Data", | ||||
|     "amount": "Ammontare", | ||||
|     "action": "Azione", | ||||
|     "credit_number": "Numero Credito", | ||||
|     "notes": "Note", | ||||
|     "confirm_delete": "Vuoi cancellare questa nota di credito?", | ||||
|     "item": { | ||||
|       "title": "Titolo", | ||||
|       "description": "Descrizione", | ||||
|       "quantity": "Quantità", | ||||
|       "price": "Prezzo", | ||||
|       "discount": "Sconto", | ||||
|       "total": "Totale", | ||||
|       "total_discount": "Sconto Totale", | ||||
|       "sub_total": "Sub Totale", | ||||
|       "tax": "Tassa" | ||||
|     } | ||||
|   }, | ||||
|   "payments": { | ||||
|     "title": "Pagamenti", | ||||
|     "payments_list": "Lista Pagamenti", | ||||
|     "record_payment": "Registra Pagamento", | ||||
|     "customer": "Cliente", | ||||
|     "date": "Data", | ||||
|     "amount": "Ammontare", | ||||
|     "action": "Azione", | ||||
|     "payment_number": "Numero di pagamento", | ||||
|     "payment_mode": "Modalità di Pagamento", | ||||
|     "invoice": "Fattura", | ||||
|     "note": "Note", | ||||
|     "add_payment": "Aggiungi Pagamento", | ||||
|     "new_payment": "Nuovo Pagamento", | ||||
|     "edit_payment": "Modifica Pagamento", | ||||
|     "view_payment": "Vedi Pagamento", | ||||
|     "add_new_payment": "Aggiungi nuovo pagamento", | ||||
|     "send_payment_receipt": "Invia ricevuta di pagamento", | ||||
|     "save_payment": "Salva pagamento", | ||||
|     "update_payment": "Aggiorna pagamento", | ||||
|     "payment": "Pagamento | Pagamenti", | ||||
|     "no_payments": "Ancora nessun pagamento!", | ||||
|     "no_matching_payments": "Non ci sono pagamenti!", | ||||
|     "list_of_payments": "Questa sezione conterrà la lista dei pagamenti.", | ||||
|     "select_payment_mode": "Seleziona modalità di pagamento", | ||||
|     "confirm_send_payment": "Questo pagamento verrà inviato via email al cliente", | ||||
|     "send_payment_successfully": "Pagamento inviato con successo", | ||||
|     "user_email_does_not_exist": "Email utente non esiste", | ||||
|     "something_went_wrong": "si è verificato un errore", | ||||
|  | ||||
|     "confirm_delete": "Non potrai recuperare questo pagamento | Non potrai recuperare questi pagamenti", | ||||
|     "created_message": "Pagamento creato con successo", | ||||
|     "updated_message": "Pagamento aggiornato con successo", | ||||
|     "deleted_message": "Pagamento cancellato con successo | Pagamenti cancellati con successo", | ||||
|     "invalid_amount_message": "L'ammontare del pagamento non è valido" | ||||
|   }, | ||||
|   "expenses": { | ||||
|     "title": "Spese", | ||||
|     "expenses_list": "Lista Costi", | ||||
|     "expense_title": "Titolo", | ||||
|     "contact": "Contatto", | ||||
|     "category": "Categoria", | ||||
|     "customer": "Cliente", | ||||
|     "from_date": "Dalla Data", | ||||
|     "to_date": "Alla Data", | ||||
|     "expense_date": "Data", | ||||
|     "description": "Descrizione", | ||||
|     "receipt": "Ricevuta", | ||||
|     "amount": "Ammontare", | ||||
|     "action": "Azione", | ||||
|     "note": "Nota", | ||||
|     "category_id": "Id categoria", | ||||
|     "date": "Data Spesa", | ||||
|     "add_expense": "Aggiungi Spesa", | ||||
|     "add_new_expense": "Aggiungi nuova Spesa", | ||||
|     "save_expense": "Salva la Spesa", | ||||
|     "update_expense": "Aggiorna Spesa", | ||||
|     "download_receipt": "Scarica la Ricevuta", | ||||
|     "edit_expense": "Modifica Spesa", | ||||
|     "new_expense": "Nuova Spesa", | ||||
|     "expense": "Spesa | Spese", | ||||
|     "no_expenses": "Ancora nessuna spesa!", | ||||
|     "list_of_expenses": "Questa sezione conterrà la lista delle Spese.", | ||||
|  | ||||
|     "confirm_delete": "Non potrai recuperare questa spesa | Non potrai recuperare queste spese", | ||||
|     "created_message": "Spesa creata con successo", | ||||
|     "updated_message": "Spesa modificata con successo", | ||||
|     "deleted_message": "Spesa cancellata con successo | Spese cancellate con successo", | ||||
|     "categories": { | ||||
|       "categories_list": "Lista categorie", | ||||
|       "title": "Titolo", | ||||
|       "name": "Nome", | ||||
|       "description": "Descrizione", | ||||
|       "amount": "Ammontare", | ||||
|       "actions": "Azioni", | ||||
|       "add_category": "Aggiungi Categoria", | ||||
|       "new_category": "Nuova Categoria", | ||||
|       "category": "Categoria | Categorie", | ||||
|       "select_a_category": "Seleziona Categoria" | ||||
|     } | ||||
|   }, | ||||
|   "login": { | ||||
|     "email": "Email", | ||||
|     "password": "Password", | ||||
|     "forgot_password": "Password dimenticata?", | ||||
|     "or_signIn_with": "o fai login con", | ||||
|     "login": "Login", | ||||
|     "register": "Registrati", | ||||
|     "reset_password": "Resetta Password", | ||||
|     "password_reset_successfully": "Password Resettata con successo", | ||||
|     "enter_email": "Inserisci email", | ||||
|     "enter_password": "Inserisci Password", | ||||
|     "retype_password": "Ridigita Password", | ||||
|     "login_placeholder": "mail@example.com" | ||||
|   }, | ||||
|   "reports": { | ||||
|     "title": "Report", | ||||
|     "from_date": "Da", | ||||
|     "to_date": "A", | ||||
|     "status": "Status", | ||||
|     "paid": "Pagato", | ||||
|     "unpaid": "Non pagato", | ||||
|     "download_pdf": "Scarica PDF", | ||||
|     "view_pdf": "Vedi PDF", | ||||
|     "update_report": "Aggiorna Report", | ||||
|     "report": "Report | Reports", | ||||
|     "profit_loss": { | ||||
|       "profit_loss": "Guadagni & Perdite", | ||||
|       "to_date": "A", | ||||
|       "from_date": "Da", | ||||
|       "date_range": "Seleziona intervallo date" | ||||
|     }, | ||||
|     "sales": { | ||||
|       "sales": "Vendite", | ||||
|       "date_range": "Seleziona intervallo date", | ||||
|       "to_date": "A", | ||||
|       "from_date": "Da", | ||||
|       "report_type": "Tipo di report" | ||||
|     }, | ||||
|     "taxes": { | ||||
|       "taxes": "Tasse", | ||||
|       "to_date": "Alla data", | ||||
|       "from_date": "Dalla data", | ||||
|       "date_range": "Seleziona intervallo date" | ||||
|     }, | ||||
|     "errors": { | ||||
|       "required": "Campo obbligatorio" | ||||
|     }, | ||||
|     "invoices": { | ||||
|       "invoice": "Fattura", | ||||
|       "invoice_date": "Data fattura", | ||||
|       "due_date": "Data di pagamento", | ||||
|       "amount": "Ammontare", | ||||
|       "contact_name": "Nome contatto", | ||||
|       "status": "Status" | ||||
|     }, | ||||
|     "estimates": { | ||||
|       "estimate": "Preventivo", | ||||
|       "estimate_date": "Data preventivo", | ||||
|       "due_date": "Data di pagamento", | ||||
|       "estimate_number": "Numero di preventivo", | ||||
|       "ref_number": "Numero di Rif.", | ||||
|       "amount": "Ammontare", | ||||
|       "contact_name": "Nome contatto", | ||||
|       "status": "Status" | ||||
|     }, | ||||
|     "expenses": { | ||||
|       "expenses": "Spese", | ||||
|       "category": "Categoria", | ||||
|       "date": "Data", | ||||
|       "amount": "Ammontare", | ||||
|       "to_date": "Alla data", | ||||
|       "from_date": "Dalla data", | ||||
|       "date_range": "Seleziona intervallo date" | ||||
|     } | ||||
|   }, | ||||
|   "settings": { | ||||
|     "menu_title": { | ||||
|       "account_settings": "Impostazioni Account", | ||||
|       "company_information": "Informazioni Azienda", | ||||
|       "customization": "Personalizzazione", | ||||
|       "preferences": "Opzioni", | ||||
|       "notifications": "Notifiche", | ||||
|       "tax_types": "Tupi di Tasse", | ||||
|       "expense_category": "Categorie di spesa", | ||||
|       "update_app": "Aggiorna App" | ||||
|     }, | ||||
|     "title": "Impostazioni", | ||||
|     "setting": "Opzione | Impostazioni", | ||||
|     "general": "Generale", | ||||
|     "language": "Lingua", | ||||
|     "primary_currency": "Valuta Principale", | ||||
|     "timezone": "Time Zone", | ||||
|     "date_format": "Formato data", | ||||
|     "currencies": { | ||||
|       "title": "Valute", | ||||
|       "currency": "Valùta | Valute", | ||||
|       "currencies_list": "Lista valute", | ||||
|       "select_currency": "Seleziona Valùta", | ||||
|       "name": "Nome", | ||||
|       "code": "Codice", | ||||
|       "symbol": "Simbolo", | ||||
|       "precision": "Precisione", | ||||
|       "thousand_separator": "Separatore migliaia", | ||||
|       "decimal_separator": "Separatore decimali", | ||||
|       "position": "Posizione", | ||||
|       "position_of_symbol": "Posizione del Simbolo", | ||||
|       "right": "Destra", | ||||
|       "left": "Sinistra", | ||||
|       "action": "Azione", | ||||
|       "add_currency": "Aggiungi Valùta" | ||||
|     }, | ||||
|     "mail": { | ||||
|       "host": "Mail Host", | ||||
|       "port": "Mail Port", | ||||
|       "driver": "Mail Driver", | ||||
|       "secret": "Secret", | ||||
|       "mailgun_secret": "Mailgun Secret", | ||||
|       "mailgun_domain": "Domain", | ||||
|       "mailgun_endpoint": "Mailgun Endpoint", | ||||
|       "ses_secret": "SES Secret", | ||||
|       "ses_key": "SES Key", | ||||
|       "password": "Mail Password", | ||||
|       "username": "Mail Username", | ||||
|       "mail_config": "Configurazione Mail", | ||||
|       "from_name": "Nome Mittente Mail", | ||||
|       "from_mail": "Indirizzo Mittente Mail", | ||||
|       "encryption": "Mail Encryption", | ||||
|       "mail_config_desc": "Form per Configurazione Driver Mail per invio mail dall'App. Puoi anche configurare providers di terze parti come Sendgrid, SES, etc.." | ||||
|     }, | ||||
|     "pdf": { | ||||
|       "title": "Configurazione PDF", | ||||
|       "footer_text": "Testo Footer", | ||||
|       "pdf_layout": "Layout PDF" | ||||
|     }, | ||||
|     "company_info": { | ||||
|       "company_info": "Info azienda", | ||||
|       "company_name": "Nome azienda", | ||||
|       "company_logo": "Logo azienda", | ||||
|       "section_description": "Informazioni sulla tua azienda che saranno mostrate in fattura, preventivi ed altri documenti creati dell'applicazione.", | ||||
|       "phone": "Telefono", | ||||
|       "country": "Paese", | ||||
|       "state": "Stato", | ||||
|       "city": "Città", | ||||
|       "address": "Indirizzo", | ||||
|       "zip": "CAP", | ||||
|       "save": "Salva", | ||||
|       "updated_message": "Informazioni Azienda aggiornate con successo." | ||||
|     }, | ||||
|     "customization": { | ||||
|       "customization": "personalizzazione", | ||||
|       "save": "Salva", | ||||
|       "addresses": { | ||||
|         "title": "Indirizzi", | ||||
|         "section_description": "Puoi settare l'indirizzo di fatturazione del Cliente e/o il formato dell'indirizzo di spedizione (Mostrato solo sul PDF). ", | ||||
|         "customer_billing_address": "Indirizzo Fatturazione Cliente", | ||||
|         "customer_shipping_address": "Indirizzo spedizione Cliente", | ||||
|         "company_address": "Indirizzo Azienda", | ||||
|         "insert_fields": "Inserisci Campi", | ||||
|         "contact": "Contatto", | ||||
|         "address": "Indirizzo", | ||||
|         "display_name": "Mostra nome", | ||||
|         "primary_contact_name": "Nome contatto primario", | ||||
|         "email": "Email", | ||||
|         "website": "Sito web", | ||||
|         "name": "Nome", | ||||
|         "country": "Paese", | ||||
|         "state": "Stato", | ||||
|         "city": "Città", | ||||
|         "company_name": "Nome Azienda", | ||||
|         "address_street_1": "Indirizzo 1", | ||||
|         "address_street_2": "Indirizzo 2", | ||||
|         "phone": "Telefono", | ||||
|         "zip_code": "CAP/ZIP Code", | ||||
|         "address_setting_updated": "Indirizzo aggiornato con Successo" | ||||
|       }, | ||||
|       "updated_message": "Info azienda aggiornate con successo", | ||||
|  | ||||
|       "invoices": { | ||||
|         "title": "Fatture", | ||||
|         "notes": "Note", | ||||
|         "invoice_prefix": "Prefisso Fattura", | ||||
|         "invoice_settings": "Impostazioni fattura", | ||||
|         "autogenerate_invoice_number": "Auto genera numero di fattura", | ||||
|         "invoice_setting_description": "Disabilita, se non vuoi auto-generare i numeri delle fatture ogni volta che crei una nuova fattura.", | ||||
|         "enter_invoice_prefix": "Inserisci prefisso fattura", | ||||
|         "terms_and_conditions": "Termini e Condizioni", | ||||
|         "invoice_setting_updated": "Impostazioni fatture aggiornate con successo" | ||||
|       }, | ||||
|  | ||||
|       "estimates": { | ||||
|         "title": "Preventivi", | ||||
|         "estimate_prefix": "Prefisso Preventivi", | ||||
|         "estimate_settings": "Impostazioni Preventivi", | ||||
|         "autogenerate_estimate_number": "Auto-genera Numero di preventivo", | ||||
|         "estimate_setting_description": "Disabilita, se non vuoi autogenerare il numero di preventivo ogni volta che ne viene creato uno nuovo.", | ||||
|         "enter_estimate_prefix": "Inserisci prefisso preventivo", | ||||
|         "estimate_setting_updated": "Impostazioni preventivi aggiornate con successo" | ||||
|       }, | ||||
|  | ||||
|       "payments": { | ||||
|         "title": "Pagamenti", | ||||
|         "payment_prefix": "Prefisso Pagamento", | ||||
|         "payment_settings": "Impostazioni Pagamento", | ||||
|         "autogenerate_payment_number": "Auto genera il numero di Pagamento", | ||||
|         "payment_setting_description": "Disabilita, se non vuoi autogenerare il numero di pagamento ogni volta che ne viene creato uno nuovo.", | ||||
|         "enter_payment_prefix": "Inserisci prefisso di pagamento", | ||||
|         "payment_setting_updated": "Impostazioni di pagamento aggiornate con successo", | ||||
|         "payment_mode": "Modalità di pagamento", | ||||
|         "add_payment_mode": "Aggiungi modalità di pagamento", | ||||
|         "edit_payment_mode": "Modifica modalità di pagamento", | ||||
|         "mode_name": "Nome modalità", | ||||
|         "payment_mode_added": "Modalità di pagamento aggiunta", | ||||
|         "payment_mode_updated": "Modalità di pagamento aggiornata", | ||||
|         "payment_mode_confirm_delete": "Non potrai ripristinare la modalità di pagamento", | ||||
|         "already_in_use": "Modalità di pagamento già in uso", | ||||
|         "deleted_message": "Payment Mode deleted successfully" | ||||
|       }, | ||||
|  | ||||
|       "items": { | ||||
|         "title": "Items", | ||||
|         "units": "unità", | ||||
|         "add_item_unit": "Aggiungi Unità Item", | ||||
|         "edit_item_unit": "Modifica unità articolo", | ||||
|         "unit_name": "Nome", | ||||
|         "item_unit_added": "Unità aggiunta", | ||||
|         "item_unit_updated": "Unità aggiornata", | ||||
|         "item_unit_confirm_delete": "Non potrai ripristinare questa unità Item", | ||||
|         "already_in_use": "Unità Item già in uso", | ||||
|         "deleted_message": "Unità item eliminata con successo" | ||||
|       } | ||||
|     }, | ||||
|     "account_settings": { | ||||
|       "profile_picture": "Immagine profilo", | ||||
|       "name": "Nome", | ||||
|       "email": "Email", | ||||
|       "password": "Password", | ||||
|       "confirm_password": "Conferma Password", | ||||
|       "account_settings": "Impostazioni Account", | ||||
|       "save": "Salva", | ||||
|       "section_description": "Puoi aggiornare nome email e password utilizzando il form qui sotto.", | ||||
|       "updated_message": "Impostazioni account aggiornate con successo" | ||||
|     }, | ||||
|     "user_profile": { | ||||
|       "name": "Nome", | ||||
|       "email": "Email", | ||||
|       "password": "Password", | ||||
|       "confirm_password": "Conferma Password" | ||||
|     }, | ||||
|     "notification": { | ||||
|       "title": "Notifica", | ||||
|       "email": "Invia notifiche a", | ||||
|       "description": "Quali notifiche email vorresti ricevere quando qualcosa cambia?", | ||||
|       "invoice_viewed": "Fattura visualizzata", | ||||
|       "invoice_viewed_desc": "Quando il cliente visualizza la fattura inviata via dashboard applicazione.", | ||||
|       "estimate_viewed": "Preventivo visualizzato", | ||||
|       "estimate_viewed_desc": "Quando il cliente visualizza il preventivo inviato dall'applicazione.", | ||||
|       "save": "Salva", | ||||
|       "email_save_message": "Email salvata con successo", | ||||
|       "please_enter_email": "Inserisci Email" | ||||
|     }, | ||||
|     "tax_types": { | ||||
|       "title": "Tipi di Imposta", | ||||
|       "add_tax": "Aggiungi Imposta", | ||||
|       "edit_tax": "Modifica imposta", | ||||
|       "description": "Puoi aggiongere e rimuovere imposte a piacimento. Vengono supportate Tasse differenti per prodotti/servizi specifici esattamento come per le fatture.", | ||||
|       "add_new_tax": "Aggiungi nuova imposta", | ||||
|       "tax_settings": "Impostazioni Imposte", | ||||
|       "tax_per_item": "Tassa per prodotto/servizio", | ||||
|       "tax_name": "Nome imposta", | ||||
|       "compound_tax": "Imposta composta", | ||||
|       "percent": "Percento", | ||||
|       "action": "Azione", | ||||
|       "tax_setting_description": "Abilita se vuoi aggiungere imposte specifiche per prodotti o servizi. Di default le imposte sono aggiunte direttamente alla fattura.", | ||||
|       "created_message": "Tipo di imposta creato con successo", | ||||
|       "updated_message": "Tipo di imposta aggiornato con successo", | ||||
|       "deleted_message": "Tipo di imposta eliminato con successo", | ||||
|       "confirm_delete": "Non potrai ripristinare questo tipo di imposta", | ||||
|       "already_in_use": "Imposta già in uso" | ||||
|     }, | ||||
|     "expense_category": { | ||||
|       "title": "Categorie di spesa", | ||||
|       "action": "Azione", | ||||
|       "description": "Le categorie sono necessarie per aggiungere delle voci di spesa. Puoi aggiungere o eliminare queste categorie in base alle tue preferenze.", | ||||
|       "add_new_category": "Aggiungi nuova categoria", | ||||
|       "add_category": "Aggiungi categoria", | ||||
|       "edit_category": "Modifica categoria", | ||||
|       "category_name": "Nome Categoria", | ||||
|       "category_description": "Descrizione", | ||||
|       "created_message": "Categoria di spesa creata con successo", | ||||
|       "deleted_message": "Categoria di spesa eliminata con successo", | ||||
|       "updated_message": "Categoria di spesa aggiornata con successo", | ||||
|       "confirm_delete": "Non potrai ripristinare questa categoria di spesa", | ||||
|       "already_in_use": "Categoria già in uso" | ||||
|     }, | ||||
|     "preferences": { | ||||
|       "currency": "Valùta", | ||||
|       "language": "Lingua", | ||||
|       "time_zone": "Time Zone", | ||||
|       "fiscal_year": "Anno finanziario", | ||||
|       "date_format": "Formato Data", | ||||
|       "discount_setting": "Impostazione Sconto", | ||||
|       "discount_per_item": "Sconto Per Item ", | ||||
|       "discount_setting_description": "Abilita se vuoi aggiungere uno sconto ad uno specifica fattura. Di default, lo sconto è aggiunto direttamente in fattura.", | ||||
|       "save": "Salva", | ||||
|       "preference": "Preferenza | Preferenze", | ||||
|       "general_settings": "Impostazioni di default del sistema.", | ||||
|       "updated_message": "Preferenze aggiornate con successo", | ||||
|       "select_language": "seleziona lingua", | ||||
|       "select_time_zone": "Seleziona Time Zone", | ||||
|       "select_date_formate": "Seleziona Formato Data", | ||||
|       "select_financial_year": "Seleziona anno finanziario" | ||||
|     }, | ||||
|     "update_app": { | ||||
|       "title": "Aggiorna App", | ||||
|       "description": "Puoi facilmente aggiornare l'app. Aggiorna cliccando sul bottone qui sotto", | ||||
|       "check_update": "Controllo aggiornamenti", | ||||
|       "avail_update": "Aggiornamento disponibile", | ||||
|       "next_version": "Versione successiva", | ||||
|       "update": "Aggiorna ora", | ||||
|       "update_progress": "Aggiornamento in corso...", | ||||
|       "progress_text": "Sarà necessario qualche minuto. Per favore non aggiornare la pagina e non chiudere la finestra prima che l'aggiornamento sia completato", | ||||
|       "update_success": "L'App è aggiornata! Attendi che la pagina venga ricaricata automaticamente.", | ||||
|       "latest_message": "Nessun aggiornamneto disponibile! Sei già alla versione più recente.", | ||||
|       "current_version": "Versione corrente", | ||||
|       "download_zip_file": "Scarica il file ZIP", | ||||
|       "unzipping_package": "Pacchetto di decompressione", | ||||
|       "copying_files": "Copia dei file", | ||||
|       "running_migrations": "Esecuzione delle migrazioni", | ||||
|       "finishing_update": "Aggiornamento di finitura", | ||||
|       "update_failed": "Aggiornamento non riuscito", | ||||
|       "update_failed_text": "Scusate! L'aggiornamento non è riuscito il: passaggio {step}" | ||||
|     } | ||||
|   }, | ||||
|   "wizard": { | ||||
|     "account_info": "Informazioni Account", | ||||
|     "account_info_desc": "I dettagli qui sotto verranno usati per creare l'account principale dell'Amministratore. Puoi modificarli in qualsiasi momento dopo esserti loggato come Amministratore.", | ||||
|     "name": "Nome", | ||||
|     "email": "Email", | ||||
|     "password": "Password", | ||||
|     "confirm_password": "Conferma Password", | ||||
|     "save_cont": "Salva & Continua", | ||||
|     "company_info": "Informazioni Azienda", | ||||
|     "company_info_desc": "Questa informazione verrà mostrata nelle fatture. Puoi modificare queste informazione in un momento successivo dalla pagina delle impostazioni.", | ||||
|     "company_name": "Nome Azienda", | ||||
|     "company_logo": "Logo Azienda", | ||||
|     "logo_preview": "Anteprima Logo", | ||||
|     "preferences": "Impostazioni", | ||||
|     "preferences_desc": "Impostazioni di default del sistema.", | ||||
|     "country": "Paese", | ||||
|     "state": "Stato", | ||||
|     "city": "Città", | ||||
|     "address": "Indirizzo", | ||||
|     "street": "Indirizzo1 | Indirizzo2", | ||||
|     "phone": "Telefono", | ||||
|     "zip_code": "CAP/Zip Code", | ||||
|     "go_back": "Torna indietro", | ||||
|     "currency": "Valùta", | ||||
|     "language": "Lingua", | ||||
|     "time_zone": "Time Zone", | ||||
|     "fiscal_year": "Anno Finanziario", | ||||
|     "date_format": "Formato Date", | ||||
|     "from_address": "Indirizzo - Da", | ||||
|     "username": "Username", | ||||
|     "next": "Successivo", | ||||
|     "continue": "Continua", | ||||
|     "skip": "Salta", | ||||
|     "database": { | ||||
|       "database": "URL del sito & database", | ||||
|       "connection": "Connessione Database", | ||||
|       "host": "Database Host", | ||||
|       "port": "Database - Porta", | ||||
|       "password": "Database Password", | ||||
|       "app_url": "App URL", | ||||
|       "username": "Database Username", | ||||
|       "db_name": "Database Nome", | ||||
|       "desc": "Crea un database sul tuo server e setta le credenziali usando il form qui sotto." | ||||
|     }, | ||||
|     "permissions": { | ||||
|       "permissions": "Permessi", | ||||
|       "permission_confirm_title": "Sei sicuro di voler continuare?", | ||||
|       "permission_confirm_desc": "Controllo sui permessi Cartelle, fallito", | ||||
|       "permission_desc": "Qui sotto la lista dei permessi richiesti per far funzionare correttamente l'App. Se il controllo dei permessi fallisce, assicurati di aggiornare/modificare i permessi sulle cartelle." | ||||
|     }, | ||||
|     "mail": { | ||||
|       "host": "Mail Host", | ||||
|       "port": "Mail - Porta", | ||||
|       "driver": "Mail Driver", | ||||
|       "secret": "Secret", | ||||
|       "mailgun_secret": "Mailgun Secret", | ||||
|       "mailgun_domain": "Domain", | ||||
|       "mailgun_endpoint": "Mailgun Endpoint", | ||||
|       "ses_secret": "SES Secret", | ||||
|       "ses_key": "SES Key", | ||||
|       "password": "Mail Password", | ||||
|       "username": "Mail Username", | ||||
|       "mail_config": "Configurazione Mail", | ||||
|       "from_name": "Nome mittente mail", | ||||
|       "from_mail": "Indirizzo mittente mail", | ||||
|       "encryption": "Tipo di cifratura Mail", | ||||
|       "mail_config_desc": "Form per configurazione del 'driver mail' per inviare emails dall'App. Puoi anche configurare servizi di terze parti come Sendgrid, SES, ecc.." | ||||
|     }, | ||||
|     "req": { | ||||
|       "system_req": "Requisiti di Sistema", | ||||
|       "php_req_version": "Php (versione {version} richiesta)", | ||||
|       "check_req": "Controllo Requisiti", | ||||
|       "system_req_desc": "Crater ha alcuni requisiti di sistema. Assicurati che il server ha la versione di php richiesta e tutte le estensioni necessarie." | ||||
|     }, | ||||
|     "errors": { | ||||
|       "migrate_failed": "Migrate Failed", | ||||
|       "database_variables_save_error": "Cannot write configuration to .env file. Please check its file permissions", | ||||
|       "mail_variables_save_error": "Email configuration failed.", | ||||
|       "connection_failed": "Database connection failed", | ||||
|       "database_should_be_empty": "Database should be empty" | ||||
|     }, | ||||
|     "success": { | ||||
|       "mail_variables_save_successfully": "Email configurata con successo", | ||||
|       "database_variables_save_successfully": "Database configurato con successo." | ||||
|     } | ||||
|   }, | ||||
|   "layout_login": { | ||||
|     "copyright_crater": "Copyright @ Crater - 2020", | ||||
|     "super_simple_invoicing": "Fatturazione super semplice", | ||||
|     "for_freelancer": "per Freelancers &", | ||||
|     "small_businesses": "Medio Piccoli Business ", | ||||
|     "crater_help": "Crater ti aiuta a tracciare le spese, registrare pagamenti e generare graziose", | ||||
|     "invoices_and_estimates": "fatture & preventivi con possibilità di scegliere tra diversi modelli." | ||||
|   }, | ||||
|   "validation": { | ||||
|     "invalid_url": "URL non valido (es: http://www.crater.com)", | ||||
|     "required": "Campo obbligatorio", | ||||
|     "email_incorrect": "Email non corretta.", | ||||
|     "email_already_taken": "Email già in uso.", | ||||
|     "email_does_not_exist": "L'utente con questa email non esiste", | ||||
|     "item_unit_already_taken": "Questo nome item è già utilizzato", | ||||
|     "payment_mode_already_taken": "Questa modalità di pagamento è già stata inserita.", | ||||
|     "send_reset_link": "Invia Link di Reset", | ||||
|     "not_yet": "Non ancora? Invia di nuovo", | ||||
|     "password_min_length": "La password deve contenere {count} caratteri", | ||||
|     "name_min_length": "Il nome deve avere almeno {count} lettere.", | ||||
|     "enter_valid_tax_rate": "Inserisci un tasso di imposta valido", | ||||
|     "numbers_only": "Solo numeri.", | ||||
|     "characters_only": "Solo caratteri.", | ||||
|     "password_incorrect": "La Password deve essere identica", | ||||
|     "password_length": "La password deve essere lunga {count} caratteri.", | ||||
|     "qty_must_greater_than_zero": "La quantità deve essere maggiore di zero.", | ||||
|     "price_greater_than_zero": "Il prezzo deve essere maggiore di zero.", | ||||
|     "payment_greater_than_zero": "Il pagamento deve essere maggiore di zero.", | ||||
|     "payment_greater_than_due_amount": "Il pagamento inserito è maggiore di quello indicato in fattura.", | ||||
|     "quantity_maxlength": "La Quantità non può essere maggiore di 20 cifre.", | ||||
|     "price_maxlength": "Il prezzo non può contenere più di 20 cifre.", | ||||
|     "price_minvalue": "Il prezzo deve essere maggiore di 0.", | ||||
|     "amount_maxlength": "La somma non deve contenere più di 20 cifre.", | ||||
|     "amount_minvalue": "La somma deve essere maggiore di 0.", | ||||
|     "description_maxlength": "La Descrizione non deve superare i 255 caratteri.", | ||||
|     "subject_maxlength": "L'Oggetto non deve superare i 100 caratter.", | ||||
|     "message_maxlength": "Il messaggio non può superare i 255 caratteri.", | ||||
|     "maximum_options_error": "Massimo di {max} opzioni selezionate. Per selezionare un'altra opzione deseleziona prima una opzione.", | ||||
|     "notes_maxlength": "Le note non possono superare i 255 caratteri.", | ||||
|     "address_maxlength": "L'Indirizzo non può eccedere i 255 caratteri.", | ||||
|     "ref_number_maxlength": "Il Numero di Riferimento non può superare i 255 caratteri.", | ||||
|     "prefix_maxlength": "Il Prefisso non può superare i 5 caratteri.", | ||||
|     "something_went_wrong": "Si è verificato un errore" | ||||
|   } | ||||
| } | ||||
| @ -17,11 +17,17 @@ | ||||
|     "save": "Salvar", | ||||
|     "cancel": "Cancelar", | ||||
|     "update": "Atualizar", | ||||
|     "deselect": "Desmarcar", | ||||
|     "download": "Baixar", | ||||
|     "from_date": "A partir da Data", | ||||
|     "to_date": "Até a Data", | ||||
|     "from": "De", | ||||
|     "to": "Para", | ||||
|     "sort_by": "Ordenar por", | ||||
|     "ascending": "Crescente", | ||||
|     "descending": "Descendente", | ||||
|     "subject": "Sujeita", | ||||
|     "message": "Mensagem", | ||||
|     "go_back": "Voltar", | ||||
|     "back_to_login": "Voltar ao Login", | ||||
|     "home": "Home", | ||||
| @ -62,14 +68,16 @@ | ||||
|     "four_zero_four": "404", | ||||
|     "you_got_lost": "Ops! Se perdeu!", | ||||
|     "go_home": "Ir para Home", | ||||
|  | ||||
|     "test_mail_conf": "Testar configuração de email", | ||||
|     "send_mail_successfully": "Correio enviado com sucesso", | ||||
|     "setting_updated": "Configuração atualizada com sucesso", | ||||
|     "select_state": "Selecione Estado", | ||||
|     "select_country": "Selecionar pais", | ||||
|     "select_city": "Selecionar cidade", | ||||
|     "street_1": "Rua 1", | ||||
|     "street_2": "Rua # 2", | ||||
|     "action_failed": "Ação: Falhou" | ||||
|     "action_failed": "Ação: Falhou", | ||||
|     "retry": "Atualização falhou" | ||||
|   }, | ||||
|   "dashboard": { | ||||
|     "select_year": "Selecione Ano", | ||||
| @ -155,7 +163,7 @@ | ||||
|     "select_a_customer": "Selecione um cliente", | ||||
|     "type_or_click": "Digite ou clique para selecionar", | ||||
|  | ||||
|     "confirm_delete": "Você não poderá recuperar este cliente | Você não poderá recuperar esses clientes", | ||||
|     "confirm_delete": "Você não poderá recuperar este cliente e todas as faturas, estimativas e pagamentos relacionados. | Você não poderá recuperar esses clientes e todas as faturas, estimativas e pagamentos relacionados.", | ||||
|     "created_message": "Cliente criado com sucesso", | ||||
|     "updated_message": "Cliente atualizado com sucesso", | ||||
|     "deleted_message": "Cliente excluído com sucesso | Clientes excluídos com sucesso" | ||||
| @ -180,7 +188,7 @@ | ||||
|     "no_items": "Ainda não existe itens", | ||||
|     "list_of_items": "Esta seção conterá a lista de itens.", | ||||
|     "select_a_unit": "Seleciona unidade", | ||||
|  | ||||
|     "taxes": "Impostos", | ||||
|     "item_attached_message": "Não é possível excluir um item que já está em uso.", | ||||
|     "confirm_delete": "Você não poderá recuperar este item | Você não poderá recuperar esses itens", | ||||
|     "created_message": "Item criado com sucesso", | ||||
| @ -329,6 +337,9 @@ | ||||
|     "no_matching_invoices": "Não há faturas correspondentes!", | ||||
|     "mark_as_sent_successfully": "Fatura marcada como enviada com sucesso", | ||||
|     "send_invoice_successfully": "Fatura enviada com sucesso", | ||||
|     "cloned_successfully": "Fatura clonada com sucesso", | ||||
|     "clone_invoice": "Clonar fatura", | ||||
|     "confirm_clone": "Esta fatura será clonada em uma nova fatura", | ||||
|     "item": { | ||||
|       "title": "Titulo do Item", | ||||
|       "description": "Descrição", | ||||
| @ -394,6 +405,7 @@ | ||||
|     "edit_payment": "Editar Pagamento", | ||||
|     "view_payment": "Ver Pagamento", | ||||
|     "add_new_payment": "Adicionar novo Pagamento", | ||||
|     "send_payment_receipt": "Enviar recibo de pagamento", | ||||
|     "save_payment": "Salvar Pagamento", | ||||
|     "update_payment": "Atualizar Pagamento", | ||||
|     "payment": "Pagamento | Pagamentos", | ||||
| @ -414,6 +426,7 @@ | ||||
|     "expense_title": "Título", | ||||
|     "contact": "Contato", | ||||
|     "category": "Categoria", | ||||
|     "customer": "Cliente", | ||||
|     "from_date": "A partir da Data", | ||||
|     "to_date": "Até a Data", | ||||
|     "expense_date": "Data", | ||||
| @ -527,7 +540,7 @@ | ||||
|       "date_range": "Selecionar período" | ||||
|     } | ||||
|   }, | ||||
| "settings": { | ||||
|   "settings": { | ||||
|     "menu_title": { | ||||
|       "account_settings": "Configurações da conta", | ||||
|       "company_information": "Informações da Empresa", | ||||
| @ -601,281 +614,312 @@ | ||||
|       "updated_message": "Informações da Empresa atualizadas com sucesso" | ||||
|     }, | ||||
|     "customization": { | ||||
|         "customization": "Personalizar", | ||||
|         "save": "Salvar", | ||||
|         "addresses": { | ||||
|             "title": "Endereço", | ||||
|             "section_description": "Você pode definir o endereço de cobrança do cliente e o formato do endereço de entrega do cliente (exibido apenas em PDF).", | ||||
|             "customer_billing_address": "Endereço de Cobrança do Cliente", | ||||
|             "customer_shipping_address": "Endereço de Entrega do Cliente", | ||||
|             "company_address": "Endereço da Empresa", | ||||
|             "insert_fields": "Inserir Campos", | ||||
|             "contact": "Contato", | ||||
|             "address": "Endereço", | ||||
|             "display_name": "Nome em Exibição", | ||||
|             "primary_contact_name": "Nome do Contato Principal", | ||||
|             "email": "Email", | ||||
|             "website": "Website", | ||||
|             "name": "Nome", | ||||
|             "country": "Pais", | ||||
|             "state": "Estado", | ||||
|             "city": "Cidade", | ||||
|             "company_name": "Nome da Empresa", | ||||
|             "address_street_1": "Endereço Rua 1", | ||||
|             "address_street_2": "Endereço Rua 2", | ||||
|             "phone": "Telefone", | ||||
|             "zip_code": "CEP", | ||||
|             "address_setting_updated": "Configuração de Endereço Atualizada com Sucesso" | ||||
|         }, | ||||
|         "updated_message": "Informações da Empresa atualizadas com sucesso", | ||||
|  | ||||
|         "invoices": { | ||||
|             "title": "Faturas", | ||||
|             "notes": "Notas", | ||||
|             "invoice_prefix": "Fatura Prefixo", | ||||
|             "invoice_settings": "Configrações da Fatura", | ||||
|             "autogenerate_invoice_number": "Gerar automaticamente o número da Fatura", | ||||
|             "invoice_setting_description": "Desative isso, se você não deseja gerar automaticamente números da Fatura sempre que criar uma nova.", | ||||
|             "enter_invoice_prefix": "Digite o prefixo da Fatura", | ||||
|             "terms_and_conditions": "Termos e Condições", | ||||
|             "invoice_setting_updated": "Configuração da Fatura atualizada com sucesso" | ||||
|         }, | ||||
|  | ||||
|         "estimates": { | ||||
|             "title": "Orçamentos", | ||||
|             "estimate_prefix": "Orçamento Prefixo", | ||||
|             "estimate_settings": "Configurações do Orçamento", | ||||
|             "autogenerate_estimate_number": "Gerar automaticamente o número do Orçamento", | ||||
|             "estimate_setting_description": "Desative isso, se você não deseja gerar automaticamente números do Orçamento sempre que criar um novo.", | ||||
|             "enter_estimate_prefix": "Digite o prefixo do Orçamento", | ||||
|             "estimate_setting_updated": "Configuração do Orçamento atualizada com sucesso" | ||||
|         }, | ||||
|  | ||||
|         "payments": { | ||||
|             "title": "Pagamentos", | ||||
|             "payment_prefix": "Pagamento Prefixo", | ||||
|             "payment_settings": "Configurações de Pagamento", | ||||
|             "autogenerate_payment_number": "Gerar automaticamente número do Pagamento", | ||||
|             "payment_setting_description": "Desative isso, se você não deseja gerar automaticamente números do Pagamento sempre que criar um novo.", | ||||
|             "enter_payment_prefix": "Digite o Prefixo do Pagamento", | ||||
|             "payment_setting_updated": "Configurações de Pagamento atualizada com sucesso" | ||||
|         } | ||||
|     }, | ||||
|     "account_settings": { | ||||
|         "profile_picture": "Foto do Perfil", | ||||
|         "name": "Nome", | ||||
|       "customization": "Personalizar", | ||||
|       "save": "Salvar", | ||||
|       "addresses": { | ||||
|         "title": "Endereço", | ||||
|         "section_description": "Você pode definir o endereço de cobrança do cliente e o formato do endereço de entrega do cliente (exibido apenas em PDF).", | ||||
|         "customer_billing_address": "Endereço de Cobrança do Cliente", | ||||
|         "customer_shipping_address": "Endereço de Entrega do Cliente", | ||||
|         "company_address": "Endereço da Empresa", | ||||
|         "insert_fields": "Inserir Campos", | ||||
|         "contact": "Contato", | ||||
|         "address": "Endereço", | ||||
|         "display_name": "Nome em Exibição", | ||||
|         "primary_contact_name": "Nome do Contato Principal", | ||||
|         "email": "Email", | ||||
|         "password": "Senha", | ||||
|         "confirm_password": "Confirmar Senha", | ||||
|         "account_settings": "Configurações da conta", | ||||
|         "save": "Salvar", | ||||
|         "section_description": "Você pode atualizar seu nome, email e senha usando o formulário abaixo.", | ||||
|         "updated_message": "Configurações da conta atualizadas com sucesso" | ||||
|       }, | ||||
|       "user_profile": { | ||||
|         "website": "Website", | ||||
|         "name": "Nome", | ||||
|         "email": "Email", | ||||
|         "password": "Password", | ||||
|         "confirm_password": "Confirmar Senha" | ||||
|       }, | ||||
|       "notification": { | ||||
|         "title": "Notificação", | ||||
|         "email": "Enviar Notificações para", | ||||
|         "description": "Quais notificações por email você gostaria de receber quando algo mudar?", | ||||
|         "invoice_viewed": "Fatura Visualizada", | ||||
|         "invoice_viewed_desc": "Quando o seu cliente visualiza uma Fatura enviada pelo painel do Crater.", | ||||
|         "estimate_viewed": "Orçamento Visualizado", | ||||
|         "estimate_viewed_desc": "Quando o seu cliente visualiza um Orçamento enviada pelo painel do Crater.", | ||||
|         "save": "Salvar", | ||||
|         "email_save_message": "E-mail salvo com sucesso", | ||||
|         "please_enter_email": "Por favor digite um E-mail" | ||||
|       }, | ||||
|       "tax_types": { | ||||
|         "title": "Tipos de Impostos", | ||||
|         "add_tax": "Adicionar Imposto", | ||||
|         "description": "Você pode adicionar ou remover impostos conforme desejar. O Crater suporta impostos sobre itens individuais e também na Fatura.", | ||||
|         "add_new_tax": "Adicionar Novo Imposto", | ||||
|         "tax_settings": "Configurações de Impostos", | ||||
|         "tax_per_item": "Imposto por Item", | ||||
|         "tax_name": "Nome do Imposto", | ||||
|         "compound_tax": "Imposto Composto", | ||||
|         "percent": "Porcentagem", | ||||
|         "action": "Ação", | ||||
|         "tax_setting_description": "Habilite isso se desejar adicionar Impostos a itens da Fatura Idividualmente. Por padrão, os impostos são adicionados diretamente à Fatura.", | ||||
|         "created_message": "Tipo de Imposto criado com sucesso", | ||||
|         "updated_message": "Tipo de Imposto Atualizado com sucesso", | ||||
|         "deleted_message": "Tipo de Imposto Deletado com sucesso", | ||||
|         "confirm_delete": "Você não poderá recuperar este tipo de Imposto", | ||||
|         "already_in_use": "O Imposto já está em uso" | ||||
|       }, | ||||
|       "expense_category": { | ||||
|         "title": "Categoria de Despesa", | ||||
|         "action": "Ação", | ||||
|         "description": "As Categorias são necessárias para adicionar entradas de Despesas. Você pode adicionar ou remover essas Categorias de acordo com sua preferência.", | ||||
|         "add_new_category": "Adicionar Nova Categoria", | ||||
|         "category_name": "Nome da Categoria", | ||||
|         "category_description": "Descrição", | ||||
|         "created_message": "Categoria de Despesa criada com sucesso", | ||||
|         "deleted_message": "Categoria de Despesa excluída com sucesso", | ||||
|         "updated_message": "Categoria de Despesa atualizada com sucesso", | ||||
|         "confirm_delete": "Você não poderá recuperar esta Categoria de Despesa", | ||||
|         "already_in_use": "A categoria já está em uso" | ||||
|       }, | ||||
|       "preferences": { | ||||
|         "currency": "Moeda", | ||||
|         "language": "Idioma", | ||||
|         "time_zone": "Fuso Horário", | ||||
|         "fiscal_year": "Ano Financeiro", | ||||
|         "date_format": "Formato da Data", | ||||
|         "discount_setting": "Configuração de Desconto", | ||||
|         "discount_per_item": "Desconto por Item ", | ||||
|         "discount_setting_description": "Habilite isso se desejar adicionar desconto a itens de Fatura individualmente. Por padrão, o desconto é adicionado diretamente à Fatura.", | ||||
|         "save": "Salvar", | ||||
|         "preference": "Preferência | Preferências", | ||||
|         "general_settings": "Preferências padrão para o sistema.", | ||||
|         "updated_message": "Preferências atualizadas com sucesso", | ||||
|         "select_language": "Selecione um Idioma", | ||||
|         "select_time_zone": "Selecione um fuso horário", | ||||
|         "select_date_formate": "Selecione um formato de data", | ||||
|         "select_financial_year": "Selecione o ano financeiro" | ||||
|       }, | ||||
|       "update_app": { | ||||
|         "title": "Atualizar Aplicativo", | ||||
|         "description": "Você pode atualizar facilmente o Crater, verifique se hà novas atualizações, clicando no botão abaixo", | ||||
|         "check_update": "Verifique se há atualizações", | ||||
|         "avail_update": "Nova atualização disponível", | ||||
|         "next_version": "Próxima versão", | ||||
|         "update": "Atualizar agora", | ||||
|         "update_progress": "Atualização em progresso...", | ||||
|         "progress_text": "Levará apenas alguns minutos. Não atualize a tela ou feche a janela antes que a atualização seja concluída", | ||||
|         "update_success": "O aplicativo foi atualizado! Aguarde enquanto a janela do navegador é recarregada automaticamente.", | ||||
|         "latest_message": "Nenhuma atualização disponível! Você está na versão mais recente.", | ||||
|         "current_version": "Versão Atual" | ||||
|       } | ||||
|     }, | ||||
|     "wizard": { | ||||
|         "account_info": "Informação da conta", | ||||
|         "account_info_desc": "Os detalhes abaixo serão usados para criar a conta principal do administrador. Além disso, você pode alterar os detalhes a qualquer momento após o login.", | ||||
|         "name": "Nome", | ||||
|         "email": "Email", | ||||
|         "password": "Senha", | ||||
|         "confirm_password": "Confirmar Senha", | ||||
|         "save_cont": "Salvar e Continuar", | ||||
|         "company_info": "Informação da Empresa", | ||||
|         "company_info_desc": "Esta informação será exibida nas Faturas. Observe que você pode editar isso mais tarde na página de configurações.", | ||||
|         "company_name": "Nome da Empresa", | ||||
|         "company_logo": "Logotipo da Empresa", | ||||
|         "logo_preview": "Previsualizar Logotipo", | ||||
|         "preferences": "Preferências", | ||||
|         "preferences_desc": "Preferências padrão para o sistema.", | ||||
|         "country": "Pais", | ||||
|         "state": "Estado", | ||||
|         "city": "Cidade", | ||||
|         "address": "Endereço", | ||||
|         "street": "Rua 1 | Rua 2", | ||||
|         "company_name": "Nome da Empresa", | ||||
|         "address_street_1": "Endereço Rua 1", | ||||
|         "address_street_2": "Endereço Rua 2", | ||||
|         "phone": "Telefone", | ||||
|         "zip_code": "CEP", | ||||
|         "go_back": "Voltar", | ||||
|         "currency": "Moeda", | ||||
|         "language": "Idioma", | ||||
|         "time_zone": "Fuso Horário", | ||||
|         "fiscal_year": "Ano Financeiro", | ||||
|         "date_format": "Formato de Data", | ||||
|         "from_address": "Do Endereço", | ||||
|         "username": "Nome de Usuário", | ||||
|         "next": "Próximo", | ||||
|         "continue": "Continuar", | ||||
|         "skip": "Pular", | ||||
|         "database": { | ||||
|           "database": "URL do Site e Base de Dados", | ||||
|           "connection": "Conexão da Base de Dados", | ||||
|           "host": "Host da Base de Dados", | ||||
|           "port": "Porta da Base de Dados", | ||||
|           "password": "Senha da Base de Dados", | ||||
|           "app_url": "URL do Aplicativo", | ||||
|           "username": "Usuário da Base de Dados", | ||||
|           "db_name": "Nome da Base de Dados", | ||||
|           "desc": "Crie um Banco de Dados no seu servidor e defina as credenciais usando o formulário abaixo." | ||||
|         }, | ||||
|         "permissions": { | ||||
|           "permissions": "Permissões", | ||||
|           "permission_confirm_title": "Você tem certeza que quer continuar?", | ||||
|           "permission_confirm_desc": "Falha na verificação de permissão da pasta", | ||||
|           "permission_desc": "Abaixo está a lista de permissões de pasta que são necessárias para que o aplicativo funcione. Se a verificação da permissão falhar, atualize as permissões da pasta." | ||||
|         }, | ||||
|         "mail": { | ||||
|           "host": "Host do email", | ||||
|           "port": "Porta do email", | ||||
|           "driver": "Driver do email", | ||||
|           "secret": "Segredo", | ||||
|           "mailgun_secret": "Segredo do Mailgun", | ||||
|           "mailgun_domain": "Domínio", | ||||
|           "mailgun_endpoint": "Endpoint do Mailgun", | ||||
|           "ses_secret": "Segredo do SES", | ||||
|           "ses_key": "Chave SES", | ||||
|           "password": "Senha do email", | ||||
|           "username": "Nome do Usuário do email", | ||||
|           "mail_config": "Configuração de email", | ||||
|           "from_name": "Nome do email", | ||||
|           "from_mail": "Endereço de email", | ||||
|           "encryption": "Criptografia de email", | ||||
|           "mail_config_desc": "Abaixo está o formulário para configurar o driver de email que será usado para enviar emails do aplicativo. Você também pode configurar provedores de terceiros como Sendgrid, SES etc." | ||||
|         }, | ||||
|         "req": { | ||||
|           "system_req": "Requisitos de Sistema", | ||||
|           "php_req_version": "PHP (versão {version} obrigatória)", | ||||
|           "check_req": "Verificar Requisitos", | ||||
|           "system_req_desc": "O Crater tem alguns requisitos de servidor. Verifique se o seu servidor possui a versão do PHP necessária e todas as extensões mencionadas abaixo." | ||||
|         }, | ||||
|         "errors": { | ||||
|           "migrate_failed": "Falha na migração", | ||||
|           "database_variables_save_error": "Não é possível gravar a configuração no arquivo .env. Por favor, verifique suas permissões de arquivo", | ||||
|           "mail_variables_save_error": "A configuração do email falhou.", | ||||
|           "connection_failed": "Falha na conexão com o banco de dados", | ||||
|           "database_should_be_empty": "O banco de dados deve estar vazio" | ||||
|         }, | ||||
|         "success": { | ||||
|           "mail_variables_save_successfully": "Email configurado com sucesso", | ||||
|           "database_variables_save_successfully": "Banco de dados configurado com sucesso." | ||||
|         } | ||||
|         "address_setting_updated": "Configuração de Endereço Atualizada com Sucesso" | ||||
|       }, | ||||
|       "layout_login": { | ||||
|         "copyright_crater": "Copyright @ Crater - 2020", | ||||
|         "super_simple_invoicing": "Faturamento super simples", | ||||
|         "for_freelancer": "Para Freelancers &", | ||||
|         "small_businesses": "Pequenos Negócios ", | ||||
|         "crater_help": "Crater ajuda a rastrear despesas, registrar pagamentos e gerar belas", | ||||
|         "invoices_and_estimates": "Faturas e Orçamentos com capacidade de escolher vários modelos." | ||||
|       "updated_message": "Informações da Empresa atualizadas com sucesso", | ||||
|  | ||||
|       "invoices": { | ||||
|         "title": "Faturas", | ||||
|         "notes": "Notas", | ||||
|         "invoice_prefix": "Fatura Prefixo", | ||||
|         "invoice_settings": "Configrações da Fatura", | ||||
|         "autogenerate_invoice_number": "Gerar automaticamente o número da Fatura", | ||||
|         "invoice_setting_description": "Desative isso, se você não deseja gerar automaticamente números da Fatura sempre que criar uma nova.", | ||||
|         "enter_invoice_prefix": "Digite o prefixo da Fatura", | ||||
|         "terms_and_conditions": "Termos e Condições", | ||||
|         "invoice_setting_updated": "Configuração da Fatura atualizada com sucesso" | ||||
|       }, | ||||
|       "validation": { | ||||
|         "invalid_url": "url inválidas (ex: http://www.crater.com)", | ||||
|         "required": "Campo obrigatório", | ||||
|         "email_incorrect": "E-mail incorreto", | ||||
|         "email_already_taken": "O email já foi recebido.", | ||||
|         "email_does_not_exist": "O usuário com determinado email não existe", | ||||
|         "send_reset_link": "Enviar link de redefinição", | ||||
|         "not_yet": "Ainda não? Envie novamente", | ||||
|         "password_min_length": "A senha deve conter {count} caracteres", | ||||
|         "name_min_length": "O nome deve ter pelo menos {count} letras.", | ||||
|         "enter_valid_tax_rate": "Insira uma taxa de imposto válida", | ||||
|         "numbers_only": "Apenas Números.", | ||||
|         "characters_only": "Apenas Caracteres.", | ||||
|         "password_incorrect": "As senhas devem ser idênticas", | ||||
|         "password_length": "A senha deve ter {count} caracteres.", | ||||
|         "qty_must_greater_than_zero": "A quantidade deve ser maior que zero.", | ||||
|         "price_greater_than_zero": "O preço deve ser maior que zero.", | ||||
|         "payment_greater_than_zero": "O pagamento deve ser maior que zero.", | ||||
|         "payment_greater_than_due_amount": "O pagamento inserido é mais do que o valor devido desta fatura.", | ||||
|         "quantity_maxlength": "A quantidade não deve exceder 20 dígitos.", | ||||
|         "price_maxlength": "O preço não deve ser superior a 20 dígitos.", | ||||
|         "price_minvalue": "O preço deve ser maior que 0.", | ||||
|         "amount_maxlength": "Montante não deve ser superior a 20 dígitos.", | ||||
|         "amount_minvalue": "Montante deve ser maior que zero", | ||||
|         "description_maxlength": "A descrição não deve ter mais que 255 caracteres.", | ||||
|         "maximum_options_error": "Máximo de {max} opções selecionadas. Primeiro remova uma opção selecionada para selecionar outra.", | ||||
|         "notes_maxlength": "As anotações não devem ter mais que 255 caracteres.", | ||||
|         "address_maxlength": "O endereço não deve ter mais que 255 caracteres.", | ||||
|         "ref_number_maxlength": "O número de referência não deve ter mais que 255 caracteres.", | ||||
|         "prefix_maxlength": "O prefixo não deve ter mais que 5 caracteres." | ||||
|  | ||||
|       "estimates": { | ||||
|         "title": "Orçamentos", | ||||
|         "estimate_prefix": "Orçamento Prefixo", | ||||
|         "estimate_settings": "Configurações do Orçamento", | ||||
|         "autogenerate_estimate_number": "Gerar automaticamente o número do Orçamento", | ||||
|         "estimate_setting_description": "Desative isso, se você não deseja gerar automaticamente números do Orçamento sempre que criar um novo.", | ||||
|         "enter_estimate_prefix": "Digite o prefixo do Orçamento", | ||||
|         "estimate_setting_updated": "Configuração do Orçamento atualizada com sucesso" | ||||
|       }, | ||||
|  | ||||
|       "payments": { | ||||
|         "title": "Pagamentos", | ||||
|         "payment_prefix": "Pagamento Prefixo", | ||||
|         "payment_settings": "Configurações de Pagamento", | ||||
|         "autogenerate_payment_number": "Gerar automaticamente número do Pagamento", | ||||
|         "payment_setting_description": "Desative isso, se você não deseja gerar automaticamente números do Pagamento sempre que criar um novo.", | ||||
|         "enter_payment_prefix": "Digite o Prefixo do Pagamento", | ||||
|         "payment_setting_updated": "Configurações de Pagamento atualizada com sucesso", | ||||
|         "payment_mode": "Modo de pagamento", | ||||
|         "add_payment_mode": "Adicionar modo de pagamento", | ||||
|         "edit_payment_mode": "Editar modo de pagamento", | ||||
|         "mode_name": "Nome do modo", | ||||
|         "payment_mode_added": "Modo de pagamento adicionado", | ||||
|         "payment_mode_updated": "Modo de pagamento atualizado", | ||||
|         "payment_mode_confirm_delete": "Você não poderá recuperar este modo de pagamento", | ||||
|         "already_in_use": "O modo de pagamento já está em uso", | ||||
|         "deleted_message": "Modo de pagamento excluído com sucesso" | ||||
|       }, | ||||
|       "items": { | ||||
|         "title": "Itens", | ||||
|         "units": "unidades", | ||||
|         "add_item_unit": "Adicionar unidade de item", | ||||
|         "edit_item_unit": "Editar unidade de item", | ||||
|         "unit_name": "Nome da unidade", | ||||
|         "item_unit_added": "Item Unit Added", | ||||
|         "item_unit_updated": "Item Unit Updated", | ||||
|         "item_unit_confirm_delete": "Você não poderá recuperar esta unidade de item", | ||||
|         "already_in_use": "A unidade do item já está em uso", | ||||
|         "deleted_message": "Unidade de item excluída com sucesso" | ||||
|       } | ||||
|     }, | ||||
|     "account_settings": { | ||||
|       "profile_picture": "Foto do Perfil", | ||||
|       "name": "Nome", | ||||
|       "email": "Email", | ||||
|       "password": "Senha", | ||||
|       "confirm_password": "Confirmar Senha", | ||||
|       "account_settings": "Configurações da conta", | ||||
|       "save": "Salvar", | ||||
|       "section_description": "Você pode atualizar seu nome, email e senha usando o formulário abaixo.", | ||||
|       "updated_message": "Configurações da conta atualizadas com sucesso" | ||||
|     }, | ||||
|     "user_profile": { | ||||
|       "name": "Nome", | ||||
|       "email": "Email", | ||||
|       "password": "Password", | ||||
|       "confirm_password": "Confirmar Senha" | ||||
|     }, | ||||
|     "notification": { | ||||
|       "title": "Notificação", | ||||
|       "email": "Enviar Notificações para", | ||||
|       "description": "Quais notificações por email você gostaria de receber quando algo mudar?", | ||||
|       "invoice_viewed": "Fatura Visualizada", | ||||
|       "invoice_viewed_desc": "Quando o seu cliente visualiza uma Fatura enviada pelo painel do Crater.", | ||||
|       "estimate_viewed": "Orçamento Visualizado", | ||||
|       "estimate_viewed_desc": "Quando o seu cliente visualiza um Orçamento enviada pelo painel do Crater.", | ||||
|       "save": "Salvar", | ||||
|       "email_save_message": "E-mail salvo com sucesso", | ||||
|       "please_enter_email": "Por favor digite um E-mail" | ||||
|     }, | ||||
|     "tax_types": { | ||||
|       "title": "Tipos de Impostos", | ||||
|       "add_tax": "Adicionar Imposto", | ||||
|       "edit_tax": "Editar imposto", | ||||
|       "description": "Você pode adicionar ou remover impostos conforme desejar. O Crater suporta impostos sobre itens individuais e também na Fatura.", | ||||
|       "add_new_tax": "Adicionar Novo Imposto", | ||||
|       "tax_settings": "Configurações de Impostos", | ||||
|       "tax_per_item": "Imposto por Item", | ||||
|       "tax_name": "Nome do Imposto", | ||||
|       "compound_tax": "Imposto Composto", | ||||
|       "percent": "Porcentagem", | ||||
|       "action": "Ação", | ||||
|       "tax_setting_description": "Habilite isso se desejar adicionar Impostos a itens da Fatura Idividualmente. Por padrão, os impostos são adicionados diretamente à Fatura.", | ||||
|       "created_message": "Tipo de Imposto criado com sucesso", | ||||
|       "updated_message": "Tipo de Imposto Atualizado com sucesso", | ||||
|       "deleted_message": "Tipo de Imposto Deletado com sucesso", | ||||
|       "confirm_delete": "Você não poderá recuperar este tipo de Imposto", | ||||
|       "already_in_use": "O Imposto já está em uso" | ||||
|     }, | ||||
|     "expense_category": { | ||||
|       "title": "Categoria de Despesa", | ||||
|       "action": "Ação", | ||||
|       "description": "As Categorias são necessárias para adicionar entradas de Despesas. Você pode adicionar ou remover essas Categorias de acordo com sua preferência.", | ||||
|       "add_new_category": "Adicionar Nova Categoria", | ||||
|       "add_category": "Adicionar categoria", | ||||
|       "edit_category": "Editar categoria", | ||||
|       "category_name": "Nome da Categoria", | ||||
|       "category_description": "Descrição", | ||||
|       "created_message": "Categoria de Despesa criada com sucesso", | ||||
|       "deleted_message": "Categoria de Despesa excluída com sucesso", | ||||
|       "updated_message": "Categoria de Despesa atualizada com sucesso", | ||||
|       "confirm_delete": "Você não poderá recuperar esta Categoria de Despesa", | ||||
|       "already_in_use": "A categoria já está em uso" | ||||
|     }, | ||||
|     "preferences": { | ||||
|       "currency": "Moeda", | ||||
|       "language": "Idioma", | ||||
|       "time_zone": "Fuso Horário", | ||||
|       "fiscal_year": "Ano Financeiro", | ||||
|       "date_format": "Formato da Data", | ||||
|       "discount_setting": "Configuração de Desconto", | ||||
|       "discount_per_item": "Desconto por Item ", | ||||
|       "discount_setting_description": "Habilite isso se desejar adicionar desconto a itens de Fatura individualmente. Por padrão, o desconto é adicionado diretamente à Fatura.", | ||||
|       "save": "Salvar", | ||||
|       "preference": "Preferência | Preferências", | ||||
|       "general_settings": "Preferências padrão para o sistema.", | ||||
|       "updated_message": "Preferências atualizadas com sucesso", | ||||
|       "select_language": "Selecione um Idioma", | ||||
|       "select_time_zone": "Selecione um fuso horário", | ||||
|       "select_date_formate": "Selecione um formato de data", | ||||
|       "select_financial_year": "Selecione o ano financeiro" | ||||
|     }, | ||||
|     "update_app": { | ||||
|       "title": "Atualizar Aplicativo", | ||||
|       "description": "Você pode atualizar facilmente o Crater, verifique se hà novas atualizações, clicando no botão abaixo", | ||||
|       "check_update": "Verifique se há atualizações", | ||||
|       "avail_update": "Nova atualização disponível", | ||||
|       "next_version": "Próxima versão", | ||||
|       "update": "Atualizar agora", | ||||
|       "update_progress": "Atualização em progresso...", | ||||
|       "progress_text": "Levará apenas alguns minutos. Não atualize a tela ou feche a janela antes que a atualização seja concluída", | ||||
|       "update_success": "O aplicativo foi atualizado! Aguarde enquanto a janela do navegador é recarregada automaticamente.", | ||||
|       "latest_message": "Nenhuma atualização disponível! Você está na versão mais recente.", | ||||
|       "current_version": "Versão Atual", | ||||
|       "download_zip_file": "Baixar arquivo ZIP", | ||||
|       "unzipping_package": "Descompactando o pacote", | ||||
|       "copying_files": "Copiando arquivos", | ||||
|       "running_migrations": "Executando migrações", | ||||
|       "finishing_update": "Atualização de acabamento", | ||||
|       "update_failed": "Atualização falhou", | ||||
|       "update_failed_text": "Desculpa! Sua atualização falhou em: {step} step" | ||||
|     } | ||||
|   }, | ||||
|   "wizard": { | ||||
|     "account_info": "Informação da conta", | ||||
|     "account_info_desc": "Os detalhes abaixo serão usados para criar a conta principal do administrador. Além disso, você pode alterar os detalhes a qualquer momento após o login.", | ||||
|     "name": "Nome", | ||||
|     "email": "Email", | ||||
|     "password": "Senha", | ||||
|     "confirm_password": "Confirmar Senha", | ||||
|     "save_cont": "Salvar e Continuar", | ||||
|     "company_info": "Informação da Empresa", | ||||
|     "company_info_desc": "Esta informação será exibida nas Faturas. Observe que você pode editar isso mais tarde na página de configurações.", | ||||
|     "company_name": "Nome da Empresa", | ||||
|     "company_logo": "Logotipo da Empresa", | ||||
|     "logo_preview": "Previsualizar Logotipo", | ||||
|     "preferences": "Preferências", | ||||
|     "preferences_desc": "Preferências padrão para o sistema.", | ||||
|     "country": "Pais", | ||||
|     "state": "Estado", | ||||
|     "city": "Cidade", | ||||
|     "address": "Endereço", | ||||
|     "street": "Rua 1 | Rua 2", | ||||
|     "phone": "Telefone", | ||||
|     "zip_code": "CEP", | ||||
|     "go_back": "Voltar", | ||||
|     "currency": "Moeda", | ||||
|     "language": "Idioma", | ||||
|     "time_zone": "Fuso Horário", | ||||
|     "fiscal_year": "Ano Financeiro", | ||||
|     "date_format": "Formato de Data", | ||||
|     "from_address": "Do Endereço", | ||||
|     "username": "Nome de Usuário", | ||||
|     "next": "Próximo", | ||||
|     "continue": "Continuar", | ||||
|     "skip": "Pular", | ||||
|     "database": { | ||||
|       "database": "URL do Site e Base de Dados", | ||||
|       "connection": "Conexão da Base de Dados", | ||||
|       "host": "Host da Base de Dados", | ||||
|       "port": "Porta da Base de Dados", | ||||
|       "password": "Senha da Base de Dados", | ||||
|       "app_url": "URL do Aplicativo", | ||||
|       "username": "Usuário da Base de Dados", | ||||
|       "db_name": "Nome da Base de Dados", | ||||
|       "desc": "Crie um Banco de Dados no seu servidor e defina as credenciais usando o formulário abaixo." | ||||
|     }, | ||||
|     "permissions": { | ||||
|       "permissions": "Permissões", | ||||
|       "permission_confirm_title": "Você tem certeza que quer continuar?", | ||||
|       "permission_confirm_desc": "Falha na verificação de permissão da pasta", | ||||
|       "permission_desc": "Abaixo está a lista de permissões de pasta que são necessárias para que o aplicativo funcione. Se a verificação da permissão falhar, atualize as permissões da pasta." | ||||
|     }, | ||||
|     "mail": { | ||||
|       "host": "Host do email", | ||||
|       "port": "Porta do email", | ||||
|       "driver": "Driver do email", | ||||
|       "secret": "Segredo", | ||||
|       "mailgun_secret": "Segredo do Mailgun", | ||||
|       "mailgun_domain": "Domínio", | ||||
|       "mailgun_endpoint": "Endpoint do Mailgun", | ||||
|       "ses_secret": "Segredo do SES", | ||||
|       "ses_key": "Chave SES", | ||||
|       "password": "Senha do email", | ||||
|       "username": "Nome do Usuário do email", | ||||
|       "mail_config": "Configuração de email", | ||||
|       "from_name": "Nome do email", | ||||
|       "from_mail": "Endereço de email", | ||||
|       "encryption": "Criptografia de email", | ||||
|       "mail_config_desc": "Abaixo está o formulário para configurar o driver de email que será usado para enviar emails do aplicativo. Você também pode configurar provedores de terceiros como Sendgrid, SES etc." | ||||
|     }, | ||||
|     "req": { | ||||
|       "system_req": "Requisitos de Sistema", | ||||
|       "php_req_version": "PHP (versão {version} obrigatória)", | ||||
|       "check_req": "Verificar Requisitos", | ||||
|       "system_req_desc": "O Crater tem alguns requisitos de servidor. Verifique se o seu servidor possui a versão do PHP necessária e todas as extensões mencionadas abaixo." | ||||
|     }, | ||||
|     "errors": { | ||||
|       "migrate_failed": "Falha na migração", | ||||
|       "database_variables_save_error": "Não é possível gravar a configuração no arquivo .env. Por favor, verifique suas permissões de arquivo", | ||||
|       "mail_variables_save_error": "A configuração do email falhou.", | ||||
|       "connection_failed": "Falha na conexão com o banco de dados", | ||||
|       "database_should_be_empty": "O banco de dados deve estar vazio" | ||||
|     }, | ||||
|     "success": { | ||||
|       "mail_variables_save_successfully": "Email configurado com sucesso", | ||||
|       "database_variables_save_successfully": "Banco de dados configurado com sucesso." | ||||
|     } | ||||
|   }, | ||||
|   "layout_login": { | ||||
|     "copyright_crater": "Copyright @ Crater - 2020", | ||||
|     "super_simple_invoicing": "Faturamento super simples", | ||||
|     "for_freelancer": "Para Freelancers &", | ||||
|     "small_businesses": "Pequenos Negócios ", | ||||
|     "crater_help": "Crater ajuda a rastrear despesas, registrar pagamentos e gerar belas", | ||||
|     "invoices_and_estimates": "Faturas e Orçamentos com capacidade de escolher vários modelos." | ||||
|   }, | ||||
|   "validation": { | ||||
|     "invalid_url": "url inválidas (ex: http://www.crater.com)", | ||||
|     "required": "Campo obrigatório", | ||||
|     "email_incorrect": "E-mail incorreto", | ||||
|     "email_already_taken": "O email já foi recebido.", | ||||
|     "email_does_not_exist": "O usuário com determinado email não existe", | ||||
|     "send_reset_link": "Enviar link de redefinição", | ||||
|     "not_yet": "Ainda não? Envie novamente", | ||||
|     "password_min_length": "A senha deve conter {count} caracteres", | ||||
|     "name_min_length": "O nome deve ter pelo menos {count} letras.", | ||||
|     "enter_valid_tax_rate": "Insira uma taxa de imposto válida", | ||||
|     "numbers_only": "Apenas Números.", | ||||
|     "characters_only": "Apenas Caracteres.", | ||||
|     "password_incorrect": "As senhas devem ser idênticas", | ||||
|     "password_length": "A senha deve ter {count} caracteres.", | ||||
|     "qty_must_greater_than_zero": "A quantidade deve ser maior que zero.", | ||||
|     "price_greater_than_zero": "O preço deve ser maior que zero.", | ||||
|     "payment_greater_than_zero": "O pagamento deve ser maior que zero.", | ||||
|     "payment_greater_than_due_amount": "O pagamento inserido é mais do que o valor devido desta fatura.", | ||||
|     "quantity_maxlength": "A quantidade não deve exceder 20 dígitos.", | ||||
|     "price_maxlength": "O preço não deve ser superior a 20 dígitos.", | ||||
|     "price_minvalue": "O preço deve ser maior que 0.", | ||||
|     "amount_maxlength": "Montante não deve ser superior a 20 dígitos.", | ||||
|     "amount_minvalue": "Montante deve ser maior que zero", | ||||
|     "description_maxlength": "A descrição não deve ter mais que 255 caracteres.", | ||||
|     "maximum_options_error": "Máximo de {max} opções selecionadas. Primeiro remova uma opção selecionada para selecionar outra.", | ||||
|     "notes_maxlength": "As anotações não devem ter mais que 255 caracteres.", | ||||
|     "address_maxlength": "O endereço não deve ter mais que 255 caracteres.", | ||||
|     "ref_number_maxlength": "O número de referência não deve ter mais que 255 caracteres.", | ||||
|     "prefix_maxlength": "O prefixo não deve ter mais que 5 caracteres." | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -21,13 +21,6 @@ export const login = ({ commit, dispatch, state }, data) => { | ||||
|       window.toastr['success']('Login Successful') | ||||
|       resolve(response) | ||||
|     }).catch(err => { | ||||
|       if (err.response.data.error === 'invalid_credentials') { | ||||
|         window.toastr['error']('Invalid Credentials') | ||||
|       } else { | ||||
|         // Something happened in setting up the request that triggered an Error | ||||
|         console.log('Error', err.message) | ||||
|       } | ||||
|  | ||||
|       commit(types.AUTH_ERROR, err.response) | ||||
|       Ls.remove('auth.token') | ||||
|       reject(err) | ||||
|  | ||||
| @ -42,7 +42,6 @@ export default { | ||||
|   }, | ||||
|  | ||||
|   [types.ADD_ITEM_UNIT] (state, data) { | ||||
|     state.itemUnits.push(data.unit) | ||||
|     state.itemUnits = [data.unit, ...state.itemUnits] | ||||
|   }, | ||||
|  | ||||
|  | ||||
| @ -40,7 +40,6 @@ export default { | ||||
|   }, | ||||
|  | ||||
|   [types.ADD_PAYMENT_MODE] (state, data) { | ||||
|     state.paymentModes.push(data.paymentMethod) | ||||
|     state.paymentModes = [data.paymentMethod, ...state.paymentModes] | ||||
|   }, | ||||
|  | ||||
|  | ||||
| @ -46,7 +46,7 @@ | ||||
|       </div> | ||||
|     </div> | ||||
|  | ||||
|     <base-button type="submit" color="theme">{{ $t('login.login') }}</base-button> | ||||
|     <base-button :loading="isLoading" type="submit" color="theme">{{ $t('login.login') }}</base-button> | ||||
|  | ||||
|     <!-- <div class="social-links"> | ||||
|  | ||||
| @ -87,7 +87,8 @@ export default { | ||||
|         password: '', | ||||
|         remember: '' | ||||
|       }, | ||||
|       submitted: false | ||||
|       submitted: false, | ||||
|       isLoading: false | ||||
|     } | ||||
|   }, | ||||
|   validations: { | ||||
| @ -98,7 +99,7 @@ export default { | ||||
|       }, | ||||
|       password: { | ||||
|         required, | ||||
|         minLength: minLength(5) | ||||
|         minLength: minLength(8) | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
| @ -113,7 +114,6 @@ export default { | ||||
|       } | ||||
|  | ||||
|       this.isLoading = true | ||||
|  | ||||
|       this.login(this.loginData).then((res) => { | ||||
|         this.$router.push('/admin/dashboard') | ||||
|         this.isLoading = false | ||||
|  | ||||
| @ -4,16 +4,12 @@ | ||||
|       <h3 class="page-title">{{ $t('estimates.title') }}</h3> | ||||
|       <ol class="breadcrumb"> | ||||
|         <li class="breadcrumb-item"> | ||||
|           <router-link | ||||
|             slot="item-title" | ||||
|             to="dashboard"> | ||||
|           <router-link slot="item-title" to="dashboard"> | ||||
|             {{ $t('general.home') }} | ||||
|           </router-link> | ||||
|         </li> | ||||
|         <li class="breadcrumb-item"> | ||||
|           <router-link | ||||
|             slot="item-title" | ||||
|             to="#"> | ||||
|           <router-link slot="item-title" to="#"> | ||||
|             {{ $tc('estimates.estimate', 2) }} | ||||
|           </router-link> | ||||
|         </li> | ||||
| @ -33,11 +29,9 @@ | ||||
|           </base-button> | ||||
|         </div> | ||||
|         <router-link slot="item-title" class="col-xs-2" to="estimates/create"> | ||||
|           <base-button | ||||
|             size="large" | ||||
|             icon="plus" | ||||
|             color="theme" > | ||||
|             {{ $t('estimates.new_estimate') }}</base-button> | ||||
|           <base-button size="large" icon="plus" color="theme"> | ||||
|             {{ $t('estimates.new_estimate') }}</base-button | ||||
|           > | ||||
|         </router-link> | ||||
|       </div> | ||||
|     </div> | ||||
| @ -46,7 +40,7 @@ | ||||
|       <div v-show="showFilters" class="filter-section"> | ||||
|         <div class="filter-container"> | ||||
|           <div class="filter-customer"> | ||||
|             <label>{{ $tc('customers.customer',1) }} </label> | ||||
|             <label>{{ $tc('customers.customer', 1) }} </label> | ||||
|             <base-customer-select | ||||
|               ref="customerSelect" | ||||
|               @select="onSelectCustomer" | ||||
| @ -85,21 +79,28 @@ | ||||
|           </div> | ||||
|           <div class="filter-estimate"> | ||||
|             <label>{{ $t('estimates.estimate_number') }}</label> | ||||
|             <base-input | ||||
|               v-model="filters.estimate_number" | ||||
|               icon="hashtag"/> | ||||
|             <base-input v-model="filters.estimate_number" icon="hashtag" /> | ||||
|           </div> | ||||
|         </div> | ||||
|         <label class="clear-filter" @click="clearFilter">{{ $t('general.clear_all') }}</label> | ||||
|         <label class="clear-filter" @click="clearFilter">{{ | ||||
|           $t('general.clear_all') | ||||
|         }}</label> | ||||
|       </div> | ||||
|     </transition> | ||||
|     <div v-cloak v-show="showEmptyScreen" class="col-xs-1 no-data-info" align="center"> | ||||
|       <moon-walker-icon class="mt-5 mb-4"/> | ||||
|     <div | ||||
|       v-cloak | ||||
|       v-show="showEmptyScreen" | ||||
|       class="col-xs-1 no-data-info" | ||||
|       align="center" | ||||
|     > | ||||
|       <moon-walker-icon class="mt-5 mb-4" /> | ||||
|       <div class="row" align="center"> | ||||
|         <label class="col title">{{ $t('estimates.no_estimates') }}</label> | ||||
|       </div> | ||||
|       <div class="row"> | ||||
|         <label class="description col mt-1" align="center">{{ $t('estimates.list_of_estimates') }}</label> | ||||
|         <label class="description col mt-1" align="center">{{ | ||||
|           $t('estimates.list_of_estimates') | ||||
|         }}</label> | ||||
|       </div> | ||||
|       <div class="btn-container"> | ||||
|         <base-button | ||||
| @ -116,28 +117,57 @@ | ||||
|  | ||||
|     <div v-show="!showEmptyScreen" class="table-container"> | ||||
|       <div class="table-actions mt-5"> | ||||
|         <p class="table-stats">{{ $t('general.showing') }}: <b>{{ estimates.length }}</b> {{ $t('general.of') }} <b>{{ totalEstimates }}</b></p> | ||||
|         <p class="table-stats"> | ||||
|           {{ $t('general.showing') }}: <b>{{ estimates.length }}</b> | ||||
|           {{ $t('general.of') }} <b>{{ totalEstimates }}</b> | ||||
|         </p> | ||||
|  | ||||
|         <!-- Tabs --> | ||||
|         <ul class="tabs"> | ||||
|           <li class="tab" @click="getStatus('DRAFT')"> | ||||
|             <a :class="['tab-link', {'a-active': filters.status === 'DRAFT'}]" href="#">{{ $t('general.draft') }}</a> | ||||
|             <a | ||||
|               :class="['tab-link', { 'a-active': filters.status === 'DRAFT' }]" | ||||
|               href="#" | ||||
|               >{{ $t('general.draft') }}</a | ||||
|             > | ||||
|           </li> | ||||
|           <li class="tab" @click="getStatus('SENT')"> | ||||
|             <a :class="['tab-link', {'a-active': filters.status === 'SENT'}]" href="#" >{{ $t('general.sent') }}</a> | ||||
|             <a | ||||
|               :class="['tab-link', { 'a-active': filters.status === 'SENT' }]" | ||||
|               href="#" | ||||
|               >{{ $t('general.sent') }}</a | ||||
|             > | ||||
|           </li> | ||||
|           <li class="tab" @click="getStatus('')"> | ||||
|             <a :class="['tab-link', {'a-active': filters.status === '' || filters.status !== 'DRAFT' && filters.status !== 'SENT'}]" href="#">{{ $t('general.all') }}</a> | ||||
|             <a | ||||
|               :class="[ | ||||
|                 'tab-link', | ||||
|                 { | ||||
|                   'a-active': | ||||
|                     filters.status === '' || | ||||
|                     (filters.status !== 'DRAFT' && filters.status !== 'SENT'), | ||||
|                 }, | ||||
|               ]" | ||||
|               href="#" | ||||
|               >{{ $t('general.all') }}</a | ||||
|             > | ||||
|           </li> | ||||
|         </ul> | ||||
|         <transition name="fade"> | ||||
|           <v-dropdown v-if="selectedEstimates.length" :show-arrow="false"> | ||||
|             <span slot="activator" href="#" class="table-actions-button dropdown-toggle"> | ||||
|             <span | ||||
|               slot="activator" | ||||
|               href="#" | ||||
|               class="table-actions-button dropdown-toggle" | ||||
|             > | ||||
|               {{ $t('general.actions') }} | ||||
|             </span> | ||||
|             <v-dropdown-item> | ||||
|               <div class="dropdown-item" @click="removeMultipleEstimates"> | ||||
|                 <font-awesome-icon :icon="['fas', 'trash']" class="dropdown-item-icon" /> | ||||
|                 <font-awesome-icon | ||||
|                   :icon="['fas', 'trash']" | ||||
|                   class="dropdown-item-icon" | ||||
|                 /> | ||||
|                 {{ $t('general.delete') }} | ||||
|               </div> | ||||
|             </v-dropdown-item> | ||||
| @ -153,8 +183,12 @@ | ||||
|           type="checkbox" | ||||
|           class="custom-control-input" | ||||
|           @change="selectAllEstimates" | ||||
|         /> | ||||
|         <label | ||||
|           v-show="!isRequestOngoing" | ||||
|           for="select-all" | ||||
|           class="custom-control-label selectall" | ||||
|         > | ||||
|         <label v-show="!isRequestOngoing" for="select-all" class="custom-control-label selectall"> | ||||
|           <span class="select-all-label">{{ $t('general.select_all') }} </span> | ||||
|         </label> | ||||
|       </div> | ||||
| @ -178,7 +212,7 @@ | ||||
|                 :value="row.id" | ||||
|                 type="checkbox" | ||||
|                 class="custom-control-input" | ||||
|               > | ||||
|               /> | ||||
|               <label :for="row.id" class="custom-control-label" /> | ||||
|             </div> | ||||
|           </template> | ||||
| @ -186,30 +220,30 @@ | ||||
|         <table-column | ||||
|           :label="$t('estimates.date')" | ||||
|           sort-as="estimate_date" | ||||
|           show="formattedEstimateDate" /> | ||||
|           show="formattedEstimateDate" | ||||
|         /> | ||||
|         <table-column | ||||
|           :label="$t('estimates.customer')" | ||||
|           sort-as="name" | ||||
|           show="name" /> | ||||
|           show="name" | ||||
|         /> | ||||
|         <!-- <table-column | ||||
|           :label="$t('estimates.expiry_date')" | ||||
|           sort-as="expiry_date" | ||||
|           show="formattedExpiryDate" /> --> | ||||
|         <table-column | ||||
|           :label="$t('estimates.status')" | ||||
|           show="status" > | ||||
|           <template slot-scope="row" > | ||||
|         <table-column :label="$t('estimates.status')" show="status"> | ||||
|           <template slot-scope="row"> | ||||
|             <span> {{ $t('estimates.status') }}</span> | ||||
|             <span :class="'est-status-'+row.status.toLowerCase()">{{ row.status }}</span> | ||||
|             <span :class="'est-status-' + row.status.toLowerCase()">{{ | ||||
|               row.status | ||||
|             }}</span> | ||||
|           </template> | ||||
|         </table-column> | ||||
|         <table-column | ||||
|           :label="$tc('estimates.estimate', 1)" | ||||
|           show="estimate_number"/> | ||||
|         <table-column | ||||
|           :label="$t('invoices.total')" | ||||
|           sort-as="total" | ||||
|         > | ||||
|           show="estimate_number" | ||||
|         /> | ||||
|         <table-column :label="$t('invoices.total')" sort-as="total"> | ||||
|           <template slot-scope="row"> | ||||
|             <span> {{ $t('estimates.total') }}</span> | ||||
|             <div v-html="$utils.formatMoney(row.total, row.user.currency)" /> | ||||
| @ -227,50 +261,114 @@ | ||||
|                 <dot-icon /> | ||||
|               </a> | ||||
|               <v-dropdown-item> | ||||
|                 <router-link :to="{path: `estimates/${row.id}/edit`}" class="dropdown-item"> | ||||
|                   <font-awesome-icon :icon="['fas', 'pencil-alt']" class="dropdown-item-icon" /> | ||||
|                 <router-link | ||||
|                   :to="{ path: `estimates/${row.id}/edit` }" | ||||
|                   class="dropdown-item" | ||||
|                 > | ||||
|                   <font-awesome-icon | ||||
|                     :icon="['fas', 'pencil-alt']" | ||||
|                     class="dropdown-item-icon" | ||||
|                   /> | ||||
|                   {{ $t('general.edit') }} | ||||
|                 </router-link> | ||||
|               </v-dropdown-item> | ||||
|               <v-dropdown-item> | ||||
|                 <div class="dropdown-item" @click="removeEstimate(row.id)"> | ||||
|                   <font-awesome-icon :icon="['fas', 'trash']" class="dropdown-item-icon" /> | ||||
|                   <font-awesome-icon | ||||
|                     :icon="['fas', 'trash']" | ||||
|                     class="dropdown-item-icon" | ||||
|                   /> | ||||
|                   {{ $t('general.delete') }} | ||||
|                 </div> | ||||
|               </v-dropdown-item> | ||||
|               <v-dropdown-item> | ||||
|                 <router-link :to="{path: `estimates/${row.id}/view`}" class="dropdown-item"> | ||||
|                 <router-link | ||||
|                   :to="{ path: `estimates/${row.id}/view` }" | ||||
|                   class="dropdown-item" | ||||
|                 > | ||||
|                   <font-awesome-icon icon="eye" class="dropdown-item-icon" /> | ||||
|                   {{ $t('general.view') }} | ||||
|                 </router-link> | ||||
|               </v-dropdown-item> | ||||
|               <v-dropdown-item> | ||||
|                 <a class="dropdown-item" href="#/" @click="convertInToinvoice(row.id)"> | ||||
|                   <font-awesome-icon icon="file-alt" class="dropdown-item-icon" /> | ||||
|                 <a | ||||
|                   class="dropdown-item" | ||||
|                   href="#/" | ||||
|                   @click="convertInToinvoice(row.id)" | ||||
|                 > | ||||
|                   <font-awesome-icon | ||||
|                     icon="file-alt" | ||||
|                     class="dropdown-item-icon" | ||||
|                   /> | ||||
|                   {{ $t('estimates.convert_to_invoice') }} | ||||
|                 </a> | ||||
|               </v-dropdown-item> | ||||
|               <v-dropdown-item v-if="row.status !== 'SENT'"> | ||||
|                 <a class="dropdown-item" href="#/" @click.self="onMarkAsSent(row.id)"> | ||||
|                   <font-awesome-icon icon="check-circle" class="dropdown-item-icon" /> | ||||
|                 <a | ||||
|                   class="dropdown-item" | ||||
|                   href="#/" | ||||
|                   @click.self="onMarkAsSent(row.id)" | ||||
|                 > | ||||
|                   <font-awesome-icon | ||||
|                     icon="check-circle" | ||||
|                     class="dropdown-item-icon" | ||||
|                   /> | ||||
|                   {{ $t('estimates.mark_as_sent') }} | ||||
|                 </a> | ||||
|               </v-dropdown-item> | ||||
|               <v-dropdown-item v-if="row.status !== 'SENT'"> | ||||
|                 <a class="dropdown-item" href="#/" @click.self="sendEstimate(row.id)"> | ||||
|                   <font-awesome-icon icon="paper-plane" class="dropdown-item-icon" /> | ||||
|               <v-dropdown-item v-if="row.status === 'DRAFT'"> | ||||
|                 <a | ||||
|                   class="dropdown-item" | ||||
|                   href="#/" | ||||
|                   @click.self="sendEstimate(row.id)" | ||||
|                 > | ||||
|                   <font-awesome-icon | ||||
|                     icon="paper-plane" | ||||
|                     class="dropdown-item-icon" | ||||
|                   /> | ||||
|                   {{ $t('estimates.send_estimate') }} | ||||
|                 </a> | ||||
|               </v-dropdown-item> | ||||
|               <!-- resend estimte --> | ||||
|               <v-dropdown-item | ||||
|                 v-if="row.status == 'SENT' || row.status == 'VIEWED'" | ||||
|               > | ||||
|                 <a | ||||
|                   class="dropdown-item" | ||||
|                   href="#/" | ||||
|                   @click.self="sendEstimate(row.id)" | ||||
|                 > | ||||
|                   <font-awesome-icon | ||||
|                     icon="paper-plane" | ||||
|                     class="dropdown-item-icon" | ||||
|                   /> | ||||
|                   {{ $t('estimates.resend_estimate') }} | ||||
|                 </a> | ||||
|               </v-dropdown-item> | ||||
|               <!--  --> | ||||
|               <v-dropdown-item v-if="row.status !== 'ACCEPTED'"> | ||||
|                 <a class="dropdown-item" href="#/" @click.self="onMarkAsAccepted(row.id)"> | ||||
|                   <font-awesome-icon icon="check-circle" class="dropdown-item-icon" /> | ||||
|                 <a | ||||
|                   class="dropdown-item" | ||||
|                   href="#/" | ||||
|                   @click.self="onMarkAsAccepted(row.id)" | ||||
|                 > | ||||
|                   <font-awesome-icon | ||||
|                     icon="check-circle" | ||||
|                     class="dropdown-item-icon" | ||||
|                   /> | ||||
|                   {{ $t('estimates.mark_as_accepted') }} | ||||
|                 </a> | ||||
|               </v-dropdown-item> | ||||
|               <v-dropdown-item v-if="row.status !== 'REJECTED'"> | ||||
|                 <a class="dropdown-item" href="#/" @click.self="onMarkAsRejected(row.id)"> | ||||
|                   <font-awesome-icon icon="times-circle" class="dropdown-item-icon" /> | ||||
|                 <a | ||||
|                   class="dropdown-item" | ||||
|                   href="#/" | ||||
|                   @click.self="onMarkAsRejected(row.id)" | ||||
|                 > | ||||
|                   <font-awesome-icon | ||||
|                     icon="times-circle" | ||||
|                     class="dropdown-item-icon" | ||||
|                   /> | ||||
|                   {{ $t('estimates.mark_as_rejected') }} | ||||
|                 </a> | ||||
|               </v-dropdown-item> | ||||
|  | ||||
| @ -38,6 +38,8 @@ | ||||
|               <base-input | ||||
|                 v-model="item.quantity" | ||||
|                 :invalid="$v.item.quantity.$error" | ||||
|                 :is-input-group="!!item.unit_name" | ||||
|                 :input-group-text="item.unit_name" | ||||
|                 type="text" | ||||
|                 small | ||||
|                 @keyup="updateItem" | ||||
| @ -378,6 +380,7 @@ export default { | ||||
|       this.item.price = item.price | ||||
|       this.item.item_id = item.id | ||||
|       this.item.description = item.description | ||||
|       this.item.unit_name = item.unit_name | ||||
|       if (this.taxPerItem === 'YES' && item.taxes) { | ||||
|         let index = 0 | ||||
|         item.taxes.forEach(tax => { | ||||
|  | ||||
| @ -12,6 +12,7 @@ | ||||
|       ref="baseSelect" | ||||
|       v-model="itemSelect" | ||||
|       :options="items" | ||||
|       :loading="loading" | ||||
|       :show-labels="false" | ||||
|       :preserve-search="true" | ||||
|       :initial-search="item.name" | ||||
| @ -20,7 +21,7 @@ | ||||
|       label="name" | ||||
|       class="multi-select-item" | ||||
|       @value="onTextChange" | ||||
|       @select="(val) => $emit('select', val)" | ||||
|       @select="onSelect" | ||||
|     > | ||||
|       <div slot="afterList"> | ||||
|         <button type="button" class="list-add-button" @click="openItemModal"> | ||||
| @ -112,6 +113,7 @@ export default { | ||||
|     ]), | ||||
|     async searchItems (search) { | ||||
|       let data = { | ||||
|         search, | ||||
|         filter: { | ||||
|           name: search, | ||||
|           unit: '', | ||||
| @ -136,11 +138,15 @@ export default { | ||||
|     openItemModal () { | ||||
|       this.$emit('onSelectItem') | ||||
|       this.openModal({ | ||||
|         'title': 'Add Item', | ||||
|         'title': this.$t('items.add_item'), | ||||
|         'componentName': 'ItemModal', | ||||
|         'data': {taxPerItem: this.taxPerItem, taxes: this.taxes} | ||||
|       }) | ||||
|     }, | ||||
|     onSelect(val) { | ||||
|       this.$emit('select', val) | ||||
|       this.fetchItems() | ||||
|     },     | ||||
|     deselectItem () { | ||||
|       this.itemSelect = null | ||||
|       this.$emit('deselect') | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| <template> | ||||
|   <div v-if="estimate" class="main-content estimate-view-page"> | ||||
|     <div class="page-header"> | ||||
|       <h3 class="page-title"> {{ estimate.estimate_number }}</h3> | ||||
|       <h3 class="page-title">{{ estimate.estimate_number }}</h3> | ||||
|       <div class="page-actions row"> | ||||
|         <div class="col-xs-2 mr-3"> | ||||
|           <base-button | ||||
| @ -26,19 +26,42 @@ | ||||
|             {{ $t('estimates.send_estimate') }} | ||||
|           </base-button> | ||||
|         </div> | ||||
|         <v-dropdown :close-on-select="false" align="left" class="filter-container"> | ||||
|         <v-dropdown | ||||
|           :close-on-select="true" | ||||
|           align="left" | ||||
|           class="filter-container" | ||||
|         > | ||||
|           <a slot="activator" href="#"> | ||||
|             <base-button color="theme"> | ||||
|               <font-awesome-icon icon="ellipsis-h" /> | ||||
|             </base-button> | ||||
|           </a> | ||||
|           <v-dropdown-item> | ||||
|             <router-link :to="{path: `/admin/estimates/${$route.params.id}/edit`}" class="dropdown-item"> | ||||
|               <font-awesome-icon :icon="['fas', 'pencil-alt']" class="dropdown-item-icon"/> | ||||
|             <div class="dropdown-item" @click="copyPdfUrl()"> | ||||
|               <font-awesome-icon | ||||
|                 :icon="['fas', 'link']" | ||||
|                 class="dropdown-item-icon" | ||||
|               /> | ||||
|               {{ $t('general.copy_pdf_url') }} | ||||
|             </div> | ||||
|             <router-link | ||||
|               :to="{ path: `/admin/estimates/${$route.params.id}/edit` }" | ||||
|               class="dropdown-item" | ||||
|             > | ||||
|               <font-awesome-icon | ||||
|                 :icon="['fas', 'pencil-alt']" | ||||
|                 class="dropdown-item-icon" | ||||
|               /> | ||||
|               {{ $t('general.edit') }} | ||||
|             </router-link> | ||||
|             <div class="dropdown-item" @click="removeEstimate($route.params.id)"> | ||||
|               <font-awesome-icon :icon="['fas', 'trash']" class="dropdown-item-icon" /> | ||||
|             <div | ||||
|               class="dropdown-item" | ||||
|               @click="removeEstimate($route.params.id)" | ||||
|             > | ||||
|               <font-awesome-icon | ||||
|                 :icon="['fas', 'trash']" | ||||
|                 class="dropdown-item-icon" | ||||
|               /> | ||||
|               {{ $t('general.delete') }} | ||||
|             </div> | ||||
|           </v-dropdown-item> | ||||
| @ -57,14 +80,18 @@ | ||||
|           align-icon="right" | ||||
|           @input="onSearched()" | ||||
|         /> | ||||
|         <div | ||||
|           class="btn-group ml-3" | ||||
|           role="group" | ||||
|           aria-label="First group" | ||||
|         > | ||||
|           <v-dropdown :close-on-select="false" align="left" class="filter-container"> | ||||
|         <div class="btn-group ml-3" role="group" aria-label="First group"> | ||||
|           <v-dropdown | ||||
|             :close-on-select="false" | ||||
|             align="left" | ||||
|             class="filter-container" | ||||
|           > | ||||
|             <a slot="activator" href="#"> | ||||
|               <base-button class="inv-button inv-filter-fields-btn" color="default" size="medium"> | ||||
|               <base-button | ||||
|                 class="inv-button inv-filter-fields-btn" | ||||
|                 color="default" | ||||
|                 size="medium" | ||||
|               > | ||||
|                 <font-awesome-icon icon="filter" /> | ||||
|               </base-button> | ||||
|             </a> | ||||
| @ -80,8 +107,10 @@ | ||||
|                 class="inv-radio" | ||||
|                 value="estimate_date" | ||||
|                 @change="onSearched" | ||||
|               > | ||||
|               <label class="inv-label" for="filter_estimate_date">{{ $t('reports.estimates.estimate_date') }}</label> | ||||
|               /> | ||||
|               <label class="inv-label" for="filter_estimate_date">{{ | ||||
|                 $t('reports.estimates.estimate_date') | ||||
|               }}</label> | ||||
|             </div> | ||||
|             <div class="filter-items"> | ||||
|               <input | ||||
| @ -92,8 +121,10 @@ | ||||
|                 class="inv-radio" | ||||
|                 value="expiry_date" | ||||
|                 @change="onSearched" | ||||
|               > | ||||
|               <label class="inv-label" for="filter_due_date">{{ $t('estimates.due_date') }}</label> | ||||
|               /> | ||||
|               <label class="inv-label" for="filter_due_date">{{ | ||||
|                 $t('estimates.due_date') | ||||
|               }}</label> | ||||
|             </div> | ||||
|             <div class="filter-items"> | ||||
|               <input | ||||
| @ -104,11 +135,19 @@ | ||||
|                 class="inv-radio" | ||||
|                 value="estimate_number" | ||||
|                 @change="onSearched" | ||||
|               > | ||||
|               <label class="inv-label" for="filter_estimate_number">{{ $t('estimates.estimate_number') }}</label> | ||||
|               /> | ||||
|               <label class="inv-label" for="filter_estimate_number">{{ | ||||
|                 $t('estimates.estimate_number') | ||||
|               }}</label> | ||||
|             </div> | ||||
|           </v-dropdown> | ||||
|           <base-button v-tooltip.top-center="{ content: getOrderName }" class="inv-button inv-filter-sorting-btn" color="default" size="medium" @click="sortData"> | ||||
|           <base-button | ||||
|             v-tooltip.top-center="{ content: getOrderName }" | ||||
|             class="inv-button inv-filter-sorting-btn" | ||||
|             color="default" | ||||
|             size="medium" | ||||
|             @click="sortData" | ||||
|           > | ||||
|             <font-awesome-icon v-if="getOrderBy" icon="sort-amount-up" /> | ||||
|             <font-awesome-icon v-else icon="sort-amount-down" /> | ||||
|           </base-button> | ||||
| @ -116,7 +155,7 @@ | ||||
|       </div> | ||||
|       <div class="side-content"> | ||||
|         <router-link | ||||
|           v-for="(estimate,index) in estimates" | ||||
|           v-for="(estimate, index) in estimates" | ||||
|           :to="`/admin/estimates/${estimate.id}/view`" | ||||
|           :key="index" | ||||
|           class="side-estimate" | ||||
| @ -124,10 +163,20 @@ | ||||
|           <div class="left"> | ||||
|             <div class="inv-name">{{ estimate.user.name }}</div> | ||||
|             <div class="inv-number">{{ estimate.estimate_number }}</div> | ||||
|             <div :class="'est-status-'+estimate.status.toLowerCase()" class="inv-status">{{ estimate.status }}</div> | ||||
|             <div | ||||
|               :class="'est-status-' + estimate.status.toLowerCase()" | ||||
|               class="inv-status" | ||||
|             > | ||||
|               {{ estimate.status }} | ||||
|             </div> | ||||
|           </div> | ||||
|           <div class="right"> | ||||
|             <div class="inv-amount" v-html="$utils.formatMoney(estimate.total, estimate.user.currency)" /> | ||||
|             <div | ||||
|               class="inv-amount" | ||||
|               v-html=" | ||||
|                 $utils.formatMoney(estimate.total, estimate.user.currency) | ||||
|               " | ||||
|             /> | ||||
|             <div class="inv-date">{{ estimate.formattedEstimateDate }}</div> | ||||
|           </div> | ||||
|         </router-link> | ||||
| @ -137,7 +186,7 @@ | ||||
|       </div> | ||||
|     </div> | ||||
|     <div class="estimate-view-page-container"> | ||||
|       <iframe :src="`${shareableLink}`" class="frame-style"/> | ||||
|       <iframe :src="`${shareableLink}`" class="frame-style" /> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
| @ -289,6 +338,13 @@ export default { | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     copyPdfUrl () { | ||||
|       let pdfUrl = `${window.location.origin}/estimates/pdf/${this.estimate.unique_hash}` | ||||
|  | ||||
|       let response = this.$utils.copyTextToClipboard(pdfUrl) | ||||
|  | ||||
|       window.toastr['success'](this.$tc('Copied PDF url to clipboard!')) | ||||
|     }, | ||||
|     async removeEstimate (id) { | ||||
|       window.swal({ | ||||
|         title: 'Deleted', | ||||
|  | ||||
| @ -102,6 +102,19 @@ | ||||
|                     <span v-if="!$v.formData.amount.minValue" class="text-danger">{{ $t('validation.price_minvalue') }}</span> | ||||
|                   </div> | ||||
|                 </div> | ||||
|                 <div class="form-group col-sm-6"> | ||||
|                   <label class="form-label">{{ $t('expenses.customer') }}</label> | ||||
|                   <base-select | ||||
|                     ref="baseSelect" | ||||
|                     v-model="customer" | ||||
|                     :options="customerList" | ||||
|                     :searchable="true" | ||||
|                     :show-labels="false" | ||||
|                     :placeholder="$t('customers.select_a_customer')" | ||||
|                     label="name" | ||||
|                     track-by="id" | ||||
|                   /> | ||||
|                 </div> | ||||
|                 <div class="form-group col-sm-6"> | ||||
|                   <label for="description">{{ $t('expenses.note') }}</label> | ||||
|                   <base-text-area | ||||
| @ -169,7 +182,8 @@ export default { | ||||
|         expense_category_id: null, | ||||
|         expense_date: new Date(), | ||||
|         amount: null, | ||||
|         notes: '' | ||||
|         notes: '', | ||||
|         user_id: null | ||||
|       }, | ||||
|       money: { | ||||
|         decimal: '.', | ||||
| @ -185,7 +199,9 @@ export default { | ||||
|       passData: [], | ||||
|       contacts: [], | ||||
|       previewReceipt: null, | ||||
|       fileSendUrl: '/api/expenses' | ||||
|       fileSendUrl: '/api/expenses', | ||||
|       customer: null, | ||||
|       customerList: [] | ||||
|     } | ||||
|   }, | ||||
|   validations: { | ||||
| @ -297,6 +313,8 @@ export default { | ||||
|     }, | ||||
|     async fetchInitialData () { | ||||
|       this.fetchCategories() | ||||
|       let fetchData = await this.fetchCreateExpense() | ||||
|       this.customerList = fetchData.data.customers | ||||
|       if (this.isEdit) { | ||||
|         let response = await this.fetchExpense(this.$route.params.id) | ||||
|         this.category = response.data.expense.category | ||||
| @ -304,6 +322,9 @@ export default { | ||||
|         this.formData.expense_date = moment(this.formData.expense_date).toString() | ||||
|         this.formData.amount = (response.data.expense.amount) | ||||
|         this.fileSendUrl = `/api/expenses/${this.$route.params.id}` | ||||
|         if (response.data.expense.user_id) { | ||||
|           this.customer = this.customerList.find(customer => customer.id === response.data.expense.user_id) | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     async sendData () { | ||||
| @ -319,9 +340,10 @@ export default { | ||||
|         data.append('attachment_receipt', this.file) | ||||
|       } | ||||
|       data.append('expense_category_id', this.formData.expense_category_id) | ||||
|       data.append('expense_date',  moment(this.formData.expense_date).format('DD/MM/YYYY')) | ||||
|       data.append('expense_date', moment(this.formData.expense_date).format('DD/MM/YYYY')) | ||||
|       data.append('amount', (this.formData.amount)) | ||||
|       data.append('notes', this.formData.notes) | ||||
|       data.append('notes', this.formData.notes ? this.formData.notes : '') | ||||
|       data.append('user_id', this.customer ? this.customer.id : '') | ||||
|  | ||||
|       if (this.isEdit) { | ||||
|         this.isLoading = true | ||||
|  | ||||
| @ -43,7 +43,19 @@ | ||||
|     <transition name="fade"> | ||||
|       <div v-show="showFilters" class="filter-section"> | ||||
|         <div class="row"> | ||||
|           <div class="col-md-4"> | ||||
|           <div class="col-md-3"> | ||||
|             <label>{{ $t('expenses.customer') }}</label> | ||||
|             <base-select | ||||
|               v-model="filters.user" | ||||
|               :options="customers" | ||||
|               :searchable="true" | ||||
|               :show-labels="false" | ||||
|               :placeholder="$t('expenses.select_a_customer')" | ||||
|               label="name" | ||||
|               @click="filter = ! filter" | ||||
|             /> | ||||
|           </div> | ||||
|           <div class="col-md-3"> | ||||
|             <label>{{ $t('expenses.category') }}</label> | ||||
|             <base-select | ||||
|               v-model="filters.category" | ||||
| @ -55,7 +67,7 @@ | ||||
|               @click="filter = ! filter" | ||||
|             /> | ||||
|           </div> | ||||
|           <div class="col-md-4"> | ||||
|           <div class="col-md-3"> | ||||
|             <label>{{ $t('expenses.from_date') }}</label> | ||||
|             <base-date-picker | ||||
|               v-model="filters.from_date" | ||||
| @ -63,7 +75,7 @@ | ||||
|               calendar-button-icon="calendar" | ||||
|             /> | ||||
|           </div> | ||||
|           <div class="col-md-4"> | ||||
|           <div class="col-md-3"> | ||||
|             <label>{{ $t('expenses.to_date') }}</label> | ||||
|             <base-date-picker | ||||
|               v-model="filters.to_date" | ||||
| @ -161,6 +173,11 @@ | ||||
|           sort-as="name" | ||||
|           show="category.name" | ||||
|         /> | ||||
|         <table-column | ||||
|           :label="$t('expenses.customer')" | ||||
|           sort-as="user_name" | ||||
|           show="user_name" | ||||
|         /> | ||||
|         <table-column | ||||
|           :label="$t('expenses.date')" | ||||
|           sort-as="expense_date" | ||||
| @ -237,10 +254,12 @@ export default { | ||||
|       showFilters: false, | ||||
|       filtersApplied: false, | ||||
|       isRequestOngoing: true, | ||||
|       customers: [], | ||||
|       filters: { | ||||
|         category: null, | ||||
|         from_date: '', | ||||
|         to_date: '' | ||||
|         to_date: '', | ||||
|         user: '' | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
| @ -308,6 +327,7 @@ export default { | ||||
|     ]), | ||||
|     async fetchData ({ page, filter, sort }) { | ||||
|       let data = { | ||||
|         user_id: this.filters.user ? this.filters.user.id : null, | ||||
|         expense_category_id: this.filters.category !== null ? this.filters.category.id : '', | ||||
|         from_date: this.filters.from_date === '' ? this.filters.from_date : moment(this.filters.from_date).format('DD/MM/YYYY'), | ||||
|         to_date: this.filters.to_date === '' ? this.filters.to_date : moment(this.filters.to_date).format('DD/MM/YYYY'), | ||||
| @ -318,6 +338,7 @@ export default { | ||||
|  | ||||
|       this.isRequestOngoing = true | ||||
|       let response = await this.fetchExpenses(data) | ||||
|       this.customers = response.data.customers | ||||
|       this.isRequestOngoing = false | ||||
|  | ||||
|       return { | ||||
| @ -340,7 +361,8 @@ export default { | ||||
|       this.filters = { | ||||
|         category: null, | ||||
|         from_date: '', | ||||
|         to_date: '' | ||||
|         to_date: '', | ||||
|         user: null | ||||
|       } | ||||
|  | ||||
|       this.$nextTick(() => { | ||||
|  | ||||
| @ -1,19 +1,15 @@ | ||||
| <template> | ||||
|   <div class="invoice-index-page invoices main-content"> | ||||
|     <div class="page-header"> | ||||
|       <h3 class="page-title"> {{ $t('invoices.title') }}</h3> | ||||
|       <h3 class="page-title">{{ $t('invoices.title') }}</h3> | ||||
|       <ol class="breadcrumb"> | ||||
|         <li class="breadcrumb-item"> | ||||
|           <router-link | ||||
|             slot="item-title" | ||||
|             to="dashboard"> | ||||
|           <router-link slot="item-title" to="dashboard"> | ||||
|             {{ $t('general.home') }} | ||||
|           </router-link> | ||||
|         </li> | ||||
|         <li class="breadcrumb-item"> | ||||
|           <router-link | ||||
|             slot="item-title" | ||||
|             to="#"> | ||||
|           <router-link slot="item-title" to="#"> | ||||
|             {{ $tc('invoices.invoice', 2) }} | ||||
|           </router-link> | ||||
|         </li> | ||||
| @ -32,7 +28,11 @@ | ||||
|             {{ $t('general.filter') }} | ||||
|           </base-button> | ||||
|         </div> | ||||
|         <router-link slot="item-title" class="col-xs-2" to="/admin/invoices/create"> | ||||
|         <router-link | ||||
|           slot="item-title" | ||||
|           class="col-xs-2" | ||||
|           to="/admin/invoices/create" | ||||
|         > | ||||
|           <base-button size="large" icon="plus" color="theme"> | ||||
|             {{ $t('invoices.new_invoice') }} | ||||
|           </base-button> | ||||
| @ -44,7 +44,7 @@ | ||||
|       <div v-show="showFilters" class="filter-section"> | ||||
|         <div class="filter-container"> | ||||
|           <div class="filter-customer"> | ||||
|             <label>{{ $tc('customers.customer',1) }} </label> | ||||
|             <label>{{ $tc('customers.customer', 1) }} </label> | ||||
|             <base-customer-select | ||||
|               ref="customerSelect" | ||||
|               @select="onSelectCustomer" | ||||
| @ -88,22 +88,29 @@ | ||||
|           </div> | ||||
|           <div class="filter-invoice"> | ||||
|             <label>{{ $t('invoices.invoice_number') }}</label> | ||||
|             <base-input | ||||
|               v-model="filters.invoice_number" | ||||
|               icon="hashtag"/> | ||||
|             <base-input v-model="filters.invoice_number" icon="hashtag" /> | ||||
|           </div> | ||||
|         </div> | ||||
|         <label class="clear-filter" @click="clearFilter">{{ $t('general.clear_all') }}</label> | ||||
|         <label class="clear-filter" @click="clearFilter">{{ | ||||
|           $t('general.clear_all') | ||||
|         }}</label> | ||||
|       </div> | ||||
|     </transition> | ||||
|  | ||||
|     <div v-cloak v-show="showEmptyScreen" class="col-xs-1 no-data-info" align="center"> | ||||
|       <moon-walker-icon class="mt-5 mb-4"/> | ||||
|     <div | ||||
|       v-cloak | ||||
|       v-show="showEmptyScreen" | ||||
|       class="col-xs-1 no-data-info" | ||||
|       align="center" | ||||
|     > | ||||
|       <moon-walker-icon class="mt-5 mb-4" /> | ||||
|       <div class="row" align="center"> | ||||
|         <label class="col title">{{ $t('invoices.no_invoices') }}</label> | ||||
|       </div> | ||||
|       <div class="row"> | ||||
|         <label class="description col mt-1" align="center">{{ $t('invoices.list_of_invoices') }}</label> | ||||
|         <label class="description col mt-1" align="center">{{ | ||||
|           $t('invoices.list_of_invoices') | ||||
|         }}</label> | ||||
|       </div> | ||||
|       <div class="btn-container"> | ||||
|         <base-button | ||||
| @ -120,28 +127,65 @@ | ||||
|  | ||||
|     <div v-show="!showEmptyScreen" class="table-container"> | ||||
|       <div class="table-actions mt-5"> | ||||
|         <p class="table-stats">{{ $t('general.showing') }}: <b>{{ invoices.length }}</b> {{ $t('general.of') }} <b>{{ totalInvoices }}</b></p> | ||||
|         <p class="table-stats"> | ||||
|           {{ $t('general.showing') }}: <b>{{ invoices.length }}</b> | ||||
|           {{ $t('general.of') }} <b>{{ totalInvoices }}</b> | ||||
|         </p> | ||||
|  | ||||
|         <!-- Tabs --> | ||||
|         <ul class="tabs"> | ||||
|           <li class="tab" @click="getStatus('UNPAID')"> | ||||
|             <a :class="['tab-link', {'a-active': filters.status.value === 'UNPAID'}]" href="#" >{{ $t('general.due') }}</a> | ||||
|             <a | ||||
|               :class="[ | ||||
|                 'tab-link', | ||||
|                 { 'a-active': filters.status.value === 'UNPAID' }, | ||||
|               ]" | ||||
|               href="#" | ||||
|               >{{ $t('general.due') }}</a | ||||
|             > | ||||
|           </li> | ||||
|           <li class="tab" @click="getStatus('DRAFT')"> | ||||
|             <a :class="['tab-link', {'a-active': filters.status.value === 'DRAFT'}]" href="#">{{ $t('general.draft') }}</a> | ||||
|             <a | ||||
|               :class="[ | ||||
|                 'tab-link', | ||||
|                 { 'a-active': filters.status.value === 'DRAFT' }, | ||||
|               ]" | ||||
|               href="#" | ||||
|               >{{ $t('general.draft') }}</a | ||||
|             > | ||||
|           </li> | ||||
|           <li class="tab" @click="getStatus('')"> | ||||
|             <a :class="['tab-link', {'a-active': filters.status.value === '' || filters.status.value === null || filters.status.value !== 'DRAFT' && filters.status.value !== 'UNPAID'}]" href="#">{{ $t('general.all') }}</a> | ||||
|             <a | ||||
|               :class="[ | ||||
|                 'tab-link', | ||||
|                 { | ||||
|                   'a-active': | ||||
|                     filters.status.value === '' || | ||||
|                     filters.status.value === null || | ||||
|                     (filters.status.value !== 'DRAFT' && | ||||
|                       filters.status.value !== 'UNPAID'), | ||||
|                 }, | ||||
|               ]" | ||||
|               href="#" | ||||
|               >{{ $t('general.all') }}</a | ||||
|             > | ||||
|           </li> | ||||
|         </ul> | ||||
|         <transition name="fade"> | ||||
|           <v-dropdown v-if="selectedInvoices.length" :show-arrow="false"> | ||||
|             <span slot="activator" href="#" class="table-actions-button dropdown-toggle"> | ||||
|             <span | ||||
|               slot="activator" | ||||
|               href="#" | ||||
|               class="table-actions-button dropdown-toggle" | ||||
|             > | ||||
|               {{ $t('general.actions') }} | ||||
|             </span> | ||||
|             <v-dropdown-item> | ||||
|               <div class="dropdown-item" @click="removeMultipleInvoices"> | ||||
|                 <font-awesome-icon :icon="['fas', 'trash']" class="dropdown-item-icon" /> | ||||
|                 <font-awesome-icon | ||||
|                   :icon="['fas', 'trash']" | ||||
|                   class="dropdown-item-icon" | ||||
|                 /> | ||||
|                 {{ $t('general.delete') }} | ||||
|               </div> | ||||
|             </v-dropdown-item> | ||||
| @ -155,8 +199,12 @@ | ||||
|           type="checkbox" | ||||
|           class="custom-control-input" | ||||
|           @change="selectAllInvoices" | ||||
|         /> | ||||
|         <label | ||||
|           v-show="!isRequestOngoing" | ||||
|           for="select-all" | ||||
|           class="custom-control-label selectall" | ||||
|         > | ||||
|         <label v-show="!isRequestOngoing" for="select-all" class="custom-control-label selectall"> | ||||
|           <span class="select-all-label">{{ $t('general.select_all') }} </span> | ||||
|         </label> | ||||
|       </div> | ||||
| @ -180,8 +228,8 @@ | ||||
|                 :value="row.id" | ||||
|                 type="checkbox" | ||||
|                 class="custom-control-input" | ||||
|               > | ||||
|               <label :for="row.id" class="custom-control-label"/> | ||||
|               /> | ||||
|               <label :for="row.id" class="custom-control-label" /> | ||||
|             </div> | ||||
|           </template> | ||||
|         </table-column> | ||||
| @ -195,35 +243,33 @@ | ||||
|           width="20%" | ||||
|           show="name" | ||||
|         /> | ||||
|         <table-column | ||||
|           :label="$t('invoices.status')" | ||||
|           sort-as="status" | ||||
|         > | ||||
|           <template slot-scope="row" > | ||||
|         <table-column :label="$t('invoices.status')" sort-as="status"> | ||||
|           <template slot-scope="row"> | ||||
|             <span> {{ $t('invoices.status') }}</span> | ||||
|             <span :class="'inv-status-'+row.status.toLowerCase()">{{ (row.status != 'PARTIALLY_PAID')? row.status : row.status.replace('_', ' ') }}</span> | ||||
|             <span :class="'inv-status-' + row.status.toLowerCase()">{{ | ||||
|               row.status != 'PARTIALLY_PAID' | ||||
|                 ? row.status | ||||
|                 : row.status.replace('_', ' ') | ||||
|             }}</span> | ||||
|           </template> | ||||
|         </table-column> | ||||
|         <table-column | ||||
|           :label="$t('invoices.paid_status')" | ||||
|           sort-as="paid_status" | ||||
|         > | ||||
|         <table-column :label="$t('invoices.paid_status')" sort-as="paid_status"> | ||||
|           <template slot-scope="row"> | ||||
|             <span>{{ $t('invoices.paid_status') }}</span> | ||||
|             <span :class="'inv-status-'+row.paid_status.toLowerCase()">{{ (row.paid_status != 'PARTIALLY_PAID')? row.paid_status : row.paid_status.replace('_', ' ') }}</span> | ||||
|             <span :class="'inv-status-' + row.paid_status.toLowerCase()">{{ | ||||
|               row.paid_status != 'PARTIALLY_PAID' | ||||
|                 ? row.paid_status | ||||
|                 : row.paid_status.replace('_', ' ') | ||||
|             }}</span> | ||||
|           </template> | ||||
|         </table-column> | ||||
|         <table-column | ||||
|           :label="$t('invoices.number')" | ||||
|           show="invoice_number" | ||||
|         /> | ||||
|         <table-column | ||||
|           :label="$t('invoices.amount_due')" | ||||
|           sort-as="due_amount" | ||||
|         > | ||||
|         <table-column :label="$t('invoices.number')" show="invoice_number" /> | ||||
|         <table-column :label="$t('invoices.amount_due')" sort-as="due_amount"> | ||||
|           <template slot-scope="row"> | ||||
|             <span>{{ $t('invoices.amount_due') }}</span> | ||||
|             <div v-html="$utils.formatMoney(row.due_amount, row.user.currency)"/> | ||||
|             <div | ||||
|               v-html="$utils.formatMoney(row.due_amount, row.user.currency)" | ||||
|             /> | ||||
|           </template> | ||||
|         </table-column> | ||||
|         <table-column | ||||
| @ -238,42 +284,91 @@ | ||||
|                 <dot-icon /> | ||||
|               </a> | ||||
|               <v-dropdown-item> | ||||
|                 <router-link :to="{path: `invoices/${row.id}/edit`}" class="dropdown-item"> | ||||
|                   <font-awesome-icon :icon="['fas', 'pencil-alt']" class="dropdown-item-icon"/> | ||||
|                 <router-link | ||||
|                   :to="{ path: `invoices/${row.id}/edit` }" | ||||
|                   class="dropdown-item" | ||||
|                 > | ||||
|                   <font-awesome-icon | ||||
|                     :icon="['fas', 'pencil-alt']" | ||||
|                     class="dropdown-item-icon" | ||||
|                   /> | ||||
|                   {{ $t('general.edit') }} | ||||
|                 </router-link> | ||||
|                 <router-link :to="{path: `invoices/${row.id}/view`}" class="dropdown-item"> | ||||
|                 <router-link | ||||
|                   :to="{ path: `invoices/${row.id}/view` }" | ||||
|                   class="dropdown-item" | ||||
|                 > | ||||
|                   <font-awesome-icon icon="eye" class="dropdown-item-icon" /> | ||||
|                   {{ $t('invoices.view') }} | ||||
|                 </router-link> | ||||
|               </v-dropdown-item> | ||||
|               <v-dropdown-item v-if="row.status == 'DRAFT'"> | ||||
|                 <a class="dropdown-item" href="#/" @click="sendInvoice(row.id)" > | ||||
|                   <font-awesome-icon icon="paper-plane" class="dropdown-item-icon" /> | ||||
|                 <a class="dropdown-item" href="#/" @click="sendInvoice(row.id)"> | ||||
|                   <font-awesome-icon | ||||
|                     icon="paper-plane" | ||||
|                     class="dropdown-item-icon" | ||||
|                   /> | ||||
|                   {{ $t('invoices.send_invoice') }} | ||||
|                 </a> | ||||
|               </v-dropdown-item> | ||||
|               <v-dropdown-item | ||||
|                 v-if="row.status === 'SENT' || row.status === 'VIEWED'" | ||||
|               > | ||||
|                 <a class="dropdown-item" href="#/" @click="sendInvoice(row.id)"> | ||||
|                   <font-awesome-icon | ||||
|                     icon="paper-plane" | ||||
|                     class="dropdown-item-icon" | ||||
|                   /> | ||||
|                   {{ $t('invoices.resend_invoice') }} | ||||
|                 </a> | ||||
|               </v-dropdown-item> | ||||
|               <v-dropdown-item v-if="row.status == 'DRAFT'"> | ||||
|                 <a class="dropdown-item" href="#/" @click="markInvoiceAsSent(row.id)"> | ||||
|                   <font-awesome-icon icon="check-circle" class="dropdown-item-icon" /> | ||||
|                 <a | ||||
|                   class="dropdown-item" | ||||
|                   href="#/" | ||||
|                   @click="markInvoiceAsSent(row.id)" | ||||
|                 > | ||||
|                   <font-awesome-icon | ||||
|                     icon="check-circle" | ||||
|                     class="dropdown-item-icon" | ||||
|                   /> | ||||
|                   {{ $t('invoices.mark_as_sent') }} | ||||
|                 </a> | ||||
|               </v-dropdown-item> | ||||
|               <v-dropdown-item v-if="row.status === 'SENT' || row.status === 'VIEWED' || row.status === 'OVERDUE'"> | ||||
|                 <router-link :to="`/admin/payments/${row.id}/create`" class="dropdown-item"> | ||||
|                   <font-awesome-icon :icon="['fas', 'credit-card']" class="dropdown-item-icon"/> | ||||
|               <v-dropdown-item | ||||
|                 v-if=" | ||||
|                   row.status === 'SENT' || | ||||
|                   row.status === 'VIEWED' || | ||||
|                   row.status === 'OVERDUE' | ||||
|                 " | ||||
|               > | ||||
|                 <router-link | ||||
|                   :to="`/admin/payments/${row.id}/create`" | ||||
|                   class="dropdown-item" | ||||
|                 > | ||||
|                   <font-awesome-icon | ||||
|                     :icon="['fas', 'credit-card']" | ||||
|                     class="dropdown-item-icon" | ||||
|                   /> | ||||
|                   {{ $t('payments.record_payment') }} | ||||
|                 </router-link> | ||||
|               </v-dropdown-item> | ||||
|               <v-dropdown-item> | ||||
|                 <a class="dropdown-item" href="#/" @click="onCloneInvoice(row.id)"> | ||||
|                 <a | ||||
|                   class="dropdown-item" | ||||
|                   href="#/" | ||||
|                   @click="onCloneInvoice(row.id)" | ||||
|                 > | ||||
|                   <font-awesome-icon icon="copy" class="dropdown-item-icon" /> | ||||
|                   {{ $t('invoices.clone_invoice') }} | ||||
|                 </a> | ||||
|               </v-dropdown-item> | ||||
|               <v-dropdown-item> | ||||
|                 <div class="dropdown-item" @click="removeInvoice(row.id)"> | ||||
|                   <font-awesome-icon :icon="['fas', 'trash']" class="dropdown-item-icon" /> | ||||
|                   <font-awesome-icon | ||||
|                     :icon="['fas', 'trash']" | ||||
|                     class="dropdown-item-icon" | ||||
|                   /> | ||||
|                   {{ $t('general.delete') }} | ||||
|                 </div> | ||||
|               </v-dropdown-item> | ||||
|  | ||||
| @ -38,6 +38,8 @@ | ||||
|               <base-input | ||||
|                 v-model="item.quantity" | ||||
|                 :invalid="$v.item.quantity.$error" | ||||
|                 :is-input-group="!!item.unit_name" | ||||
|                 :input-group-text="item.unit_name" | ||||
|                 type="text" | ||||
|                 small | ||||
|                 @keyup="updateItem" | ||||
| @ -379,6 +381,7 @@ export default { | ||||
|       this.item.price = item.price | ||||
|       this.item.item_id = item.id | ||||
|       this.item.description = item.description | ||||
|       this.item.unit_name = item.unit_name | ||||
|       if (this.taxPerItem === 'YES' && item.taxes) { | ||||
|         let index = 0 | ||||
|         item.taxes.forEach(tax => { | ||||
|  | ||||
| @ -12,6 +12,7 @@ | ||||
|       ref="baseSelect" | ||||
|       v-model="itemSelect" | ||||
|       :options="items" | ||||
|       :loading="loading" | ||||
|       :show-labels="false" | ||||
|       :preserve-search="true" | ||||
|       :initial-search="item.name" | ||||
| @ -20,7 +21,7 @@ | ||||
|       label="name" | ||||
|       class="multi-select-item" | ||||
|       @value="onTextChange" | ||||
|       @select="(val) => $emit('select', val)" | ||||
|       @select="onSelect" | ||||
|     > | ||||
|       <div slot="afterList"> | ||||
|         <button type="button" class="list-add-button" @click="openItemModal"> | ||||
| @ -101,6 +102,7 @@ export default { | ||||
|     ]), | ||||
|     async searchItems (search) { | ||||
|       let data = { | ||||
|         search, | ||||
|         filter: { | ||||
|           name: search, | ||||
|           unit: '', | ||||
| @ -125,11 +127,15 @@ export default { | ||||
|     openItemModal () { | ||||
|       this.$emit('onSelectItem') | ||||
|       this.openModal({ | ||||
|         'title': 'Add Item', | ||||
|         'title': this.$t('items.add_item'), | ||||
|         'componentName': 'ItemModal', | ||||
|         'data': {taxPerItem: this.taxPerItem, taxes: this.taxes} | ||||
|       }) | ||||
|     }, | ||||
|     onSelect(val) { | ||||
|       this.$emit('select', val) | ||||
|       this.fetchItems() | ||||
|     }, | ||||
|     deselectItem () { | ||||
|       this.itemSelect = null | ||||
|       this.$emit('deselect') | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| <template> | ||||
|   <div v-if="invoice" class="main-content invoice-view-page"> | ||||
|     <div class="page-header"> | ||||
|       <h3 class="page-title"> {{ invoice.invoice_number }}</h3> | ||||
|       <h3 class="page-title">{{ invoice.invoice_number }}</h3> | ||||
|       <div class="page-actions row"> | ||||
|         <div class="col-xs-2 mr-3"> | ||||
|           <base-button | ||||
| @ -24,26 +24,47 @@ | ||||
|         > | ||||
|           {{ $t('invoices.send_invoice') }} | ||||
|         </base-button> | ||||
|         <router-link v-if="invoice.status === 'SENT'" :to="`/admin/payments/${$route.params.id}/create`"> | ||||
|           <base-button | ||||
|             color="theme" | ||||
|           > | ||||
|         <router-link | ||||
|           v-if="invoice.status === 'SENT'" | ||||
|           :to="`/admin/payments/${$route.params.id}/create`" | ||||
|         > | ||||
|           <base-button color="theme"> | ||||
|             {{ $t('payments.record_payment') }} | ||||
|           </base-button> | ||||
|         </router-link> | ||||
|         <v-dropdown :close-on-select="false" align="left" class="filter-container"> | ||||
|         <v-dropdown | ||||
|           :close-on-select="true" | ||||
|           align="left" | ||||
|           class="filter-container" | ||||
|         > | ||||
|           <a slot="activator" href="#"> | ||||
|             <base-button color="theme"> | ||||
|               <font-awesome-icon icon="ellipsis-h" /> | ||||
|             </base-button> | ||||
|           </a> | ||||
|           <v-dropdown-item> | ||||
|             <router-link :to="{path: `/admin/invoices/${$route.params.id}/edit`}" class="dropdown-item"> | ||||
|               <font-awesome-icon :icon="['fas', 'pencil-alt']" class="dropdown-item-icon"/> | ||||
|             <div class="dropdown-item" @click="copyPdfUrl"> | ||||
|               <font-awesome-icon | ||||
|                 :icon="['fas', 'link']" | ||||
|                 class="dropdown-item-icon" | ||||
|               /> | ||||
|               {{ $t('general.copy_pdf_url') }} | ||||
|             </div> | ||||
|             <router-link | ||||
|               :to="{ path: `/admin/invoices/${$route.params.id}/edit` }" | ||||
|               class="dropdown-item" | ||||
|             > | ||||
|               <font-awesome-icon | ||||
|                 :icon="['fas', 'pencil-alt']" | ||||
|                 class="dropdown-item-icon" | ||||
|               /> | ||||
|               {{ $t('general.edit') }} | ||||
|             </router-link> | ||||
|             <div class="dropdown-item" @click="removeInvoice($route.params.id)"> | ||||
|               <font-awesome-icon :icon="['fas', 'trash']" class="dropdown-item-icon" /> | ||||
|               <font-awesome-icon | ||||
|                 :icon="['fas', 'trash']" | ||||
|                 class="dropdown-item-icon" | ||||
|               /> | ||||
|               {{ $t('general.delete') }} | ||||
|             </div> | ||||
|           </v-dropdown-item> | ||||
| @ -61,14 +82,18 @@ | ||||
|           align-icon="right" | ||||
|           @input="onSearch" | ||||
|         /> | ||||
|         <div | ||||
|           class="btn-group ml-3" | ||||
|           role="group" | ||||
|           aria-label="First group" | ||||
|         > | ||||
|           <v-dropdown :close-on-select="false" align="left" class="filter-container"> | ||||
|         <div class="btn-group ml-3" role="group" aria-label="First group"> | ||||
|           <v-dropdown | ||||
|             :close-on-select="false" | ||||
|             align="left" | ||||
|             class="filter-container" | ||||
|           > | ||||
|             <a slot="activator" href="#"> | ||||
|               <base-button class="inv-button inv-filter-fields-btn" color="default" size="medium"> | ||||
|               <base-button | ||||
|                 class="inv-button inv-filter-fields-btn" | ||||
|                 color="default" | ||||
|                 size="medium" | ||||
|               > | ||||
|                 <font-awesome-icon icon="filter" /> | ||||
|               </base-button> | ||||
|             </a> | ||||
| @ -84,8 +109,10 @@ | ||||
|                 class="inv-radio" | ||||
|                 value="invoice_date" | ||||
|                 @change="onSearch" | ||||
|               > | ||||
|               <label class="inv-label" for="filter_invoice_date">{{ $t('invoices.invoice_date') }}</label> | ||||
|               /> | ||||
|               <label class="inv-label" for="filter_invoice_date">{{ | ||||
|                 $t('invoices.invoice_date') | ||||
|               }}</label> | ||||
|             </div> | ||||
|             <div class="filter-items"> | ||||
|               <input | ||||
| @ -96,8 +123,10 @@ | ||||
|                 class="inv-radio" | ||||
|                 value="due_date" | ||||
|                 @change="onSearch" | ||||
|               > | ||||
|               <label class="inv-label" for="filter_due_date">{{ $t('invoices.due_date') }}</label> | ||||
|               /> | ||||
|               <label class="inv-label" for="filter_due_date">{{ | ||||
|                 $t('invoices.due_date') | ||||
|               }}</label> | ||||
|             </div> | ||||
|             <div class="filter-items"> | ||||
|               <input | ||||
| @ -108,11 +137,19 @@ | ||||
|                 class="inv-radio" | ||||
|                 value="invoice_number" | ||||
|                 @change="onSearch" | ||||
|               > | ||||
|               <label class="inv-label" for="filter_invoice_number">{{ $t('invoices.invoice_number') }}</label> | ||||
|               /> | ||||
|               <label class="inv-label" for="filter_invoice_number">{{ | ||||
|                 $t('invoices.invoice_number') | ||||
|               }}</label> | ||||
|             </div> | ||||
|           </v-dropdown> | ||||
|           <base-button v-tooltip.top-center="{ content: getOrderName }" class="inv-button inv-filter-sorting-btn" color="default" size="medium" @click="sortData"> | ||||
|           <base-button | ||||
|             v-tooltip.top-center="{ content: getOrderName }" | ||||
|             class="inv-button inv-filter-sorting-btn" | ||||
|             color="default" | ||||
|             size="medium" | ||||
|             @click="sortData" | ||||
|           > | ||||
|             <font-awesome-icon v-if="getOrderBy" icon="sort-amount-up" /> | ||||
|             <font-awesome-icon v-else icon="sort-amount-down" /> | ||||
|           </base-button> | ||||
| @ -121,7 +158,7 @@ | ||||
|       <base-loader v-if="isSearching" /> | ||||
|       <div v-else class="side-content"> | ||||
|         <router-link | ||||
|           v-for="(invoice,index) in invoices" | ||||
|           v-for="(invoice, index) in invoices" | ||||
|           :to="`/admin/invoices/${invoice.id}/view`" | ||||
|           :key="index" | ||||
|           class="side-invoice" | ||||
| @ -129,10 +166,20 @@ | ||||
|           <div class="left"> | ||||
|             <div class="inv-name">{{ invoice.user.name }}</div> | ||||
|             <div class="inv-number">{{ invoice.invoice_number }}</div> | ||||
|             <div :class="'inv-status-'+invoice.status.toLowerCase()" class="inv-status">{{ invoice.status }}</div> | ||||
|             <div | ||||
|               :class="'inv-status-' + invoice.status.toLowerCase()" | ||||
|               class="inv-status" | ||||
|             > | ||||
|               {{ invoice.status }} | ||||
|             </div> | ||||
|           </div> | ||||
|           <div class="right"> | ||||
|             <div class="inv-amount" v-html="$utils.formatMoney(invoice.due_amount, invoice.user.currency)" /> | ||||
|             <div | ||||
|               class="inv-amount" | ||||
|               v-html=" | ||||
|                 $utils.formatMoney(invoice.due_amount, invoice.user.currency) | ||||
|               " | ||||
|             /> | ||||
|             <div class="inv-date">{{ invoice.formattedInvoiceDate }}</div> | ||||
|           </div> | ||||
|         </router-link> | ||||
| @ -141,8 +188,8 @@ | ||||
|         </p> | ||||
|       </div> | ||||
|     </div> | ||||
|     <div class="invoice-view-page-container" > | ||||
|       <iframe :src="`${shareableLink}`" class="frame-style"/> | ||||
|     <div class="invoice-view-page-container"> | ||||
|       <iframe :src="`${shareableLink}`" class="frame-style" /> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
| @ -291,6 +338,14 @@ export default { | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     copyPdfUrl () { | ||||
|       let pdfUrl = `${window.location.origin}/invoices/pdf/${this.invoice.unique_hash}` | ||||
|  | ||||
|       let response = this.$utils.copyTextToClipboard(pdfUrl) | ||||
|  | ||||
|       window.toastr['success'](this.$tc('Copied PDF url to clipboard!')) | ||||
|  | ||||
|     }, | ||||
|     async removeInvoice (id) { | ||||
|       this.selectInvoice([parseInt(id)]) | ||||
|       this.id = id | ||||
|  | ||||
| @ -266,7 +266,7 @@ export default { | ||||
|     }, | ||||
|     async addItemUnit () { | ||||
|       this.openModal({ | ||||
|         'title': 'Add Item Unit', | ||||
|         'title': this.$t('settings.customization.items.add_item_unit'), | ||||
|         'componentName': 'ItemUnit' | ||||
|       }) | ||||
|     } | ||||
|  | ||||
| @ -305,7 +305,7 @@ export default { | ||||
|     }, | ||||
|     async addPaymentMode () { | ||||
|       this.openModal({ | ||||
|         'title': 'Add Payment Mode', | ||||
|         'title': this.$t('settings.customization.payments.add_payment_mode'), | ||||
|         'componentName': 'PaymentMode' | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| <template> | ||||
|   <div v-if="payment" class="main-content payment-view-page"> | ||||
|     <div class="page-header"> | ||||
|       <h3 class="page-title"> {{ payment.payment_number }}</h3> | ||||
|       <h3 class="page-title">{{ payment.payment_number }}</h3> | ||||
|       <div class="page-actions row"> | ||||
|         <base-button | ||||
|           :loading="isSendingEmail" | ||||
| @ -11,19 +11,39 @@ | ||||
|         > | ||||
|           {{ $t('payments.send_payment_receipt') }} | ||||
|         </base-button> | ||||
|         <v-dropdown :close-on-select="false" align="left" class="filter-container"> | ||||
|         <v-dropdown | ||||
|           :close-on-select="true" | ||||
|           align="left" | ||||
|           class="filter-container" | ||||
|         > | ||||
|           <a slot="activator" href="#"> | ||||
|             <base-button color="theme"> | ||||
|               <font-awesome-icon icon="ellipsis-h" /> | ||||
|             </base-button> | ||||
|           </a> | ||||
|           <v-dropdown-item> | ||||
|             <router-link :to="{path: `/admin/payments/${$route.params.id}/edit`}" class="dropdown-item"> | ||||
|               <font-awesome-icon :icon="['fas', 'pencil-alt']" class="dropdown-item-icon"/> | ||||
|             <div class="dropdown-item" @click="copyPdfUrl"> | ||||
|               <font-awesome-icon | ||||
|                 :icon="['fas', 'link']" | ||||
|                 class="dropdown-item-icon" | ||||
|               /> | ||||
|               {{ $t('general.copy_pdf_url') }} | ||||
|             </div> | ||||
|             <router-link | ||||
|               :to="{ path: `/admin/payments/${$route.params.id}/edit` }" | ||||
|               class="dropdown-item" | ||||
|             > | ||||
|               <font-awesome-icon | ||||
|                 :icon="['fas', 'pencil-alt']" | ||||
|                 class="dropdown-item-icon" | ||||
|               /> | ||||
|               {{ $t('general.edit') }} | ||||
|             </router-link> | ||||
|             <div class="dropdown-item" @click="removePayment($route.params.id)"> | ||||
|               <font-awesome-icon :icon="['fas', 'trash']" class="dropdown-item-icon" /> | ||||
|               <font-awesome-icon | ||||
|                 :icon="['fas', 'trash']" | ||||
|                 class="dropdown-item-icon" | ||||
|               /> | ||||
|               {{ $t('general.delete') }} | ||||
|             </div> | ||||
|           </v-dropdown-item> | ||||
| @ -41,14 +61,18 @@ | ||||
|           align-icon="right" | ||||
|           @input="onSearch" | ||||
|         /> | ||||
|         <div | ||||
|           class="btn-group ml-3" | ||||
|           role="group" | ||||
|           aria-label="First group" | ||||
|         > | ||||
|           <v-dropdown :close-on-select="false" align="left" class="filter-container"> | ||||
|         <div class="btn-group ml-3" role="group" aria-label="First group"> | ||||
|           <v-dropdown | ||||
|             :close-on-select="false" | ||||
|             align="left" | ||||
|             class="filter-container" | ||||
|           > | ||||
|             <a slot="activator" href="#"> | ||||
|               <base-button class="inv-button inv-filter-fields-btn" color="default" size="medium"> | ||||
|               <base-button | ||||
|                 class="inv-button inv-filter-fields-btn" | ||||
|                 color="default" | ||||
|                 size="medium" | ||||
|               > | ||||
|                 <font-awesome-icon icon="filter" /> | ||||
|               </base-button> | ||||
|             </a> | ||||
| @ -64,8 +88,10 @@ | ||||
|                 class="inv-radio" | ||||
|                 value="invoice_number" | ||||
|                 @change="onSearch" | ||||
|               > | ||||
|               <label class="inv-label" for="filter_invoice_number">{{ $t('invoices.title') }}</label> | ||||
|               /> | ||||
|               <label class="inv-label" for="filter_invoice_number">{{ | ||||
|                 $t('invoices.title') | ||||
|               }}</label> | ||||
|             </div> | ||||
|             <div class="filter-items"> | ||||
|               <input | ||||
| @ -76,8 +102,10 @@ | ||||
|                 class="inv-radio" | ||||
|                 value="payment_date" | ||||
|                 @change="onSearch" | ||||
|               > | ||||
|               <label class="inv-label" for="filter_payment_date">{{ $t('payments.date') }}</label> | ||||
|               /> | ||||
|               <label class="inv-label" for="filter_payment_date">{{ | ||||
|                 $t('payments.date') | ||||
|               }}</label> | ||||
|             </div> | ||||
|             <div class="filter-items"> | ||||
|               <input | ||||
| @ -88,11 +116,19 @@ | ||||
|                 class="inv-radio" | ||||
|                 value="payment_number" | ||||
|                 @change="onSearch" | ||||
|               > | ||||
|               <label class="inv-label" for="filter_payment_number">{{ $t('payments.payment_number') }}</label> | ||||
|               /> | ||||
|               <label class="inv-label" for="filter_payment_number">{{ | ||||
|                 $t('payments.payment_number') | ||||
|               }}</label> | ||||
|             </div> | ||||
|           </v-dropdown> | ||||
|           <base-button v-tooltip.top-center="{ content: getOrderName }" class="inv-button inv-filter-sorting-btn" color="default" size="medium" @click="sortData"> | ||||
|           <base-button | ||||
|             v-tooltip.top-center="{ content: getOrderName }" | ||||
|             class="inv-button inv-filter-sorting-btn" | ||||
|             color="default" | ||||
|             size="medium" | ||||
|             @click="sortData" | ||||
|           > | ||||
|             <font-awesome-icon v-if="getOrderBy" icon="sort-amount-up" /> | ||||
|             <font-awesome-icon v-else icon="sort-amount-down" /> | ||||
|           </base-button> | ||||
| @ -101,7 +137,7 @@ | ||||
|       <base-loader v-if="isSearching" /> | ||||
|       <div v-else class="side-content"> | ||||
|         <router-link | ||||
|           v-for="(payment,index) in payments" | ||||
|           v-for="(payment, index) in payments" | ||||
|           :to="`/admin/payments/${payment.id}/view`" | ||||
|           :key="index" | ||||
|           class="side-payment" | ||||
| @ -112,7 +148,10 @@ | ||||
|             <div class="inv-number">{{ payment.invoice_number }}</div> | ||||
|           </div> | ||||
|           <div class="right"> | ||||
|             <div class="inv-amount" v-html="$utils.formatMoney(payment.amount, payment.user.currency)" /> | ||||
|             <div | ||||
|               class="inv-amount" | ||||
|               v-html="$utils.formatMoney(payment.amount, payment.user.currency)" | ||||
|             /> | ||||
|             <div class="inv-date">{{ payment.formattedPaymentDate }}</div> | ||||
|             <!-- <div class="inv-number">{{ payment.payment_method.name }}</div> --> | ||||
|           </div> | ||||
| @ -122,8 +161,8 @@ | ||||
|         </p> | ||||
|       </div> | ||||
|     </div> | ||||
|     <div class="payment-view-page-container" > | ||||
|       <iframe :src="`${shareableLink}`" class="frame-style"/> | ||||
|     <div class="payment-view-page-container"> | ||||
|       <iframe :src="`${shareableLink}`" class="frame-style" /> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
| @ -260,6 +299,13 @@ export default { | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     copyPdfUrl () { | ||||
|       let pdfUrl = `${window.location.origin}/payments/pdf/${this.payment.unique_hash}` | ||||
|  | ||||
|       let response = this.$utils.copyTextToClipboard(pdfUrl) | ||||
|  | ||||
|       window.toastr['success'](this.$tc('Copied PDF url to clipboard!')) | ||||
|     }, | ||||
|     async removePayment (id) { | ||||
|       this.id = id | ||||
|       window.swal({ | ||||
|  | ||||
| @ -403,14 +403,14 @@ export default { | ||||
|     }, | ||||
|     async addItemUnit () { | ||||
|       this.openModal({ | ||||
|         'title': 'Add Item Unit', | ||||
|         'title': this.$t('settings.customization.items.add_item_unit'), | ||||
|         'componentName': 'ItemUnit' | ||||
|       }) | ||||
|       this.$refs.itemTable.refresh() | ||||
|     }, | ||||
|     async editItemUnit (data) { | ||||
|       this.openModal({ | ||||
|         'title': 'Edit Item Unit', | ||||
|         'title': this.$t('settings.customization.items.edit_item_unit'), | ||||
|         'componentName': 'ItemUnit', | ||||
|         'id': data.id, | ||||
|         'data': data | ||||
| @ -439,14 +439,14 @@ export default { | ||||
|     }, | ||||
|     async addPaymentMode () { | ||||
|       this.openModal({ | ||||
|         'title': 'Add Payment Mode', | ||||
|         'title': this.$t('settings.customization.payments.add_payment_mode'), | ||||
|         'componentName': 'PaymentMode' | ||||
|       }) | ||||
|       this.$refs.table.refresh() | ||||
|     }, | ||||
|     async editPaymentMode (data) { | ||||
|       this.openModal({ | ||||
|         'title': 'Edit Payment Mode', | ||||
|         'title': this.$t('settings.customization.payments.edit_payment_mode'), | ||||
|         'componentName': 'PaymentMode', | ||||
|         'id': data.id, | ||||
|         'data': data | ||||
|  | ||||
| @ -121,7 +121,7 @@ export default { | ||||
|     }, | ||||
|     openCategoryModal () { | ||||
|       this.openModal({ | ||||
|         'title': 'Add Category', | ||||
|         'title': this.$t('settings.expense_category.add_category'), | ||||
|         'componentName': 'CategoryModal' | ||||
|       }) | ||||
|       this.$refs.table.refresh() | ||||
| @ -129,7 +129,7 @@ export default { | ||||
|     async EditCategory (id) { | ||||
|       let response = await this.fetchCategory(id) | ||||
|       this.openModal({ | ||||
|         'title': 'Edit Category', | ||||
|         'title': this.$t('settings.expense_category.edit_category'), | ||||
|         'componentName': 'CategoryModal', | ||||
|         'id': id, | ||||
|         'data': response.data.category | ||||
|  | ||||
| @ -183,7 +183,7 @@ export default { | ||||
|     async EditTax (id) { | ||||
|       let response = await this.fetchTaxType(id) | ||||
|       this.openModal({ | ||||
|         'title': 'Edit Tax', | ||||
|         'title': this.$t('settings.tax_types.edit_tax'), | ||||
|         'componentName': 'TaxTypeModal', | ||||
|         'id': id, | ||||
|         'data': response.data.taxType | ||||
|  | ||||
| @ -1,33 +1,76 @@ | ||||
| <template> | ||||
|   <div class="setting-main-container"> | ||||
|   <div class="setting-main-container update-container"> | ||||
|     <div class="card setting-card"> | ||||
|       <div class="page-header"> | ||||
|         <h3 class="page-title">{{ $t('settings.update_app.title') }}</h3> | ||||
|         <p class="page-sub-title"> | ||||
|           {{ $t('settings.update_app.description') }} | ||||
|         </p> | ||||
|         <label class="input-label">{{ $t('settings.update_app.current_version') }}</label><br> | ||||
|         <label class="input-label">{{ | ||||
|           $t('settings.update_app.current_version') | ||||
|         }}</label | ||||
|         ><br /> | ||||
|         <label class="version mb-4">{{ currentVersion }}</label> | ||||
|         <base-button :outline="true" :disabled="isCheckingforUpdate || isUpdating" size="large" color="theme" class="mb-4" @click="checkUpdate"> | ||||
|           <font-awesome-icon :class="{'update': isCheckingforUpdate}" style="margin-right: 10px;" icon="sync-alt" /> | ||||
|         <base-button | ||||
|           :outline="true" | ||||
|           :disabled="isCheckingforUpdate || isUpdating" | ||||
|           size="large" | ||||
|           color="theme" | ||||
|           class="mb-4" | ||||
|           @click="checkUpdate" | ||||
|         > | ||||
|           <font-awesome-icon | ||||
|             :class="{ update: isCheckingforUpdate }" | ||||
|             style="margin-right: 10px;" | ||||
|             icon="sync-alt" | ||||
|           /> | ||||
|           {{ $t('settings.update_app.check_update') }} | ||||
|         </base-button> | ||||
|         <hr> | ||||
|         <hr /> | ||||
|         <div v-show="!isUpdating" v-if="isUpdateAvailable" class="mt-4 content"> | ||||
|           <h3 class="page-title mb-3">{{ $t('settings.update_app.avail_update') }}</h3> | ||||
|           <label class="input-label">{{ $t('settings.update_app.next_version') }}</label><br> | ||||
|           <h3 class="page-title mb-3"> | ||||
|             {{ $t('settings.update_app.avail_update') }} | ||||
|           </h3> | ||||
|           <label class="input-label">{{ | ||||
|             $t('settings.update_app.next_version') | ||||
|           }}</label | ||||
|           ><br /> | ||||
|           <label class="version">{{ updateData.version }}</label> | ||||
|           <p class="page-sub-title" style="white-space: pre-wrap;">{{ description }}</p> | ||||
|           <base-button size="large" icon="rocket" color="theme" @click="onUpdateApp"> | ||||
|           <base-button | ||||
|             size="large" | ||||
|             icon="rocket" | ||||
|             color="theme" | ||||
|             @click="onUpdateApp" | ||||
|           > | ||||
|             {{ $t('settings.update_app.update') }} | ||||
|           </base-button> | ||||
|         </div> | ||||
|         <div v-if="isUpdating" class="mt-4 content"> | ||||
|           <h3 class="page-title">{{ $t('settings.update_app.update_progress') }}</h3> | ||||
|           <p class="page-sub-title"> | ||||
|             {{ $t('settings.update_app.progress_text') }} | ||||
|           </p> | ||||
|           <font-awesome-icon icon="spinner" class="fa-spin"/> | ||||
|           <div class="d-flex flex-row justify-content-between"> | ||||
|             <div> | ||||
|               <h3 class="page-title"> | ||||
|                 {{ $t('settings.update_app.update_progress') }} | ||||
|               </h3> | ||||
|               <p class="page-sub-title"> | ||||
|                 {{ $t('settings.update_app.progress_text') }} | ||||
|               </p> | ||||
|             </div> | ||||
|             <font-awesome-icon icon="spinner" class="update-spinner fa-spin" /> | ||||
|           </div> | ||||
|           <ul class="update-steps-container"> | ||||
|             <li class="update-step" v-for="step in updateSteps"> | ||||
|               <p class="update-step-text">{{ $t(step.translationKey) }}</p> | ||||
|               <div class="update-status-container"> | ||||
|                 <span v-if="step.time" class="update-time">{{ | ||||
|                   step.time | ||||
|                 }}</span> | ||||
|                 <span :class="'update-status status-' + getStatus(step)">{{ | ||||
|                   getStatus(step) | ||||
|                 }}</span> | ||||
|               </div> | ||||
|             </li> | ||||
|           </ul> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
| @ -36,7 +79,7 @@ | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|   data () { | ||||
|   data() { | ||||
|     return { | ||||
|       isShowProgressBar: false, | ||||
|       isUpdateAvailable: false, | ||||
| @ -46,60 +89,78 @@ export default { | ||||
|       interval: null, | ||||
|       description: '', | ||||
|       currentVersion: '', | ||||
|       updateSteps: [ | ||||
|         { | ||||
|           translationKey: 'settings.update_app.download_zip_file', | ||||
|           stepUrl: '/api/update/download', | ||||
|           time: null, | ||||
|           started: false, | ||||
|           completed: false, | ||||
|         }, | ||||
|         { | ||||
|           translationKey: 'settings.update_app.unzipping_package', | ||||
|           stepUrl: '/api/update/unzip', | ||||
|           time: null, | ||||
|           started: false, | ||||
|           completed: false, | ||||
|         }, | ||||
|         { | ||||
|           translationKey: 'settings.update_app.copying_files', | ||||
|           stepUrl: '/api/update/copy', | ||||
|           time: null, | ||||
|           started: false, | ||||
|           completed: false, | ||||
|         }, | ||||
|         { | ||||
|           translationKey: 'settings.update_app.running_migrations', | ||||
|           stepUrl: '/api/update/migrate', | ||||
|           time: null, | ||||
|           started: false, | ||||
|           completed: false, | ||||
|         }, | ||||
|         { | ||||
|           translationKey: 'settings.update_app.finishing_update', | ||||
|           stepUrl: '/api/update/finish', | ||||
|           time: null, | ||||
|           started: false, | ||||
|           completed: false, | ||||
|         }, | ||||
|       ], | ||||
|       updateData: { | ||||
|         isMinor: Boolean, | ||||
|         installed: '', | ||||
|         version: '' | ||||
|       } | ||||
|         version: '', | ||||
|       }, | ||||
|     } | ||||
|   }, | ||||
|   created () { | ||||
|   created() { | ||||
|     window.addEventListener('beforeunload', (event) => { | ||||
|       if (this.isUpdating) { | ||||
|         event.returnValue = 'Update is in progress!' | ||||
|       } | ||||
|     }) | ||||
|   }, | ||||
|   mounted () { | ||||
|   mounted() { | ||||
|     window.axios.get('/api/settings/app/version').then((res) => { | ||||
|       this.currentVersion = res.data.version | ||||
|     }) | ||||
|   }, | ||||
|   methods: { | ||||
|     closeHandler () { | ||||
|     closeHandler() { | ||||
|       console.log('closing') | ||||
|     }, | ||||
|     async onUpdateApp () { | ||||
|       try { | ||||
|         this.isUpdating = true | ||||
|         this.updateData.installed = this.currentVersion | ||||
|         let res = await window.axios.post('/api/update', this.updateData) | ||||
|  | ||||
|         if (res.data.success) { | ||||
|           setTimeout(async () => { | ||||
|             await window.axios.post('/api/update/finish', this.updateData) | ||||
|  | ||||
|             window.toastr['success'](this.$t('settings.update_app.update_success')) | ||||
|             this.currentVersion = this.updateData.version | ||||
|             this.isUpdateAvailable = false | ||||
|  | ||||
|             setTimeout(() => { | ||||
|               location.reload() | ||||
|             }, 2000) | ||||
|           }, 1000) | ||||
|         } else { | ||||
|           console.log(res.data) | ||||
|           window.toastr['error'](res.data.error) | ||||
|         } | ||||
|       } catch (e) { | ||||
|         console.log(e) | ||||
|         window.toastr['error']('Something went wrong') | ||||
|     getStatus(step) { | ||||
|       if (step.started && step.completed) { | ||||
|         return 'finished' | ||||
|       } else if (step.started && !step.completed) { | ||||
|         return 'running' | ||||
|       } else if (!step.started && !step.completed) { | ||||
|         return 'pending' | ||||
|       } else { | ||||
|         return 'error' | ||||
|       } | ||||
|  | ||||
|       this.isUpdating = false | ||||
|     }, | ||||
|  | ||||
|     async checkUpdate () { | ||||
|     async checkUpdate() { | ||||
|       try { | ||||
|         this.isCheckingforUpdate = true | ||||
|         let response = await window.axios.get('/api/check/update') | ||||
| @ -122,8 +183,67 @@ export default { | ||||
|         this.isCheckingforUpdate = false | ||||
|         window.toastr['error']('Something went wrong') | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|     }, | ||||
|     async onUpdateApp() { | ||||
|       let path = null | ||||
|  | ||||
|       for (let index = 0; index < this.updateSteps.length; index++) { | ||||
|         let currentStep = this.updateSteps[index] | ||||
|         try { | ||||
|           this.isUpdating = true | ||||
|           currentStep.started = true | ||||
|           let updateParams = { | ||||
|             version: this.updateData.version, | ||||
|             installed: this.currentVersion, | ||||
|             path: path || null, | ||||
|           } | ||||
|  | ||||
|           let requestResponse = await window.axios.post( | ||||
|             currentStep.stepUrl, | ||||
|             updateParams | ||||
|           ) | ||||
|           currentStep.completed = true | ||||
|           if (requestResponse.data && requestResponse.data.path) { | ||||
|             path = requestResponse.data.path | ||||
|           } | ||||
|  | ||||
|           // on finish | ||||
|           if ( | ||||
|             currentStep.translationKey == 'settings.update_app.finishing_update' | ||||
|           ) { | ||||
|             this.isUpdating = false | ||||
|             window.toastr['success']( | ||||
|               this.$t('settings.update_app.update_success') | ||||
|             ) | ||||
|  | ||||
|             setTimeout(() => { | ||||
|               location.reload() | ||||
|             }, 3000) | ||||
|           } | ||||
|         } catch (error) { | ||||
|           currentStep.started = false | ||||
|           currentStep.completed = true | ||||
|           window.toastr['error'](this.$t('validation.something_went_wrong')) | ||||
|           this.onUpdateFailed(currentStep.translationKey) | ||||
|           return false | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     onUpdateFailed(translationKey) { | ||||
|       let stepName = this.$t(translationKey)  | ||||
|       swal({ | ||||
|         title: this.$t('settings.update_app.update_failed'), | ||||
|         text: this.$tc('settings.update_app.update_failed_text', stepName, {step: stepName}), | ||||
|         buttons: [this.$t('general.cancel'), this.$t('general.retry')], | ||||
|       }).then(async (value) => { | ||||
|         if (value) { | ||||
|           this.onUpdateApp() | ||||
|           return  | ||||
|         } | ||||
|         this.isUpdating = false | ||||
|       }) | ||||
|     }, | ||||
|   }, | ||||
| } | ||||
| </script> | ||||
|  | ||||
|  | ||||
| @ -54,7 +54,8 @@ import { | ||||
|   faEyeSlash, | ||||
|   faSyncAlt, | ||||
|   faRocket, | ||||
|   faCamera | ||||
|   faCamera, | ||||
|   faLink, | ||||
| } from '@fortawesome/free-solid-svg-icons' | ||||
| import { far } from '@fortawesome/free-regular-svg-icons' | ||||
| import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome' | ||||
| @ -119,7 +120,8 @@ library.add( | ||||
|   faPaperPlane, | ||||
|   faSyncAlt, | ||||
|   faRocket, | ||||
|   faCamera | ||||
|   faCamera, | ||||
|   faLink | ||||
| ) | ||||
|  | ||||
| Vue.component('font-awesome-icon', FontAwesomeIcon) | ||||
|  | ||||
| @ -18,6 +18,22 @@ | ||||
|         transform: translate(-50%,-50%); | ||||
|     } | ||||
|  | ||||
|     .right-input-group-text { | ||||
|         position: absolute; | ||||
|         width: 13px; | ||||
|         height: 18px; | ||||
|         min-width: 18px; | ||||
|         color: $ls-color-gray; | ||||
|         font-style: normal; | ||||
|         font-weight: 900; | ||||
|         font-size: 14px; | ||||
|         line-height: 16px; | ||||
|         top: 50%; | ||||
|         right: 0px; | ||||
|         z-index: 1; | ||||
|         transform: translate(-50%, -50%); | ||||
|     } | ||||
|  | ||||
|     .right-icon { | ||||
|         position: absolute; | ||||
|         width: 13px; | ||||
|  | ||||
| @ -27,6 +27,7 @@ fieldset[disabled] .multiselect { | ||||
|     top: 50%; | ||||
|     left: 50%; | ||||
|     margin: -8px 0 0 -8px; | ||||
|     z-index: 5; | ||||
|     width: 16px; | ||||
|     height: 16px; | ||||
|     border-radius: 100%; | ||||
|  | ||||
							
								
								
									
										78
									
								
								resources/assets/sass/pages/settings.scss
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										78
									
								
								resources/assets/sass/pages/settings.scss
									
									
									
									
										vendored
									
									
								
							| @ -122,6 +122,84 @@ | ||||
|  | ||||
|     } | ||||
|  | ||||
|     .update-container { | ||||
|  | ||||
|         .update-spinner { | ||||
|             font-size: 30px; | ||||
|             color: $ls-color-gray--dark; | ||||
|         } | ||||
|  | ||||
|         .update-steps-container { | ||||
|             list-style-type: none; | ||||
|             width: 100%; | ||||
|             padding: 0px; | ||||
|  | ||||
|             .update-step { | ||||
|                 display: flex; | ||||
|                 width: 100%; | ||||
|                 justify-content: space-between; | ||||
|                 padding: 10px 0px; | ||||
|                 border-bottom: 1px solid $ls-color-gray--light; | ||||
|  | ||||
|                 &:last-child { | ||||
|                     border-bottom: 0px solid; | ||||
|                 } | ||||
|  | ||||
|             } | ||||
|  | ||||
|         } | ||||
|  | ||||
|         .update-step-text { | ||||
|             font-size: $font-size-base; | ||||
|             margin: 0px; | ||||
|             line-height: 2rem; | ||||
|         } | ||||
|  | ||||
|         .update-status-container { | ||||
|             display: flex; | ||||
|             flex-direction: row; | ||||
|             align-items: center; | ||||
|  | ||||
|             .update-time { | ||||
|                 font-size: 10px; | ||||
|                 color: $ls-color-gray--dark; | ||||
|                 margin-right: 10px; | ||||
|             } | ||||
|      | ||||
|             .update-status { | ||||
|                 font-size: 13px; | ||||
|                 width: 88px; | ||||
|                 height: 28px; | ||||
|                 display: block; | ||||
|                 text-align: center; | ||||
|                 border-radius: 30px; | ||||
|                 text-transform: uppercase; | ||||
|                 line-height: 2rem; | ||||
|             } | ||||
|      | ||||
|             .status-pending { | ||||
|                 background-color: #EAF1FB; | ||||
|                 color: $ls-color-secondary; | ||||
|             } | ||||
|      | ||||
|             .status-running { | ||||
|                 background-color: rgba(21, 178, 236, 0.15); | ||||
|                 color: $ls-color-light-blue; | ||||
|             } | ||||
|      | ||||
|             .status-finished { | ||||
|                 background-color: #D4F6EE; | ||||
|                 color: $ls-color-green; | ||||
|             } | ||||
|      | ||||
|             .status-error { | ||||
|                 background-color: rgba(251, 113, 120, 0.22); | ||||
|                 color: $ls-color-red; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     .add-new-tax { | ||||
|         height: 45px; | ||||
|         white-space: nowrap; | ||||
|  | ||||
| @ -1,10 +1,12 @@ | ||||
| <!DOCTYPE html> | ||||
| <html> | ||||
|  | ||||
| <head> | ||||
|     <title>Estimate</title> | ||||
|     <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> | ||||
|     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | ||||
|  | ||||
|     <style type="text/css"> | ||||
|         /* -- Base -- */ | ||||
|         body { | ||||
|             font-family: "DejaVu Sans"; | ||||
|         } | ||||
| @ -12,31 +14,22 @@ | ||||
|         html { | ||||
|             margin: 0px; | ||||
|             padding: 0px; | ||||
|             margin-top: 50px; | ||||
|         } | ||||
|  | ||||
|         table { | ||||
|             border-collapse: collapse; | ||||
|         } | ||||
|  | ||||
|         .header-line { | ||||
|             color:rgba(0, 0, 0, 0.2); | ||||
|             position: absolute; | ||||
|             top: 90px; | ||||
|             left: 0px; | ||||
|             width: 100%; | ||||
|         } | ||||
|  | ||||
|         hr { | ||||
|             margin: 0 30px 0 30px; | ||||
|             color:rgba(0, 0, 0, 0.2); | ||||
|             color: rgba(0, 0, 0, 0.2); | ||||
|             border: 0.5px solid #EAF1FB; | ||||
|         } | ||||
|  | ||||
|         .header-center { | ||||
|             text-align: center | ||||
|         } | ||||
|         /* -- Header -- */ | ||||
|  | ||||
|         .header-table { | ||||
|         .header-container { | ||||
|             position: absolute; | ||||
|             width: 100%; | ||||
|             height: 90px; | ||||
| @ -44,6 +37,14 @@ | ||||
|             top: -50px; | ||||
|         } | ||||
|  | ||||
|         .header-bottom-divider { | ||||
|             color: rgba(0, 0, 0, 0.2); | ||||
|             position: absolute; | ||||
|             top: 90px; | ||||
|             left: 0px; | ||||
|             width: 100%; | ||||
|         } | ||||
|  | ||||
|         .header-logo { | ||||
|             height: 50px; | ||||
|             margin-top: 20px; | ||||
| @ -51,122 +52,95 @@ | ||||
|             color: #817AE3; | ||||
|         } | ||||
|  | ||||
|         .inv-flex{ | ||||
|             display:flex; | ||||
|         } | ||||
|  | ||||
|         .inv-data{ | ||||
|             text-align:right; | ||||
|             margin-right:120px; | ||||
|         } | ||||
|         .inv-value{ | ||||
|             text-align:left; | ||||
|             margin-left:160px; | ||||
|         } | ||||
|         .header { | ||||
|             font-size: 20px; | ||||
|             color: rgba(0, 0, 0, 0.7); | ||||
|         } | ||||
|  | ||||
|         .TextColor1 { | ||||
|             font-size: 16px; | ||||
|             color: rgba(0, 0, 0, 0.5); | ||||
|         } | ||||
|  | ||||
|         @page { | ||||
|             margin-top: 60px !important; | ||||
|         } | ||||
|  | ||||
|         .wrapper { | ||||
|            display: block; | ||||
|            margin-top: 0px; | ||||
|            padding-top: 16px; | ||||
|            padding-bottom: 20px; | ||||
|             display: block; | ||||
|             margin-top: 0px; | ||||
|             padding-top: 16px; | ||||
|             padding-bottom: 20px; | ||||
|         } | ||||
|  | ||||
|         .address { | ||||
|             /* display: inline-block; */ | ||||
|             padding-top: 30px | ||||
|         /* -- Company Details -- */ | ||||
|  | ||||
|         .company-details-container { | ||||
|             padding-top: 30px; | ||||
|         } | ||||
|  | ||||
|         .company { | ||||
|         .company-address-container { | ||||
|             float: left; | ||||
|             padding-left: 30px; | ||||
|             font-weight: normal; | ||||
|             display: inline; | ||||
|             float:left; | ||||
|             width:30%; | ||||
|             width: 30%; | ||||
|             text-transform: capitalize; | ||||
|             margin-bottom: 2px; | ||||
|         } | ||||
|  | ||||
|         .company h1 { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|         .company-address-container { | ||||
|             padding-left: 30px; | ||||
|             float: left; | ||||
|             width: 30%; | ||||
|             text-transform: capitalize; | ||||
|             margin-bottom: 2px; | ||||
|         } | ||||
|  | ||||
|         .company-address-container h1 { | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             letter-spacing: 0.05em; | ||||
|             margin-bottom: 0px; | ||||
|             margin-top: 10px; | ||||
|         } | ||||
|  | ||||
|         .company-add { | ||||
|         .company-address { | ||||
|             margin-top: 2px; | ||||
|             text-align: left; | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 12px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
|         } | ||||
|  | ||||
|         .job-add { | ||||
|             /* display: inline; */ | ||||
|         .estimate-details-container { | ||||
|             float: right; | ||||
|             padding: 10px 30px 0 0; | ||||
|         } | ||||
|         .amount-due { | ||||
|             background-color: #f2f2f2; | ||||
|         } | ||||
|  | ||||
|         .textRight { | ||||
|             text-align: right; | ||||
|         } | ||||
|  | ||||
|         .textLeft { | ||||
|             text-align: left; | ||||
|         } | ||||
|  | ||||
|         .textStyle1 { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|         .attribute-label { | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|             padding-right: 40px; | ||||
|             text-align: left; | ||||
|             color: #55547A | ||||
|         } | ||||
|  | ||||
|         .textStyle2 { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|         .attribute-value { | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|             text-align: right; | ||||
|         } | ||||
|         .bill-add { | ||||
|             width:45%; | ||||
|  | ||||
|         /* -- Customer Address -- */ | ||||
|  | ||||
|         .customer-address-container { | ||||
|             width: 45%; | ||||
|             padding: 0px 0 0 0px; | ||||
|         } | ||||
|  | ||||
|         /* -------------------------- */ | ||||
|         /* shipping style */ | ||||
|         /* -- Shipping -- */ | ||||
|  | ||||
|         .ship-address-container { | ||||
|         .shipping-address-container { | ||||
|             float: right; | ||||
|             padding-left: 30px; | ||||
|         } | ||||
|  | ||||
|         .ship-to { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|         .shipping-address-container--left { | ||||
|             float: left; | ||||
|             padding-left: 0px; | ||||
|         } | ||||
|  | ||||
|         .shipping-address-label { | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|             padding: 0px; | ||||
| @ -174,18 +148,15 @@ | ||||
|             margin-bottom: 0px; | ||||
|         } | ||||
|  | ||||
|         .ship-user-name { | ||||
|             max-width: 250px | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|         .shipping-address-name { | ||||
|             max-width: 160px; | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             padding: 0px; | ||||
|             margin: 0px; | ||||
|         } | ||||
|         .ship-user-address { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|  | ||||
|         .shipping-address { | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
| @ -193,27 +164,15 @@ | ||||
|             margin: 0px; | ||||
|             width: 160px; | ||||
|         } | ||||
|         .ship-user-phone { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
|             padding: 0px; | ||||
|             margin: 0px; | ||||
|         } | ||||
|  | ||||
|         /* -------------------------- */ | ||||
|         /* billing style */ | ||||
|         /* -- Billing -- */ | ||||
|  | ||||
|         .bill-address-container { | ||||
|         .billing-address-container { | ||||
|             float: left; | ||||
|             padding-left: 30px; | ||||
|         } | ||||
|  | ||||
|         .bill-to { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|         .billing-address-label { | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|             padding: 0px; | ||||
| @ -221,19 +180,15 @@ | ||||
|             margin-bottom: 0px; | ||||
|         } | ||||
|  | ||||
|         .bill-user-name { | ||||
|             max-width: 250px | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|         .billing-address-name { | ||||
|             max-width: 160px; | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             padding: 0px; | ||||
|             margin: 0px; | ||||
|         } | ||||
|  | ||||
|         .bill-user-address { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|         .billing-address { | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
| @ -242,28 +197,20 @@ | ||||
|             width: 160px; | ||||
|         } | ||||
|  | ||||
|         .bill-user-phone { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
|             padding: 0px; | ||||
|             margin: 0px; | ||||
|         } | ||||
|         /* -- Items Table -- */ | ||||
|  | ||||
|         .table2 { | ||||
|         .items-table { | ||||
|             margin-top: 35px; | ||||
|             padding: 0px 30px 10px 30px; | ||||
|             page-break-before: avoid; | ||||
|             page-break-after: auto; | ||||
|         } | ||||
|  | ||||
|         .table2 hr { | ||||
|             height:0.1px; | ||||
|         .items-table hr { | ||||
|             height: 0.1px; | ||||
|         } | ||||
|  | ||||
|         .ItemTableHeader { | ||||
|         .item-table-heading { | ||||
|             font-size: 13.5; | ||||
|             text-align: center; | ||||
|             color: rgba(0, 0, 0, 0.85); | ||||
| @ -271,85 +218,86 @@ | ||||
|             padding-bottom: 10px; | ||||
|         } | ||||
|  | ||||
|         tr.main-table-header th { | ||||
|         tr.item-table-heading-row th { | ||||
|             border-bottom: 0.620315px solid #E8E8E8; | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|         } | ||||
|  | ||||
|         .main-table-header { | ||||
|         .item-table-heading-row { | ||||
|             margin-bottom: 10px; | ||||
|         } | ||||
|  | ||||
|         tr.item-details td { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|         tr.item-row td { | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|         } | ||||
|  | ||||
|         .items { | ||||
|         .item-cell { | ||||
|             font-size: 13; | ||||
|             color: rgba(0, 0, 0, 0.6); | ||||
|             color: #040405; | ||||
|             text-align: center; | ||||
|             padding: 5px; | ||||
|             padding-top: 10px; | ||||
|         } | ||||
|  | ||||
|         .padd8 { | ||||
|             padding-top: 8px; | ||||
|             padding-bottom: 8px; | ||||
|         } | ||||
|  | ||||
|         .padd2 { | ||||
|             padding-top: 2px; | ||||
|             padding-bottom: 2px; | ||||
|         } | ||||
|         .table3 { | ||||
|             border-top: none; | ||||
|             box-sizing: border-box; | ||||
|             width: 630px; | ||||
|             page-break-inside: avoid; | ||||
|             page-break-before: auto; | ||||
|             page-break-after: auto; | ||||
|  | ||||
|         } | ||||
|  | ||||
|         .total-border-left { | ||||
|             border: 1px solid #E8E8E8!important; | ||||
|             border-right: 0px !important; | ||||
|             padding-top: 0px; | ||||
|             padding:8px !important; | ||||
|         } | ||||
|         .total-border-right { | ||||
|             border: 1px solid #E8E8E8!important; | ||||
|             border-left: 0px !important; | ||||
|             padding-top: 0px; | ||||
|             padding:8px !important; | ||||
|  | ||||
|         } | ||||
|         .inv-item { | ||||
|             border-color: #d9d9d9; | ||||
|         } | ||||
|  | ||||
|         .no-border { | ||||
|             border: none; | ||||
|         .item-description { | ||||
|             color: #595959; | ||||
|             font-size: 9px; | ||||
|             line-height: 12px; | ||||
|         } | ||||
|  | ||||
|         .desc { | ||||
|             font-weight: 100; | ||||
|             text-align: justify; | ||||
|             font-size: 10px; | ||||
|             margin-bottom: 15px; | ||||
|             margin-top:7px; | ||||
|             color:rgba(0, 0, 0, 0.85); | ||||
|         /* -- Total Display Table -- */ | ||||
|  | ||||
|         .total-display-container { | ||||
|             padding: 0 25px; | ||||
|         } | ||||
|  | ||||
|         .total-display-table { | ||||
|             border-top: none; | ||||
|             box-sizing: border-box; | ||||
|             page-break-inside: avoid; | ||||
|             page-break-before: auto; | ||||
|             page-break-after: auto; | ||||
|             margin-left: 500px; | ||||
|             margin-top: 20px; | ||||
|         } | ||||
|  | ||||
|         .total-table-attribute-label { | ||||
|             font-size: 12px; | ||||
|             color: #55547A; | ||||
|             text-align: left; | ||||
|             padding-left: 10px; | ||||
|         } | ||||
|  | ||||
|         .total-table-attribute-value { | ||||
|             font-weight: bold; | ||||
|             text-align: right; | ||||
|             font-size: 12px; | ||||
|             color: #040405; | ||||
|             padding-right: 10px; | ||||
|             padding-top: 2px; | ||||
|             padding-bottom: 2px; | ||||
|         } | ||||
|  | ||||
|         .total-border-left { | ||||
|             border: 1px solid #E8E8E8 !important; | ||||
|             border-right: 0px !important; | ||||
|             padding-top: 0px; | ||||
|             padding: 8px !important; | ||||
|         } | ||||
|  | ||||
|         .total-border-right { | ||||
|             border: 1px solid #E8E8E8 !important; | ||||
|             border-left: 0px !important; | ||||
|             padding-top: 0px; | ||||
|             padding: 8px !important; | ||||
|         } | ||||
|  | ||||
|         /* -- Notes -- */ | ||||
|  | ||||
|         .notes { | ||||
|             font-style: normal; | ||||
|             font-weight: 300; | ||||
|             font-size: 12px; | ||||
|             color: #595959; | ||||
|             margin-top: 15px; | ||||
| @ -360,8 +308,6 @@ | ||||
|         } | ||||
|  | ||||
|         .notes-label { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             letter-spacing: 0.05em; | ||||
| @ -371,65 +317,122 @@ | ||||
|             padding-bottom: 10px; | ||||
|         } | ||||
|  | ||||
|         /* -- Helpers -- */ | ||||
|  | ||||
|         .text-primary { | ||||
|             color: #5851DB; | ||||
|         } | ||||
|  | ||||
|         .text-center { | ||||
|             text-align: center | ||||
|         } | ||||
|  | ||||
|         table .text-left { | ||||
|             text-align: left; | ||||
|         } | ||||
|  | ||||
|         table .text-right { | ||||
|             text-align: right; | ||||
|         } | ||||
|  | ||||
|         .border-0 { | ||||
|             border: none; | ||||
|         } | ||||
|  | ||||
|         .py-2 { | ||||
|             padding-top: 2px; | ||||
|             padding-bottom: 2px; | ||||
|         } | ||||
|  | ||||
|         .py-8 { | ||||
|             padding-top: 8px; | ||||
|             padding-bottom: 8px; | ||||
|         } | ||||
|  | ||||
|         .py-3 { | ||||
|             padding: 3px 0; | ||||
|         } | ||||
|  | ||||
|         .pr-20 { | ||||
|             padding-right: 20px; | ||||
|         } | ||||
|  | ||||
|         .pr-10 { | ||||
|             padding-right: 10px; | ||||
|         } | ||||
|  | ||||
|         .pl-20 { | ||||
|             padding-left: 20px; | ||||
|         } | ||||
|  | ||||
|         .pl-10 { | ||||
|             padding-left: 10px; | ||||
|         } | ||||
|  | ||||
|         .pl-0 { | ||||
|             padding-left: 0; | ||||
|         } | ||||
|     </style> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
|     <div class="header-table"> | ||||
|     <div class="header-container"> | ||||
|         <table width="100%"> | ||||
|             <tr> | ||||
|                 <td class="header-center"> | ||||
|                 <td class="text-center"> | ||||
|                     @if($logo) | ||||
|                         <img class="header-logo" src="{{ $logo }}" alt="Company Logo"> | ||||
|                     <img class="header-logo" src="{{ $logo }}" alt="Company Logo"> | ||||
|                     @else | ||||
|                         @if($estimate->user->company) | ||||
|                         <h2 class="header-logo"> {{$estimate->user->company->name}} </h2> | ||||
|                         @endif | ||||
|                     @if($estimate->user->company) | ||||
|                     <h2 class="header-logo"> {{$estimate->user->company->name}} </h2> | ||||
|                     @endif | ||||
|                     @endif | ||||
|                 </td> | ||||
|             </tr> | ||||
|         </table> | ||||
|         <hr class="header-line" /> | ||||
|         <hr class="header-bottom-divider" /> | ||||
|     </div> | ||||
|     <div class="wrapper"> | ||||
|         <div class="address"> | ||||
|             <div class="company"> | ||||
|         <div class="company-details-container"> | ||||
|             <div class="company-address-container"> | ||||
|                 @include('app.pdf.estimate.partials.company-address') | ||||
|             </div> | ||||
|             <div class="job-add"> | ||||
|                 <table> | ||||
|             <div class="estimate-details-container"> | ||||
|                 <table class="estimate-details-table"> | ||||
|                     <tr> | ||||
|                         <td class="textStyle1" style="text-align: left; color: #55547A">Estimate Number</td> | ||||
|                         <td class="textStyle2">  {{$estimate->estimate_number}}</td> | ||||
|                         <td class="attribute-label">Estimate Number</td> | ||||
|                         <td class="attribute-value">  {{$estimate->estimate_number}}</td> | ||||
|                     </tr> | ||||
|                     <tr> | ||||
|                         <td class="textStyle1" style="text-align: left; color: #55547A">Estimate Date </td> | ||||
|                         <td class="textStyle2">  {{$estimate->formattedEstimateDate}}</td> | ||||
|                         <td class="attribute-label">Estimate Date </td> | ||||
|                         <td class="attribute-value">  {{$estimate->formattedEstimateDate}}</td> | ||||
|                     </tr> | ||||
|                     <tr> | ||||
|                         <td class="textStyle1" style="text-align: left; color: #55547A">Expiry Date</td> | ||||
|                         <td class="textStyle2">  {{$estimate->formattedExpiryDate}}</td> | ||||
|                         <td class="attribute-label">Expiry Date</td> | ||||
|                         <td class="attribute-value">  {{$estimate->formattedExpiryDate}}</td> | ||||
|                     </tr> | ||||
|                 </table> | ||||
|             </div> | ||||
|             <div style="clear: both;"></div> | ||||
|         </div> | ||||
|         <div class="bill-add"> | ||||
|             <div class="bill-address-container"> | ||||
|         <div class="customer-address-container"> | ||||
|             <div class="billing-address-container"> | ||||
|                 @include('app.pdf.estimate.partials.billing-address') | ||||
|             </div> | ||||
|             @if($estimate->user->billingaddress) | ||||
|                 <div class="ship-address-container"> | ||||
|             <div class="shipping-address-container"> | ||||
|             @else | ||||
|                 <div class="ship-address-container " style="float:left;padding-left:0px;"> | ||||
|             <div class="shipping-address-container--left"> | ||||
|             @endif | ||||
|                 @include('app.pdf.estimate.partials.shipping-address') | ||||
|             @include('app.pdf.estimate.partials.shipping-address') | ||||
|             </div> | ||||
|             <div style="clear: both;"></div> | ||||
|             </div> | ||||
|             <div style="position:relative"> | ||||
|                 @include('app.pdf.estimate.partials.table') | ||||
|             </div> | ||||
|             @include('app.pdf.estimate.partials.notes') | ||||
|         </div> | ||||
|         <div style="position:relative"> | ||||
|             @include('app.pdf.estimate.partials.table') | ||||
|         </div> | ||||
|         @include('app.pdf.estimate.partials.notes') | ||||
|     </div> | ||||
| </body> | ||||
|  | ||||
| </html> | ||||
|  | ||||
| @ -1,9 +1,11 @@ | ||||
| <!DOCTYPE html> | ||||
| <html> | ||||
|  | ||||
| <head> | ||||
|     <title>Estimate</title> | ||||
|     <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> | ||||
|     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | ||||
|     <style type="text/css"> | ||||
|         /* -- Base -- */ | ||||
|         body { | ||||
|             font-family: "DejaVu Sans"; | ||||
|         } | ||||
| @ -11,22 +13,21 @@ | ||||
|         html { | ||||
|             margin: 0px; | ||||
|             padding: 0px; | ||||
|             margin-top: 50px; | ||||
|         } | ||||
|  | ||||
|         table { | ||||
|             border-collapse: collapse; | ||||
|         } | ||||
|  | ||||
|         .header-left { | ||||
|             padding-top: 45px; | ||||
|             padding-bottom: 45px; | ||||
|             padding-left: 30px; | ||||
|             display:inline-block; | ||||
|             width:30%; | ||||
|         hr { | ||||
|             color: rgba(0, 0, 0, 0.2); | ||||
|             border: 0.5px solid #EAF1FB; | ||||
|         } | ||||
|         @page { | ||||
|             margin-top: 60px !important; | ||||
|         } | ||||
|         .header-table { | ||||
|  | ||||
|         /* -- Header -- */ | ||||
|  | ||||
|         .header-container { | ||||
|             background: #817AE3; | ||||
|             position: absolute; | ||||
|             width: 100%; | ||||
| @ -34,351 +35,286 @@ | ||||
|             left: 0px; | ||||
|             top: -60px; | ||||
|         } | ||||
|  | ||||
|         .header-section-left { | ||||
|             padding-top: 45px; | ||||
|             padding-bottom: 45px; | ||||
|             padding-left: 30px; | ||||
|             display: inline-block; | ||||
|             width: 30%; | ||||
|         } | ||||
|  | ||||
|         .header-logo { | ||||
|             position: absolute; | ||||
|             height: 50px; | ||||
|             text-transform: capitalize; | ||||
|             color: #fff; | ||||
|         } | ||||
|         .header-right { | ||||
|             display:inline-block; | ||||
|             width:35%; | ||||
|             float:right; | ||||
|  | ||||
|         .header-section-right { | ||||
|             display: inline-block; | ||||
|             width: 35%; | ||||
|             float: right; | ||||
|             padding: 20px 30px 20px 0px; | ||||
|             text-align: right; | ||||
|             color:white; | ||||
|             color: white; | ||||
|         } | ||||
|  | ||||
|         } | ||||
|         .inv-flex{ | ||||
|             display:flex; | ||||
|         } | ||||
|         .inv-data{ | ||||
|             text-align:right; | ||||
|             margin-right:120px; | ||||
|         } | ||||
|         .inv-value{ | ||||
|             text-align:left; | ||||
|             margin-left:160px; | ||||
|         } | ||||
|         .header { | ||||
|             font-size: 20px; | ||||
|             color: rgba(0, 0, 0, 0.7); | ||||
|         } | ||||
|  | ||||
|         .TextColor1 { | ||||
|             font-size: 16px; | ||||
|             color: rgba(0, 0, 0, 0.5); | ||||
|         /* -- Estimate Details -- */ | ||||
|  | ||||
|         .estimate-details-container { | ||||
|             text-align: center; | ||||
|             width: 40%; | ||||
|         } | ||||
|  | ||||
|         .wrapper { | ||||
|            display: block; | ||||
|            margin-top: 60px; | ||||
|            padding-bottom: 20px; | ||||
|         .estimate-details-container h1 { | ||||
|             margin: 0; | ||||
|             font-size: 24px; | ||||
|             line-height: 36px; | ||||
|             text-align: right; | ||||
|             font-family: "DejaVu Sans"; | ||||
|         } | ||||
|  | ||||
|         .address { | ||||
|             display: block; | ||||
|             padding-top: 20px; | ||||
|         } | ||||
|         .company { | ||||
|             padding: 0 0 0 30px; | ||||
|             display: inline; | ||||
|             float:left; | ||||
|             width:30%; | ||||
|         } | ||||
|  | ||||
|         .company h1 { | ||||
|             font-style: normal; | ||||
|             font-weight: bold; | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             letter-spacing: 0.05em; | ||||
|             margin-bottom: 0; | ||||
|         } | ||||
|  | ||||
|         .company-add { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|         .estimate-details-container h4 { | ||||
|             margin: 0; | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
|             margin-top: 0px; | ||||
|         } | ||||
|  | ||||
|         /* -------------------------- */ | ||||
|         /* billing style */ | ||||
|         .bill-address-container { | ||||
|             display: block; | ||||
|             /* position: absolute; */ | ||||
|             float:right; | ||||
|             padding: 0 40px 0 0; | ||||
|         } | ||||
|  | ||||
|         .bill-to { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|             padding: 0px; | ||||
|             margin-bottom: 0px; | ||||
|         } | ||||
|  | ||||
|         .bill-user-name { | ||||
|             max-width: 250px | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             padding: 0px; | ||||
|             margin-top: 0px; | ||||
|             margin-bottom: 0px; | ||||
|         } | ||||
|  | ||||
|         .bill-user-address { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
|             padding: 0px; | ||||
|             margin: 0px; | ||||
|             width: 170px; | ||||
|         } | ||||
|         .bill-user-phone { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
|             padding: 0px; | ||||
|             margin: 0px; | ||||
|         } | ||||
|  | ||||
|         /* -------------------------- */ | ||||
|         /* shipping style */ | ||||
|         .ship-address-container { | ||||
|             display: block; | ||||
|             float:right; | ||||
|             padding: 0 30px 0 0; | ||||
|         } | ||||
|  | ||||
|         .ship-to { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|             padding: 0px; | ||||
|             margin-bottom: 0px; | ||||
|         } | ||||
|  | ||||
|         .ship-user-name { | ||||
|             max-width: 250px | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             padding: 0px; | ||||
|             margin-top: 0px; | ||||
|             margin-bottom: 0px; | ||||
|         } | ||||
|  | ||||
|         .ship-user-address { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
|             padding: 0px; | ||||
|             margin: 0px; | ||||
|             width: 170px; | ||||
|         } | ||||
|  | ||||
|         .ship-user-phone { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
|             padding: 0px; | ||||
|             margin: 0px; | ||||
|         } | ||||
|  | ||||
|         .job-add { | ||||
|             display: inline; | ||||
|             float: right; | ||||
|             width:40%; | ||||
|         } | ||||
|  | ||||
|         .amount-due { | ||||
|             background-color: #f2f2f2; | ||||
|         } | ||||
|  | ||||
|         .textRight { | ||||
|             text-align: right; | ||||
|         } | ||||
|  | ||||
|         .textLeft { | ||||
|             text-align: left; | ||||
|         .estimate-details-container h3 { | ||||
|             margin-bottom: 1px; | ||||
|             margin-top: 0; | ||||
|         } | ||||
|  | ||||
|         .textStyle1 { | ||||
|         /* -- Address -- */ | ||||
|  | ||||
|         .wrapper { | ||||
|             display: block; | ||||
|             margin-top: 60px; | ||||
|             padding-bottom: 20px; | ||||
|         } | ||||
|  | ||||
|         .address-container { | ||||
|             display: block; | ||||
|             padding-top: 20px; | ||||
|         } | ||||
|  | ||||
|         /* -- Company Address -- */ | ||||
|  | ||||
|         .company-address-container { | ||||
|             padding: 0 0 0 30px; | ||||
|             display: inline; | ||||
|             float: left; | ||||
|             width: 30%; | ||||
|         } | ||||
|  | ||||
|         .company-address-container { | ||||
|             padding-left: 30px; | ||||
|             float: left; | ||||
|             width: 30%; | ||||
|             text-transform: capitalize; | ||||
|             margin-bottom: 2px; | ||||
|         } | ||||
|  | ||||
|         .company-address-container h1 { | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             letter-spacing: 0.05em; | ||||
|             margin-bottom: 0px; | ||||
|             margin-top: 10px; | ||||
|         } | ||||
|  | ||||
|         .company-address { | ||||
|             margin-top: 2px; | ||||
|             text-align: left; | ||||
|  | ||||
|  | ||||
|             font-size: 12px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
|         } | ||||
|  | ||||
|         /* -- Billing -- */ | ||||
|  | ||||
|         .billing-address-container { | ||||
|             display: block; | ||||
|             /* position: absolute; */ | ||||
|             float: right; | ||||
|             padding: 0 40px 0 0; | ||||
|         } | ||||
|  | ||||
|         .billing-address-label { | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|             padding: 0px; | ||||
|             margin-bottom: 0px; | ||||
|         } | ||||
|  | ||||
|         .billing-address-name { | ||||
|             max-width: 160px; | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             padding: 0px; | ||||
|             margin-top: 0px; | ||||
|             margin-bottom: 0px; | ||||
|         } | ||||
|  | ||||
|         .billing-address { | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
|             padding: 0px; | ||||
|             margin: 0px; | ||||
|             width: 170px; | ||||
|         } | ||||
|  | ||||
|         /* -- Shipping -- */ | ||||
|  | ||||
|         .shipping-address-container { | ||||
|             display: block; | ||||
|             float: right; | ||||
|             padding: 0 30px 0 0; | ||||
|         } | ||||
|  | ||||
|         .shipping-address-label { | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|             padding: 0px; | ||||
|             margin-bottom: 0px; | ||||
|         } | ||||
|  | ||||
|         .shipping-address-name { | ||||
|             max-width: 160px; | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             padding: 0px; | ||||
|             margin-top: 0px; | ||||
|             margin-bottom: 0px; | ||||
|         } | ||||
|  | ||||
|         .shipping-address { | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
|             padding: 0px; | ||||
|             margin: 0px; | ||||
|             width: 170px; | ||||
|         } | ||||
|  | ||||
|         .attribute-label { | ||||
|             font-size: 12; | ||||
|             font-weight: bold; | ||||
|             line-height:22px; | ||||
|             line-height: 22px; | ||||
|             color: rgba(0, 0, 0, 0.8); | ||||
|         } | ||||
|  | ||||
|         .textStyle2 { | ||||
|         .attribute-value { | ||||
|             font-size: 12; | ||||
|             line-height:22px; | ||||
|             line-height: 22px; | ||||
|             color: rgba(0, 0, 0, 0.7); | ||||
|         } | ||||
|  | ||||
|         .main-table-header td { | ||||
|             padding: 5px; | ||||
|             padding-bottom: 10px; | ||||
|         } | ||||
|         /* -- Items Table -- */ | ||||
|  | ||||
|         .main-table-header { | ||||
|             border-bottom: 1px solid red; | ||||
|         } | ||||
|  | ||||
|         .table2 { | ||||
|             margin-top: 30px; | ||||
|             padding: 0px 30px 10px 30px; | ||||
|         .items-table { | ||||
|             padding: 30px 30px 10px 30px; | ||||
|             page-break-before: avoid; | ||||
|             page-break-after: auto; | ||||
|         } | ||||
|  | ||||
|         hr { | ||||
|             margin: 0 30px 0 30px; | ||||
|             color:rgba(0, 0, 0, 0.2); | ||||
|             border: 0.5px solid #EAF1FB; | ||||
|         .items-table hr { | ||||
|             height: 0.1px; | ||||
|             margin: 0 30px; | ||||
|         } | ||||
|  | ||||
|         .table2 hr { | ||||
|             height:0.1px; | ||||
|         } | ||||
|  | ||||
|         .ItemTableHeader { | ||||
|         .item-table-heading { | ||||
|             font-size: 13.5; | ||||
|             text-align: center; | ||||
|             color: rgba(0, 0, 0, 0.85); | ||||
|             padding: 5px; | ||||
|         } | ||||
|  | ||||
|         tr.main-table-header th { | ||||
|         .item-table-heading-row td { | ||||
|             padding: 5px; | ||||
|             padding-bottom: 10px; | ||||
|         } | ||||
|  | ||||
|         .item-table-heading-row { | ||||
|             border-bottom: 1px solid red; | ||||
|         } | ||||
|  | ||||
|         tr.item-table-heading-row th { | ||||
|             border-bottom: 0.620315px solid #E8E8E8; | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|         } | ||||
|  | ||||
|         tr.item-details td { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|         tr.item-row td { | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|         } | ||||
|  | ||||
|         .items { | ||||
|         .item-cell { | ||||
|             font-size: 13; | ||||
|             color: rgba(0, 0, 0, 0.6); | ||||
|             color: #040405; | ||||
|             text-align: center; | ||||
|             padding: 5px; | ||||
|             padding-top: 10px; | ||||
|         } | ||||
|  | ||||
|         .note-header { | ||||
|             font-size: 13; | ||||
|             color: rgba(0, 0, 0, 0.6); | ||||
|         .item-description { | ||||
|             color: #595959; | ||||
|             font-size: 9px; | ||||
|             line-height: 12px; | ||||
|             page-break-inside: avoid; | ||||
|         } | ||||
|  | ||||
|         .note-text { | ||||
|             font-size: 10; | ||||
|             color: rgba(0, 0, 0, 0.6); | ||||
|         /* -- Total Display Table -- */ | ||||
|  | ||||
|         .total-display-container { | ||||
|             padding: 0 25px; | ||||
|         } | ||||
|  | ||||
|         .padd8 { | ||||
|             padding-top: 8px; | ||||
|             padding-bottom: 8px; | ||||
|         .item-cell-table-hr { | ||||
|             margin: 0 25px 0 30px; | ||||
|         } | ||||
|  | ||||
|         .padd2 { | ||||
|         .total-display-table { | ||||
|             box-sizing: border-box; | ||||
|             page-break-inside: avoid; | ||||
|             page-break-before: auto; | ||||
|             page-break-after: auto; | ||||
|             margin-left: 500px; | ||||
|             border: 1px solid #EAF1FB; | ||||
|             border-top: none; | ||||
|         } | ||||
|  | ||||
|         .total-table-attribute-label { | ||||
|             font-size: 12px; | ||||
|             color: #55547A; | ||||
|             text-align: left; | ||||
|             padding-left: 10px; | ||||
|         } | ||||
|  | ||||
|         .total-table-attribute-value { | ||||
|             font-weight: bold; | ||||
|             text-align: right; | ||||
|             font-size: 12px; | ||||
|             color: #040405; | ||||
|             padding-right: 10px; | ||||
|             padding-top: 2px; | ||||
|             padding-bottom: 2px; | ||||
|         } | ||||
|  | ||||
|         .table3 { | ||||
|             border: 1px solid #EAF1FB; | ||||
|             border-top: none; | ||||
|             box-sizing: border-box; | ||||
|             width: 630px; | ||||
|             page-break-inside: avoid; | ||||
|             page-break-before: auto; | ||||
|             page-break-after: auto; | ||||
|         } | ||||
|  | ||||
|         .text-per-item-table3 { | ||||
|             border: 1px solid #EAF1FB; | ||||
|             border-top: none; | ||||
|             padding-right: 30px; | ||||
|             box-sizing: border-box; | ||||
|             width: 260px; | ||||
|             /* height: 100px; */ | ||||
|             position: absolute; | ||||
|             right: -25; | ||||
|         } | ||||
|  | ||||
|         .inv-item { | ||||
|             border-color: #d9d9d9; | ||||
|         } | ||||
|  | ||||
|         .no-border { | ||||
|             border: none; | ||||
|         } | ||||
|  | ||||
|         .desc { | ||||
|             font-weight: 100; | ||||
|             text-align: justify; | ||||
|             font-size: 10px; | ||||
|             margin-bottom: 15px; | ||||
|             margin-top:7px; | ||||
|             color:rgba(0, 0, 0, 0.85); | ||||
|         } | ||||
|  | ||||
|         .company-details{ | ||||
|             text-align: center; | ||||
|             width: 40%; | ||||
|         } | ||||
|  | ||||
|         .company-details h1 { | ||||
|             margin:0; | ||||
|             font-style: normal; | ||||
|             font-weight: 500; | ||||
|             font-size: 24px; | ||||
|             line-height: 36px; | ||||
|             text-align: right; | ||||
|         } | ||||
|  | ||||
|         .company-details h4 { | ||||
|             margin:0; | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             text-align: right; | ||||
|         } | ||||
|  | ||||
|         .company-details h3 { | ||||
|              margin-bottom:1px; | ||||
|              margin-top:0; | ||||
|         } | ||||
|         /* -- Notes -- */ | ||||
|  | ||||
|         .notes { | ||||
|             font-style: normal; | ||||
|             font-weight: 300; | ||||
|             font-size: 12px; | ||||
|             color: #595959; | ||||
|             margin-top: 15px; | ||||
| @ -389,8 +325,6 @@ | ||||
|         } | ||||
|  | ||||
|         .notes-label { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             letter-spacing: 0.05em; | ||||
| @ -400,23 +334,79 @@ | ||||
|             padding-bottom: 10px; | ||||
|         } | ||||
|  | ||||
|         /* -- Helpers -- */ | ||||
|  | ||||
|         .text-primary { | ||||
|             color: #5851DB; | ||||
|         } | ||||
|  | ||||
|         .text-center { | ||||
|             text-align: center | ||||
|         } | ||||
|  | ||||
|         table .text-left { | ||||
|             text-align: left; | ||||
|         } | ||||
|  | ||||
|         table .text-right { | ||||
|             text-align: right; | ||||
|         } | ||||
|  | ||||
|         .border-0 { | ||||
|             border: none; | ||||
|         } | ||||
|  | ||||
|         .py-2 { | ||||
|             padding-top: 2px; | ||||
|             padding-bottom: 2px; | ||||
|         } | ||||
|  | ||||
|         .py-8 { | ||||
|             padding-top: 8px; | ||||
|             padding-bottom: 8px; | ||||
|         } | ||||
|  | ||||
|         .py-3 { | ||||
|             padding: 3px 0; | ||||
|         } | ||||
|  | ||||
|         .pr-20 { | ||||
|             padding-right: 20px; | ||||
|         } | ||||
|  | ||||
|         .pr-10 { | ||||
|             padding-right: 10px; | ||||
|         } | ||||
|  | ||||
|         .pl-20 { | ||||
|             padding-left: 20px; | ||||
|         } | ||||
|  | ||||
|         .pl-10 { | ||||
|             padding-left: 10px; | ||||
|         } | ||||
|  | ||||
|         .pl-0 { | ||||
|             padding-left: 0; | ||||
|         } | ||||
|     </style> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
|     <div class="header-table"> | ||||
|     <div class="header-container"> | ||||
|         <table width="100%"> | ||||
|             <tr> | ||||
|                 @if($logo) | ||||
|                     <td width="60%" class="header-left"> | ||||
|                         <img class="header-logo" src="{{ $logo }}" alt="Company Logo"> | ||||
|                 @else | ||||
|                     <td width="60%" class="header-left" style="padding-top: 0px;"> | ||||
|                         @if($estimate->user->company) | ||||
|                             <h1 class="header-logo"> {{$estimate->user->company->name}} </h1> | ||||
|                         @endif | ||||
|                 @endif | ||||
|                 <td width="60%" class="header-section-left"> | ||||
|                     <img class="header-logo" src="{{ $logo }}" alt="Company Logo"> | ||||
|                     @else | ||||
|                 <td width="60%" class="header-section-left" style="padding-top: 0px;"> | ||||
|                     @if($estimate->user->company) | ||||
|                     <h1 class="header-logo"> {{$estimate->user->company->name}} </h1> | ||||
|                     @endif | ||||
|                     @endif | ||||
|                 </td> | ||||
|                 <td width="40%" class="header-right company-details"> | ||||
|                 <td width="40%" class="header-section-right estimate-details-container"> | ||||
|                     <h1>Estimate</h1> | ||||
|                     <h4>{{$estimate->estimate_number}}</h4> | ||||
|                     <h4>{{$estimate->formattedEstimateDate}}</h4> | ||||
| @ -426,24 +416,24 @@ | ||||
|     </div> | ||||
|     <hr> | ||||
|     <div class="wrapper"> | ||||
|         <div class="address"> | ||||
|             <div class="company"> | ||||
|         <div class="address-container"> | ||||
|             <div class="company-address-container"> | ||||
|                 @include('app.pdf.estimate.partials.company-address') | ||||
|             </div> | ||||
|             <div class="ship-address-container"> | ||||
|             <div class="shipping-address-container"> | ||||
|                 @include('app.pdf.estimate.partials.shipping-address') | ||||
|             </div> | ||||
|             @if($estimate->user->shippingaddress) | ||||
|                 <div class="bill-address-container"> | ||||
|             <div class="billing-address-container"> | ||||
|             @else | ||||
|                 <div class="bill-address-container" style="float:right;padding-right:0px;"> | ||||
|             <div class="billing-address-container" style="float:right; padding-right:0px;"> | ||||
|             @endif | ||||
|                 @include('app.pdf.estimate.partials.billing-address') | ||||
|             </div> | ||||
|             <div style="clear: both;"></div> | ||||
|             @include('app.pdf.estimate.partials.table') | ||||
|             @include('app.pdf.estimate.partials.notes') | ||||
|         </div> | ||||
|         @include('app.pdf.estimate.partials.table') | ||||
|         @include('app.pdf.estimate.partials.notes') | ||||
|     </div> | ||||
| </body> | ||||
|  | ||||
| </html> | ||||
|  | ||||
| @ -1,10 +1,12 @@ | ||||
| <!DOCTYPE html> | ||||
| <html> | ||||
|  | ||||
| <head> | ||||
|     <title>Estimate</title> | ||||
|     <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> | ||||
|     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | ||||
|  | ||||
|     <style type="text/css"> | ||||
|         /* -- Base -- */ | ||||
|         body { | ||||
|             font-family: "DejaVu Sans"; | ||||
|         } | ||||
| @ -12,147 +14,138 @@ | ||||
|         html { | ||||
|             margin: 0px; | ||||
|             padding: 0px; | ||||
|             margin-top: 50px; | ||||
|         } | ||||
|  | ||||
|         table { | ||||
|             border-collapse: collapse; | ||||
|         } | ||||
|  | ||||
|         .header-line { | ||||
|             color:rgba(0, 0, 0, 0.2); | ||||
|             position: absolute; | ||||
|             top: 80px; | ||||
|             left: 0px; | ||||
|             right: -70px; | ||||
|             width: 100%; | ||||
|         } | ||||
|  | ||||
|         hr { | ||||
|             color:rgba(0, 0, 0, 0.2); | ||||
|             color: rgba(0, 0, 0, 0.2); | ||||
|             border: 0.5px solid #EAF1FB; | ||||
|         } | ||||
|  | ||||
|         .items-table-hr{ | ||||
|             margin: 0 30px 0 30px; | ||||
|         } | ||||
|         /* -- Header -- */ | ||||
|  | ||||
|         .header-left { | ||||
|             padding-top: 45px; | ||||
|             padding-bottom: 45px; | ||||
|             padding-left: 30px; | ||||
|             display:inline-block; | ||||
|             width:30%; | ||||
|         } | ||||
|  | ||||
|         .header-table { | ||||
|         .header-container { | ||||
|             position: absolute; | ||||
|             width: 100%; | ||||
|             height: 150px; | ||||
|             left: 0px; | ||||
|             top: -60px; | ||||
|         } | ||||
|  | ||||
|         .header-section-left { | ||||
|             padding-top: 45px; | ||||
|             padding-bottom: 45px; | ||||
|             padding-left: 30px; | ||||
|             display: inline-block; | ||||
|             width: 30%; | ||||
|         } | ||||
|  | ||||
|         .header-bottom-divider { | ||||
|             color: rgba(0, 0, 0, 0.2); | ||||
|             position: absolute; | ||||
|             top: 100px; | ||||
|             left: 0px; | ||||
|             width: 100%; | ||||
|         } | ||||
|  | ||||
|         .header-logo { | ||||
|             position: absolute; | ||||
|             height: 50px; | ||||
|             text-transform: capitalize; | ||||
|             color: #817AE3; | ||||
|         } | ||||
|         .header-right { | ||||
|             display:inline-block; | ||||
|  | ||||
|         .header-section-right { | ||||
|             display: inline-block; | ||||
|             position: absolute; | ||||
|             right:0; | ||||
|             right: 0; | ||||
|             padding: 15px 30px 15px 0px; | ||||
|             float: right; | ||||
|         } | ||||
|         .inv-flex{ | ||||
|             display:flex; | ||||
|         } | ||||
|         .inv-data{ | ||||
|             text-align:right; | ||||
|             margin-right:120px; | ||||
|         } | ||||
|         .inv-value{ | ||||
|             text-align:left; | ||||
|             margin-left:160px; | ||||
|         } | ||||
|  | ||||
|         .header { | ||||
|             font-size: 20px; | ||||
|             color: rgba(0, 0, 0, 0.7); | ||||
|         } | ||||
|  | ||||
|         .TextColor1 { | ||||
|             font-size: 16px; | ||||
|             color: rgba(0, 0, 0, 0.5); | ||||
|         /* -- Company Address -- */ | ||||
|  | ||||
|         .company-address-container { | ||||
|             width: auto; | ||||
|             text-transform: capitalize; | ||||
|             margin-bottom: 2px; | ||||
|         } | ||||
|  | ||||
|         @page { | ||||
|             margin-top: 60px !important; | ||||
|         } | ||||
|         .company-address-container h1 { | ||||
|  | ||||
|         .wrapper { | ||||
|            display: block; | ||||
|            padding-top: 50px; | ||||
|            padding-bottom: 20px; | ||||
|         } | ||||
|  | ||||
|         .address { | ||||
|             display: inline-block; | ||||
|             padding-top: 100px | ||||
|         } | ||||
|  | ||||
|         .bill-add { | ||||
|             display: inline; | ||||
|             float:left; | ||||
|             width:40%; | ||||
|             padding: 0 0 0 30px; | ||||
|         } | ||||
|         .company { | ||||
|             padding-left: 30px; | ||||
|             display: inline; | ||||
|             float:left; | ||||
|             width:30%; | ||||
|         } | ||||
|  | ||||
|         .company h1 { | ||||
|             font-style: normal; | ||||
|             font-weight: bold; | ||||
|             font-size: 18px; | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             letter-spacing: 0.05em; | ||||
|             margin-bottom: 0px; | ||||
|             margin-top: 10px; | ||||
|         } | ||||
|  | ||||
|         .company-add { | ||||
|         .company-address { | ||||
|             margin-top: 2px; | ||||
|             text-align: left; | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 10px; | ||||
|  | ||||
|  | ||||
|             font-size: 12px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
|             margin: 0px; | ||||
|         } | ||||
|  | ||||
|          /* -------------------------- */ | ||||
|         /* shipping style */ | ||||
|         .ship-to { | ||||
|         /* -- Content Wrapper -- */ | ||||
|  | ||||
|         .wrapper { | ||||
|             display: block; | ||||
|             padding-top: 100px; | ||||
|             padding-bottom: 20px; | ||||
|         } | ||||
|  | ||||
|         .main-content { | ||||
|         } | ||||
|  | ||||
|         .customer-address-container { | ||||
|             display: inline; | ||||
|             float: left; | ||||
|             width: 40%; | ||||
|             padding: 0 0 0 30px; | ||||
|         } | ||||
|  | ||||
|         /* -- Shipping -- */ | ||||
|  | ||||
|         .shipping-address-container { | ||||
|             float: right; | ||||
|             display: block; | ||||
|         } | ||||
|  | ||||
|         .shipping-address-container--left { | ||||
|             float: left; | ||||
|             padding-left: 0; | ||||
|         } | ||||
|  | ||||
|         .shipping-address-label { | ||||
|             padding-top: 5px; | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|             margin-bottom: 0px; | ||||
|         } | ||||
|  | ||||
|         .ship-user-name { | ||||
|         .shipping-address-name { | ||||
|             padding: 0px; | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             margin: 0px; | ||||
|             max-width: 160px; | ||||
|         } | ||||
|  | ||||
|         .ship-user-address { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|         .shipping-address { | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
| @ -160,38 +153,28 @@ | ||||
|             width: 160px; | ||||
|         } | ||||
|  | ||||
|         .ship-user-phone { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
|             margin: 0px; | ||||
|         /* -- Billing -- */ | ||||
|  | ||||
|         .billing-address-container { | ||||
|             float: left; | ||||
|         } | ||||
|  | ||||
|          /* -------------------------- */ | ||||
|         /* billing style */ | ||||
|         .bill-to { | ||||
|         .billing-address-label { | ||||
|             padding-top: 5px; | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|             margin-bottom: 0px; | ||||
|         } | ||||
|  | ||||
|         .bill-user-name { | ||||
|         .billing-address-name { | ||||
|             padding: 0px; | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             margin: 0px; | ||||
|             max-width: 160px; | ||||
|         } | ||||
|  | ||||
|         .bill-user-address { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|         .billing-address { | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
| @ -199,187 +182,131 @@ | ||||
|             width: 160px; | ||||
|         } | ||||
|  | ||||
|         .bill-user-phone { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
|             margin: 0px; | ||||
|         } | ||||
|         /* -- Estimate Details -- */ | ||||
|  | ||||
|  | ||||
|         .job-add { | ||||
|         .estimate-details-container { | ||||
|             display: block; | ||||
|             float: right; | ||||
|             padding: 20px 30px 0 0; | ||||
|         } | ||||
|         .amount-due { | ||||
|             background-color: #f2f2f2; | ||||
|         } | ||||
|  | ||||
|         .textRight { | ||||
|             text-align: right; | ||||
|         } | ||||
|  | ||||
|         .textLeft { | ||||
|         .attribute-label { | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|             text-align: left; | ||||
|             color: #55547A | ||||
|         } | ||||
|  | ||||
|         .textStyle1 { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|         } | ||||
|  | ||||
|         .textStyle2 { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|         .attribute-value { | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|             text-align: right; | ||||
|         } | ||||
|         .main-table-header td { | ||||
|             padding: 10px; | ||||
|         } | ||||
|         .main-table-header { | ||||
|             border-bottom: 1px solid red; | ||||
|         } | ||||
|         tr.main-table-header th { | ||||
|             font-style: normal; | ||||
|             font-weight: 600; | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|         } | ||||
|         tr.item-details td { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|         } | ||||
|         .table2 { | ||||
|             padding: 0px 30px 10px 30px; | ||||
|  | ||||
|         /* -- Items Table -- */ | ||||
|  | ||||
|         .items-table { | ||||
|             padding: 30px 30px 10px 30px; | ||||
|             page-break-before: avoid; | ||||
|             page-break-after: auto; | ||||
|         } | ||||
|  | ||||
|         .table2 hr { | ||||
|             height:0.1px; | ||||
|         .items-table hr { | ||||
|             height: 0.1px; | ||||
|             margin: 0 30px; | ||||
|         } | ||||
|  | ||||
|         .ItemTableHeader { | ||||
|         .item-table-heading { | ||||
|             font-size: 13.5; | ||||
|             text-align: center; | ||||
|             color: rgba(0, 0, 0, 0.85); | ||||
|             padding: 5px; | ||||
|             padding-bottom: 10px; | ||||
|         } | ||||
|  | ||||
|         .items { | ||||
|         tr.item-table-heading-row th { | ||||
|             border-bottom: 0.620315px solid #E8E8E8; | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|         } | ||||
|  | ||||
|         .item-table-heading-row { | ||||
|             margin-bottom: 10px; | ||||
|         } | ||||
|  | ||||
|         tr.item-row td { | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|         } | ||||
|  | ||||
|         .item-cell { | ||||
|             font-size: 13; | ||||
|             color: rgba(0, 0, 0, 0.6); | ||||
|             color: #040405; | ||||
|             text-align: center; | ||||
|             padding: 5px; | ||||
|             padding-top: 10px; | ||||
|             border-color: #d9d9d9; | ||||
|         } | ||||
|  | ||||
|         .note-header { | ||||
|             font-size: 13; | ||||
|             color: rgba(0, 0, 0, 0.6); | ||||
|         .item-description { | ||||
|             color: #595959; | ||||
|             font-size: 9px; | ||||
|             line-height: 12px; | ||||
|         } | ||||
|  | ||||
|         .note-text { | ||||
|             font-size: 10; | ||||
|             color: rgba(0, 0, 0, 0.6); | ||||
|         .item-cell-table-hr { | ||||
|             margin: 0 30px 0 30px; | ||||
|         } | ||||
|  | ||||
|         .padd8 { | ||||
|             padding-top: 8px; | ||||
|             padding-bottom: 8px; | ||||
|         /* -- Total Display Table -- */ | ||||
|  | ||||
|         .total-display-container { | ||||
|             padding: 0 25px; | ||||
|         } | ||||
|  | ||||
|         .padd2 { | ||||
|         .total-display-table { | ||||
|             box-sizing: border-box; | ||||
|             page-break-inside: avoid; | ||||
|             page-break-before: auto; | ||||
|             page-break-after: auto; | ||||
|             margin-left: 500px; | ||||
|             margin-top: 20px; | ||||
|         } | ||||
|  | ||||
|         .total-table-attribute-label { | ||||
|             font-size: 12px; | ||||
|             color: #55547A; | ||||
|             text-align: left; | ||||
|             padding-left: 10px; | ||||
|         } | ||||
|  | ||||
|         .total-table-attribute-value { | ||||
|             font-weight: bold; | ||||
|             text-align: right; | ||||
|             font-size: 12px; | ||||
|             color: #040405; | ||||
|             padding-right: 10px; | ||||
|             padding-top: 2px; | ||||
|             padding-bottom: 2px; | ||||
|         } | ||||
|  | ||||
|         .table3 { | ||||
|              border: 1px solid #EAF1FB; | ||||
|              border-top: none; | ||||
|             box-sizing: border-box; | ||||
|             width: 630px; | ||||
|             page-break-inside: avoid; | ||||
|             page-break-before: auto; | ||||
|             page-break-after: auto; | ||||
|         .total-border-left { | ||||
|             border: 1px solid #E8E8E8 !important; | ||||
|             border-right: 0px !important; | ||||
|             padding-top: 0px; | ||||
|             padding: 8px !important; | ||||
|         } | ||||
|  | ||||
|         td.estimate-total1 { | ||||
|             text-align:left; | ||||
|             padding: 15px 0 15px 10px; | ||||
|             font-size:12px; | ||||
|             line-height: 18px; | ||||
|             color: #55547A; | ||||
|             border-bottom:1px solid #E8E8E8; | ||||
|             border-top:1px solid #E8E8E8; | ||||
|             border-left:1px solid #E8E8E8; | ||||
|         .total-border-right { | ||||
|             border: 1px solid #E8E8E8 !important; | ||||
|             border-left: 0px !important; | ||||
|             padding-top: 0px; | ||||
|             padding: 8px !important; | ||||
|         } | ||||
|  | ||||
|         td.estimate-total2 { | ||||
|             font-weight: 500; | ||||
|             text-align: right; | ||||
|             font-size:12px; | ||||
|             line-height: 18px; | ||||
|             padding: 15px 10px 15px 0; | ||||
|             color: #5851DB; | ||||
|             border-bottom:1px solid #E8E8E8; | ||||
|             border-top:1px solid #E8E8E8; | ||||
|             border-right:1px solid #E8E8E8; | ||||
|         } | ||||
|  | ||||
|         .inv-item { | ||||
|             border-color: #d9d9d9; | ||||
|         } | ||||
|  | ||||
|         .no-border { | ||||
|             border: none; | ||||
|         } | ||||
|         .desc { | ||||
|             font-weight: 100; | ||||
|             text-align: justify; | ||||
|             font-size: 10px; | ||||
|             margin-bottom: 15px; | ||||
|             margin-top:7px; | ||||
|             color:rgba(0, 0, 0, 0.85); | ||||
|         } | ||||
|         .company-details h1 { | ||||
|             margin:0; | ||||
|             font-style: normal; | ||||
|             font-weight: bold; | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             letter-spacing: 0.05em; | ||||
|             text-align: left; | ||||
|             max-width: 220px; | ||||
|         } | ||||
|         .company-details h4 { | ||||
|             margin:0; | ||||
|             font-style: normal; | ||||
|             font-weight: 100; | ||||
|             font-size: 18px; | ||||
|             line-height: 25px; | ||||
|             text-align: right; | ||||
|         } | ||||
|         .company-details h3 { | ||||
|              margin-bottom:1px; | ||||
|              margin-top:0; | ||||
|         } | ||||
|         tr.total td { | ||||
|             border-bottom:1px solid #E8E8E8; | ||||
|             border-top:1px solid #E8E8E8; | ||||
|         } | ||||
|         /* -- Notes -- */ | ||||
|  | ||||
|         .notes { | ||||
|             font-style: normal; | ||||
|             font-weight: 300; | ||||
|             font-size: 12px; | ||||
|             color: #595959; | ||||
|             margin-top: 15px; | ||||
| @ -390,8 +317,6 @@ | ||||
|         } | ||||
|  | ||||
|         .notes-label { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             letter-spacing: 0.05em; | ||||
| @ -401,67 +326,125 @@ | ||||
|             padding-bottom: 10px; | ||||
|         } | ||||
|  | ||||
|         /* -- Helpers -- */ | ||||
|  | ||||
|         .text-primary { | ||||
|             color: #5851DB; | ||||
|         } | ||||
|  | ||||
|         .text-center { | ||||
|             text-align: center | ||||
|         } | ||||
|  | ||||
|         table .text-left { | ||||
|             text-align: left; | ||||
|         } | ||||
|  | ||||
|         table .text-right { | ||||
|             text-align: right; | ||||
|         } | ||||
|  | ||||
|         .border-0 { | ||||
|             border: none; | ||||
|         } | ||||
|  | ||||
|         .py-2 { | ||||
|             padding-top: 2px; | ||||
|             padding-bottom: 2px; | ||||
|         } | ||||
|  | ||||
|         .py-8 { | ||||
|             padding-top: 8px; | ||||
|             padding-bottom: 8px; | ||||
|         } | ||||
|  | ||||
|         .py-3 { | ||||
|             padding: 3px 0; | ||||
|         } | ||||
|  | ||||
|         .pr-20 { | ||||
|             padding-right: 20px; | ||||
|         } | ||||
|  | ||||
|         .pr-10 { | ||||
|             padding-right: 10px; | ||||
|         } | ||||
|  | ||||
|         .pl-20 { | ||||
|             padding-left: 20px; | ||||
|         } | ||||
|  | ||||
|         .pl-10 { | ||||
|             padding-left: 10px; | ||||
|         } | ||||
|  | ||||
|         .pl-0 { | ||||
|             padding-left: 0; | ||||
|         } | ||||
|     </style> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
|     <div class="header-table"> | ||||
|     <div class="header-container"> | ||||
|         <table width="100%"> | ||||
|             <tr> | ||||
|                 @if($logo) | ||||
|                     <td class="header-left"> | ||||
|                 <td class="header-section-left"> | ||||
|                     <img class="header-logo" src="{{ $logo }}" alt="Company Logo"> | ||||
|                 @else | ||||
|                     @else | ||||
|                     @if($estimate->user->company) | ||||
|                     <td class="header-left" style="padding-top:0px;"> | ||||
|                         <h1 class="header-logo"> {{$estimate->user->company->name}} </h1> | ||||
|                 <td class="header-section-left" style="padding-top:0px;"> | ||||
|                     <h1 class="header-logo"> {{$estimate->user->company->name}} </h1> | ||||
|                     @endif | ||||
|                     @endif | ||||
|                 @endif | ||||
|                 </td> | ||||
|                 <td class="header-right company-details"> | ||||
|                 <td class="header-section-right company-address-container"> | ||||
|                     @include('app.pdf.estimate.partials.company-address') | ||||
|                 </td> | ||||
|             </tr> | ||||
|         </table> | ||||
|     </div> | ||||
|  | ||||
|     <hr class="header-line"> | ||||
|     <hr class="header-bottom-divider"> | ||||
|  | ||||
|     <div class="wrapper"> | ||||
|         <div class="address"> | ||||
|             <div class="bill-add"> | ||||
|                 <div style="float:left;"> | ||||
|         <div class="main-content"> | ||||
|             <div class="customer-address-container"> | ||||
|                 <div class="billing-address-container"> | ||||
|                     @include('app.pdf.estimate.partials.billing-address') | ||||
|                 </div> | ||||
|                @if($estimate->user->billingaddress) | ||||
|                     <div style="float:right;"> | ||||
|                 @else | ||||
|                     <div style="float:left;"> | ||||
|                 @endif | ||||
|                     @include('app.pdf.estimate.partials.shipping-address') | ||||
|                 @if($estimate->user->billingaddress) | ||||
|                 <div class="shipping-address-container"> | ||||
|                     @else | ||||
|                     <div class="shipping-address-container--left"> | ||||
|                         @endif | ||||
|                         @include('app.pdf.estimate.partials.shipping-address') | ||||
|                     </div> | ||||
|                     <div style="clear: both;"></div> | ||||
|                 </div> | ||||
|  | ||||
|                 <div class="estimate-details-container"> | ||||
|                     <table> | ||||
|                         <tr> | ||||
|                             <td class="attribute-label">Estimate Number</td> | ||||
|                             <td class="attribute-value">  {{$estimate->estimate_number}}</td> | ||||
|                         </tr> | ||||
|                         <tr> | ||||
|                             <td class="attribute-label">Estimate Date </td> | ||||
|                             <td class="attribute-value">  {{$estimate->formattedEstimateDate}}</td> | ||||
|                         </tr> | ||||
|                         <tr> | ||||
|                             <td class="attribute-label">Expiry Date</td> | ||||
|                             <td class="attribute-value">  {{$estimate->formattedExpiryDate}}</td> | ||||
|                         </tr> | ||||
|                     </table> | ||||
|                 </div> | ||||
|                 <div style="clear: both;"></div> | ||||
|             </div> | ||||
|  | ||||
|             <div class="job-add"> | ||||
|                 <table> | ||||
|                     <tr> | ||||
|                         <td class="textStyle1" style="text-align: left; color: #55547A">Estimate Number</td> | ||||
|                         <td class="textStyle2">  {{$estimate->estimate_number}}</td> | ||||
|                     </tr> | ||||
|                     <tr> | ||||
|                         <td class="textStyle1" style="text-align: left; color: #55547A">Estimate Date </td> | ||||
|                         <td class="textStyle2">  {{$estimate->formattedEstimateDate}}</td> | ||||
|                     </tr> | ||||
|                     <tr> | ||||
|                         <td class="textStyle1" style="text-align: left; color: #55547A">Expiry Date</td> | ||||
|                         <td class="textStyle2">  {{$estimate->formattedExpiryDate}}</td> | ||||
|                     </tr> | ||||
|                 </table> | ||||
|             </div> | ||||
|             <div style="clear: both;"></div> | ||||
|             @include('app.pdf.estimate.partials.table') | ||||
|             @include('app.pdf.estimate.partials.notes') | ||||
|         </div> | ||||
|         @include('app.pdf.estimate.partials.table') | ||||
|         @include('app.pdf.estimate.partials.notes') | ||||
|     </div> | ||||
| </body> | ||||
|  | ||||
| </html> | ||||
|  | ||||
| @ -1,11 +1,11 @@ | ||||
| @if($estimate->user->billingaddress) | ||||
|     <p class="bill-to">Bill To,</p> | ||||
|     <p class="billing-address-label">Bill To,</p> | ||||
|     @if($estimate->user->billingaddress->name) | ||||
|         <p class="bill-user-name"> | ||||
|         <p class="billing-address-name"> | ||||
|             {{$estimate->user->billingaddress->name}} | ||||
|         </p> | ||||
|     @endif | ||||
|     <p class="bill-user-address"> | ||||
|     <p class="billing-address"> | ||||
|         @if($estimate->user->billingaddress->address_street_1) | ||||
|             {!! nl2br(htmlspecialchars($estimate->user->billingaddress->address_street_1)) !!}<br> | ||||
|         @endif | ||||
| @ -31,7 +31,7 @@ | ||||
|         @endif | ||||
|  | ||||
|         @if($estimate->user->billingaddress->phone) | ||||
|             <p class="bill-user-phone"> | ||||
|             <p class="billing-address"> | ||||
|                 Phone :{{$estimate->user->billingaddress->phone}} | ||||
|             </p> | ||||
|         @endif | ||||
|  | ||||
| @ -3,7 +3,7 @@ | ||||
| @endif | ||||
|  | ||||
| @if($company_address) | ||||
|     <p class="company-add"> | ||||
|     <p class="company-address"> | ||||
|         @if($company_address->addresses[0]['address_street_1']) | ||||
|             {!! nl2br(htmlspecialchars($company_address->addresses[0]['address_street_1'])) !!} <br> | ||||
|         @endif | ||||
|  | ||||
| @ -1,11 +1,11 @@ | ||||
| @if($estimate->user->shippingaddress) | ||||
|     <p class="ship-to">Ship To,</p> | ||||
|     <p class="shipping-address-label">Ship To,</p> | ||||
|     @if($estimate->user->shippingaddress->name) | ||||
|         <p class="ship-user-name"> | ||||
|         <p class="shipping-address-name"> | ||||
|             {{$estimate->user->shippingaddress->name}} | ||||
|         </p> | ||||
|     @endif | ||||
|     <p class="ship-user-address"> | ||||
|     <p class="shipping-address"> | ||||
|         @if($estimate->user->shippingaddress->address_street_1) | ||||
|             {!! nl2br(htmlspecialchars($estimate->user->shippingaddress->address_street_1)) !!}<br> | ||||
|         @endif | ||||
| @ -30,8 +30,8 @@ | ||||
|             {{$estimate->user->shippingaddress->country->name}}<br> | ||||
|         @endif | ||||
|  | ||||
|         @if($estimate->user->phone) | ||||
|             <p class="ship-user-phone"> | ||||
|         @if($estimate->user->shippingAddress->phone) | ||||
|             <p class="shipping-address"> | ||||
|                 Phone :{{$estimate->user->shippingaddress->phone}} | ||||
|             </p> | ||||
|         @endif | ||||
|  | ||||
| @ -1,50 +1,49 @@ | ||||
| <table width="100%" class="table2" cellspacing="0" border="0"> | ||||
|     <tr class="main-table-header"> | ||||
|         <th width="2%" class="ItemTableHeader" style="text-align: right; color: #55547A; padding-right: 20px">#</th> | ||||
|         <th width="40%" class="ItemTableHeader" style="text-align: left; color: #55547A; padding-left: 0px">Items</th> | ||||
|         <th class="ItemTableHeader" style="text-align: right; color: #55547A; padding-right: 20px">Quantity</th> | ||||
|         <th class="ItemTableHeader" style="text-align: right; color: #55547A; padding-right: 20px">Price</th> | ||||
| <table width="100%" class="items-table" cellspacing="0" border="0"> | ||||
|     <tr class="item-table-heading-row"> | ||||
|         <th width="2%" class="item-table-heading text-right pr-20">#</th> | ||||
|         <th width="40%" class="item-table-heading text-left pl-0">Items</th> | ||||
|         <th class="item-table-heading text-right pr-20">Quantity</th> | ||||
|         <th class="item-table-heading text-right pr-20">Price</th> | ||||
|         @if($estimate->discount_per_item === 'YES') | ||||
|         <th class="ItemTableHeader" style="text-align: right; color: #55547A; padding-left: 10px">Discount</th> | ||||
|         <th class="item-table-heading text-right pl-10">Discount</th> | ||||
|         @endif | ||||
|         <th class="ItemTableHeader" style="text-align: right; color: #55547A;">Amount</th> | ||||
|         <th class="item-table-heading text-right">Amount </th> | ||||
|     </tr> | ||||
|     @php | ||||
|         $index = 1 | ||||
|     @endphp | ||||
|     @foreach ($estimate->items as $item) | ||||
|         <tr class="item-details"> | ||||
|         <tr class="item-row"> | ||||
|             <td | ||||
|                 class="inv-item items" | ||||
|                 style="text-align: right; color: #040405; padding-right: 20px; vertical-align: top;" | ||||
|                 class="item-cell text-right pr-20" | ||||
|                 style="vertical-align: top;" | ||||
|             > | ||||
|                 {{$index}} | ||||
|             </td> | ||||
|             <td | ||||
|                 class="inv-item items" | ||||
|                 style="text-align: left; color: #040405;padding-left: 0px" | ||||
|                 class="item-cell text-left pl-0" | ||||
|             > | ||||
|                 <span>{{ $item->name }}</span><br> | ||||
|                 <span | ||||
|                     style="text-align: left; color: #595959; font-size: 9px; font-weight:300; line-height: 12px;" | ||||
|                     class="item-description" | ||||
|                 > | ||||
|                     {!! nl2br(htmlspecialchars($item->description)) !!} | ||||
|                 </span> | ||||
|             </td> | ||||
|             <td | ||||
|                 class="inv-item items" | ||||
|                 style="text-align: right; color: #040405; padding-right: 20px" | ||||
|                 class="item-cell text-right pr-20" | ||||
|                 style="vertical-align: top;" | ||||
|             > | ||||
|                 {{$item->quantity}} | ||||
|             </td> | ||||
|             <td | ||||
|                 class="inv-item items" | ||||
|                 style="text-align: right; color: #040405; padding-right: 20px" | ||||
|                 class="item-cell text-right pr-20" | ||||
|                 style="vertical-align: top;" | ||||
|             > | ||||
|                 {!! format_money_pdf($item->price, $estimate->user->currency) !!} | ||||
|             </td> | ||||
|             @if($estimate->discount_per_item === 'YES') | ||||
|                 <td class="inv-item items" style="text-align: right; color: #040405; padding-left: 10px"> | ||||
|                 <td class="item-cell text-right pl-10" style="vertical-align: top;"> | ||||
|                     @if($item->discount_type === 'fixed') | ||||
|                         {!! format_money_pdf($item->discount_val, $estimate->user->currency) !!} | ||||
|                     @endif | ||||
| @ -53,7 +52,7 @@ | ||||
|                     @endif | ||||
|                 </td> | ||||
|             @endif | ||||
|             <td class="inv-item items" style="text-align: right; color: #040405;"> | ||||
|             <td class="item-cell text-right" style="vertical-align: top;"> | ||||
|                 {!! format_money_pdf($item->total, $estimate->user->currency) !!} | ||||
|             </td> | ||||
|         </tr> | ||||
| @ -63,74 +62,68 @@ | ||||
|     @endforeach | ||||
| </table> | ||||
|  | ||||
| <hr class="items-table-hr"> | ||||
| <hr class="item-cell-table-hr"> | ||||
|  | ||||
| <table width="100%" cellspacing="0px" style="margin-left:420px;margin-top: 10px" border="0" class="table3 @if(count($estimate->items) > 12) page-break @endif"> | ||||
|     <tr> | ||||
|         <td class="no-borde" style="color: #55547A; padding-left:10px;  font-size:12px;">Subtotal</td> | ||||
|         <td class="no-border items" | ||||
|             style="padding-right:10px; text-align: right;  font-size:12px; color: #040405; font-weight: 500;">{!! format_money_pdf($estimate->sub_total, $estimate->user->currency) !!}</td> | ||||
|     </tr> | ||||
|  | ||||
|     @if ($estimate->tax_per_item === 'YES') | ||||
|         @for ($i = 0; $i < count($labels); $i++) | ||||
|             <tr> | ||||
|                 <td class="no-border" style="padding-left:10px; text-align:left; font-size:12px;  color: #55547A;"> | ||||
|                     {{$labels[$i]}} | ||||
|                 </td> | ||||
|                 <td class="no-border items padd2" style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px;  color: #040405"> | ||||
|                     {!! format_money_pdf($taxes[$i], $estimate->user->currency) !!} | ||||
|                 </td> | ||||
|             </tr> | ||||
|         @endfor | ||||
|     @else | ||||
|         @foreach ($estimate->taxes as $tax) | ||||
|             <tr> | ||||
|                 <td class="no-border" style="padding-left:10px; text-align:left; font-size:12px;  color: #55547A;"> | ||||
|                     {{$tax->name.' ('.$tax->percent.'%)'}} | ||||
|                 </td> | ||||
|                 <td class="no-border items padd2" style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px;  color: #040405"> | ||||
|                     {!! format_money_pdf($tax->amount, $estimate->user->currency) !!} | ||||
|                 </td> | ||||
|             </tr> | ||||
|         @endforeach | ||||
|     @endif | ||||
|  | ||||
|     @if ($estimate->discount_per_item === 'NO') | ||||
| <div class="total-display-container"> | ||||
|     <table width="100%" cellspacing="0px" border="0" class="total-display-table @if(count($estimate->items) > 12) page-break @endif"> | ||||
|         <tr> | ||||
|             <td class="no-border" style="padding-left:10px; text-align:left; font-size:12px; color: #55547A;"> | ||||
|                 @if($estimate->discount_type === 'fixed') | ||||
|                     Discount | ||||
|                 @endif | ||||
|                 @if($estimate->discount_type === 'percentage') | ||||
|                     Discount ({{$estimate->discount}}%) | ||||
|                 @endif | ||||
|             </td> | ||||
|             <td class="no-border items padd2" style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px;  color: #040405"> | ||||
|                 @if($estimate->discount_type === 'fixed') | ||||
|                     {!! format_money_pdf($estimate->discount_val, $estimate->user->currency) !!} | ||||
|                 @endif | ||||
|                 @if($estimate->discount_type === 'percentage') | ||||
|                     {!! format_money_pdf($estimate->discount_val, $estimate->user->currency) !!} | ||||
|                 @endif | ||||
|             <td class="border-0 total-table-attribute-label">Subtotal</td> | ||||
|             <td class="border-0 item-cell total-table-attribute-value ">{!! format_money_pdf($estimate->sub_total, $estimate->user->currency) !!}</td> | ||||
|         </tr> | ||||
|  | ||||
|         @if ($estimate->tax_per_item === 'YES') | ||||
|             @for ($i = 0; $i < count($labels); $i++) | ||||
|                 <tr> | ||||
|                     <td class="border-0 total-table-attribute-label"> | ||||
|                         {{$labels[$i]}} | ||||
|                     </td> | ||||
|                     <td class="border-0 item-cell  total-table-attribute-value"> | ||||
|                         {!! format_money_pdf($taxes[$i], $estimate->user->currency) !!} | ||||
|                     </td> | ||||
|                 </tr> | ||||
|             @endfor | ||||
|         @else | ||||
|             @foreach ($estimate->taxes as $tax) | ||||
|                 <tr> | ||||
|                     <td class="border-0 total-table-attribute-label"> | ||||
|                         {{$tax->name.' ('.$tax->percent.'%)'}} | ||||
|                     </td> | ||||
|                     <td class="border-0 item-cell total-table-attribute-value" > | ||||
|                         {!! format_money_pdf($tax->amount, $estimate->user->currency) !!} | ||||
|                     </td> | ||||
|                 </tr> | ||||
|             @endforeach | ||||
|         @endif | ||||
|  | ||||
|         @if ($estimate->discount_per_item === 'NO') | ||||
|             <tr> | ||||
|                 <td class="border-0 total-table-attribute-label pl-10"> | ||||
|                     @if($estimate->discount_type === 'fixed') | ||||
|                         Discount | ||||
|                     @endif | ||||
|                     @if($estimate->discount_type === 'percentage') | ||||
|                         Discount ({{$estimate->discount}}%) | ||||
|                     @endif | ||||
|                 </td> | ||||
|                 <td class="border-0 item-cell total-table-attribute-value text-right"> | ||||
|                     @if($estimate->discount_type === 'fixed') | ||||
|                         {!! format_money_pdf($estimate->discount_val, $estimate->user->currency) !!} | ||||
|                     @endif | ||||
|                     @if($estimate->discount_type === 'percentage') | ||||
|                         {!! format_money_pdf($estimate->discount_val, $estimate->user->currency) !!} | ||||
|                     @endif | ||||
|                 </td> | ||||
|             </tr> | ||||
|         @endif | ||||
|         <tr> | ||||
|             <td class="py-3"></td> | ||||
|             <td class="py-3"></td> | ||||
|         </tr> | ||||
|         <tr> | ||||
|             <td class="border-0 total-border-left total-table-attribute-label">Total</td> | ||||
|             <td class="border-0 total-border-right item-cell py-8 total-table-attribute-value text-primary"> | ||||
|                 {!! format_money_pdf($estimate->total, $estimate->user->currency)!!} | ||||
|             </td> | ||||
|         </tr> | ||||
|     @endif | ||||
|     <tr> | ||||
|         <td style="padding:3px 0px"></td> | ||||
|         <td style="padding:3px 0px"></td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|         <td class="no-border total-border-left" | ||||
|             style="padding-left:10px; padding-bottom:10px; text-align:left; padding-top:20px; font-size:12px;  color: #55547A;" | ||||
|         > | ||||
|             <label class="total-bottom"> Total </label> | ||||
|         </td> | ||||
|         <td | ||||
|             class="no-border total-border-right items padd8" | ||||
|             style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px;  padding-top:20px; color: #5851DB" | ||||
|         > | ||||
|             {!! format_money_pdf($estimate->total, $estimate->user->currency)!!} | ||||
|         </td> | ||||
|     </tr> | ||||
| </table> | ||||
|     </table> | ||||
| </div> | ||||
|  | ||||
| @ -1,10 +1,12 @@ | ||||
| <!DOCTYPE html> | ||||
| <html> | ||||
|  | ||||
| <head> | ||||
|     <title>Invoice</title> | ||||
|     <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> | ||||
|     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | ||||
|  | ||||
|     <style type="text/css"> | ||||
|         /* -- Base -- */ | ||||
|         body { | ||||
|             font-family: "DejaVu Sans"; | ||||
|         } | ||||
| @ -15,29 +17,27 @@ | ||||
|             margin-top: 50px; | ||||
|         } | ||||
|  | ||||
|         table { | ||||
|             border-collapse: collapse; | ||||
|         .text-center { | ||||
|             text-align: center | ||||
|         } | ||||
|  | ||||
|         .header-line { | ||||
|             color:rgba(0, 0, 0, 0.2); | ||||
|         hr { | ||||
|             margin: 0 30px 0 30px; | ||||
|             color: rgba(0, 0, 0, 0.2); | ||||
|             border: 0.5px solid #EAF1FB; | ||||
|         } | ||||
|  | ||||
|         /* -- Header -- */ | ||||
|  | ||||
|         .header-bottom-divider { | ||||
|             color: rgba(0, 0, 0, 0.2); | ||||
|             position: absolute; | ||||
|             top: 90px; | ||||
|             left: 0px; | ||||
|             width: 100%; | ||||
|         } | ||||
|  | ||||
|         hr { | ||||
|             margin: 0 30px 0 30px; | ||||
|             color:rgba(0, 0, 0, 0.2); | ||||
|             border: 0.5px solid #EAF1FB; | ||||
|         } | ||||
|  | ||||
|         .header-center { | ||||
|             text-align: center | ||||
|         } | ||||
|  | ||||
|         .header-table { | ||||
|         .header-container { | ||||
|             position: absolute; | ||||
|             width: 100%; | ||||
|             height: 90px; | ||||
| @ -52,122 +52,69 @@ | ||||
|             color: #817AE3; | ||||
|         } | ||||
|  | ||||
|         .inv-flex{ | ||||
|             display:flex; | ||||
|         } | ||||
|  | ||||
|         .inv-data{ | ||||
|             text-align:right; | ||||
|             margin-right:120px; | ||||
|         } | ||||
|         .inv-value{ | ||||
|             text-align:left; | ||||
|             margin-left:160px; | ||||
|         } | ||||
|         .header { | ||||
|             font-size: 20px; | ||||
|             color: rgba(0, 0, 0, 0.7); | ||||
|         } | ||||
|  | ||||
|         .TextColor1 { | ||||
|             font-size: 16px; | ||||
|             color: rgba(0, 0, 0, 0.5); | ||||
|         .content-wrapper { | ||||
|             display: block; | ||||
|             margin-top: 0px; | ||||
|             padding-top: 16px; | ||||
|             padding-bottom: 20px; | ||||
|         } | ||||
|  | ||||
|         @page { | ||||
|             margin-top: 60px !important; | ||||
|         } | ||||
|  | ||||
|         .wrapper { | ||||
|            display: block; | ||||
|            margin-top: 0px; | ||||
|            padding-top: 16px; | ||||
|            padding-bottom: 20px; | ||||
|         } | ||||
|  | ||||
|         .address { | ||||
|             /* display: inline-block; */ | ||||
|             padding-top: 30px | ||||
|         } | ||||
|  | ||||
|         .company { | ||||
|             float: left; | ||||
|         .company-address-container { | ||||
|             padding-left: 30px; | ||||
|             font-weight: normal; | ||||
|             display: inline; | ||||
|             float:left; | ||||
|             width:30%; | ||||
|             float: left; | ||||
|             width: 30%; | ||||
|             text-transform: capitalize; | ||||
|             margin-bottom: 2px; | ||||
|         } | ||||
|  | ||||
|         .company h1 { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|         .company-address-container h1 { | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             letter-spacing: 0.05em; | ||||
|             margin-bottom: 0px; | ||||
|             margin-top: 10px; | ||||
|         } | ||||
|  | ||||
|         .company-add { | ||||
|         .company-address { | ||||
|             margin-top: 2px; | ||||
|             text-align: left; | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 12px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
|         } | ||||
|  | ||||
|         .job-add { | ||||
|             /* display: inline; */ | ||||
|         .invoice-details-container { | ||||
|             float: right; | ||||
|             padding: 10px 30px 0 0; | ||||
|         } | ||||
|         .amount-due { | ||||
|             background-color: #f2f2f2; | ||||
|         } | ||||
|  | ||||
|         .textRight { | ||||
|             text-align: right; | ||||
|         } | ||||
|  | ||||
|         .textLeft { | ||||
|             text-align: left; | ||||
|         } | ||||
|  | ||||
|         .textStyle1 { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|         .attribute-label { | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|             padding-right: 40px; | ||||
|             text-align: left; | ||||
|             color: #55547A; | ||||
|         } | ||||
|  | ||||
|         .textStyle2 { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|         .attribute-value { | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|             text-align: right; | ||||
|         } | ||||
|         .bill-add { | ||||
|             width:45%; | ||||
|             padding: 0px 0 0 0px; | ||||
|         } | ||||
|  | ||||
|         /* -------------------------- */ | ||||
|         /* shipping style */ | ||||
|         /* -- Shipping -- */ | ||||
|  | ||||
|         .ship-address-container { | ||||
|         .shipping-address-container { | ||||
|             float: right; | ||||
|             padding-left: 30px; | ||||
|         } | ||||
|  | ||||
|         .ship-to { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|         .shipping-address-label { | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|             padding: 0px; | ||||
| @ -175,18 +122,15 @@ | ||||
|             margin-bottom: 0px; | ||||
|         } | ||||
|  | ||||
|         .ship-user-name { | ||||
|             max-width: 250px | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|         .shipping-address-name { | ||||
|             max-width: 160px; | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             padding: 0px; | ||||
|             margin: 0px; | ||||
|         } | ||||
|         .ship-user-address { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|  | ||||
|         .shipping-address { | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
| @ -194,27 +138,15 @@ | ||||
|             margin: 0px; | ||||
|             width: 160px; | ||||
|         } | ||||
|         .ship-user-phone { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
|             padding: 0px; | ||||
|             margin: 0px; | ||||
|         } | ||||
|  | ||||
|         /* -------------------------- */ | ||||
|         /* billing style */ | ||||
|         /* -- Billing -- */ | ||||
|  | ||||
|         .bill-address-container { | ||||
|         .billing-address-container { | ||||
|             float: left; | ||||
|             padding-left: 30px; | ||||
|         } | ||||
|  | ||||
|         .bill-to { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|         .billing-address-label { | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|             padding: 0px; | ||||
| @ -222,19 +154,15 @@ | ||||
|             margin-bottom: 0px; | ||||
|         } | ||||
|  | ||||
|         .bill-user-name { | ||||
|             max-width: 250px | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|         .billing-address-name { | ||||
|             max-width: 160px; | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             padding: 0px; | ||||
|             margin: 0px; | ||||
|         } | ||||
|  | ||||
|         .bill-user-address { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|         .billing-address { | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
| @ -243,115 +171,102 @@ | ||||
|             width: 160px; | ||||
|         } | ||||
|  | ||||
|         .bill-user-phone { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
|             padding: 0px; | ||||
|             margin: 0px; | ||||
|         } | ||||
|         /* -- Items Table -- */ | ||||
|  | ||||
|         .table2 { | ||||
|         .items-table { | ||||
|             margin-top: 35px; | ||||
|             padding: 0px 30px 10px 30px; | ||||
|             page-break-before: avoid; | ||||
|             page-break-after: auto; | ||||
|         } | ||||
|  | ||||
|  | ||||
|         .table2 hr { | ||||
|             height:0.1px; | ||||
|         .items-table hr { | ||||
|             height: 0.1px; | ||||
|         } | ||||
|  | ||||
|         .ItemTableHeader { | ||||
|         .item-table-heading { | ||||
|             font-size: 13.5; | ||||
|             text-align: center; | ||||
|             color: rgba(0, 0, 0, 0.85); | ||||
|             padding: 5px; | ||||
|             color: #55547A; | ||||
|         } | ||||
|  | ||||
|         tr.main-table-header th { | ||||
|         tr.item-table-heading-row th { | ||||
|             border-bottom: 0.620315px solid #E8E8E8; | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|         } | ||||
|  | ||||
|         tr.item-details td { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|         tr.item-row td { | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|         } | ||||
|  | ||||
|         .items { | ||||
|         .item-cell { | ||||
|             font-size: 13; | ||||
|             color: rgba(0, 0, 0, 0.6); | ||||
|             text-align: center; | ||||
|             padding: 5px; | ||||
|             padding-top: 10px; | ||||
|             color: #040405; | ||||
|         } | ||||
|  | ||||
|         .padd8 { | ||||
|             padding-top: 8px; | ||||
|             padding-bottom: 8px; | ||||
|         .item-description { | ||||
|             color: #595959; | ||||
|             font-size: 9px; | ||||
|             line-height: 12px; | ||||
|         } | ||||
|  | ||||
|         .padd2 { | ||||
|         /* -- Total Display Table -- */ | ||||
|  | ||||
|         .total-display-container { | ||||
|             padding: 0 25px; | ||||
|         } | ||||
|  | ||||
|         .total-display-table { | ||||
|             border-top: none; | ||||
|             box-sizing: border-box; | ||||
|             page-break-inside: avoid; | ||||
|             page-break-before: auto; | ||||
|             page-break-after: auto; | ||||
|             margin-left: 500px; | ||||
|             margin-top: 20px; | ||||
|         } | ||||
|  | ||||
|         .total-table-attribute-label { | ||||
|             font-size: 13px; | ||||
|             color: #55547A; | ||||
|             text-align: left; | ||||
|             padding-left: 10px; | ||||
|         } | ||||
|  | ||||
|         .total-table-attribute-value { | ||||
|             font-weight: bold; | ||||
|             text-align: right; | ||||
|             font-size: 13px; | ||||
|             color: #040405; | ||||
|             padding-right: 10px; | ||||
|             padding-top: 2px; | ||||
|             padding-bottom: 2px; | ||||
|         } | ||||
|  | ||||
|         .table3 { | ||||
|             /* border: 1px solid #EAF1FB; */ | ||||
|             border-top: none; | ||||
|             /* padding-right: 30px; */ | ||||
|             box-sizing: border-box; | ||||
|             width: 630px; | ||||
|             /* position: absolute; | ||||
|             right: -25; */ | ||||
|             page-break-inside: avoid; | ||||
|             page-break-before: auto; | ||||
|             page-break-after: auto; | ||||
|         } | ||||
|  | ||||
|         .total-border-left { | ||||
|             border: 1px solid #E8E8E8!important; | ||||
|             border: 1px solid #E8E8E8 !important; | ||||
|             border-right: 0px !important; | ||||
|             padding-top: 0px; | ||||
|             padding:8px !important; | ||||
|             padding: 8px !important; | ||||
|         } | ||||
|  | ||||
|         .total-border-right { | ||||
|             border: 1px solid #E8E8E8!important; | ||||
|             border: 1px solid #E8E8E8 !important; | ||||
|             border-left: 0px !important; | ||||
|             padding-top: 0px; | ||||
|             padding:8px !important; | ||||
|  | ||||
|             padding: 8px !important; | ||||
|         } | ||||
|  | ||||
|         .inv-item { | ||||
|             border-color: #d9d9d9; | ||||
|         } | ||||
|  | ||||
|         .no-border { | ||||
|             border: none; | ||||
|         } | ||||
|  | ||||
|         .desc { | ||||
|             font-weight: 100; | ||||
|             text-align: justify; | ||||
|             font-size: 10px; | ||||
|             margin-bottom: 15px; | ||||
|             margin-top:7px; | ||||
|             color:rgba(0, 0, 0, 0.85); | ||||
|         } | ||||
|         /* -- Notes -- */ | ||||
|  | ||||
|         .notes { | ||||
|             font-style: normal; | ||||
|             font-weight: 300; | ||||
|             font-size: 12px; | ||||
|             color: #595959; | ||||
|             margin-top: 15px; | ||||
| @ -362,8 +277,6 @@ | ||||
|         } | ||||
|  | ||||
|         .notes-label { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             letter-spacing: 0.05em; | ||||
| @ -373,13 +286,69 @@ | ||||
|             padding-bottom: 10px; | ||||
|         } | ||||
|  | ||||
|         /* -- Helpers -- */ | ||||
|  | ||||
|         .text-primary { | ||||
|             color: #5851DB; | ||||
|         } | ||||
|  | ||||
|         .text-center { | ||||
|             text-align: center | ||||
|         } | ||||
|  | ||||
|         table .text-left { | ||||
|             text-align: left; | ||||
|         } | ||||
|  | ||||
|         table .text-right { | ||||
|             text-align: right; | ||||
|         } | ||||
|  | ||||
|         .border-0 { | ||||
|             border: none; | ||||
|         } | ||||
|  | ||||
|         .py-2 { | ||||
|             padding-top: 2px; | ||||
|             padding-bottom: 2px; | ||||
|         } | ||||
|  | ||||
|         .py-8 { | ||||
|             padding-top: 8px; | ||||
|             padding-bottom: 8px; | ||||
|         } | ||||
|  | ||||
|         .py-3 { | ||||
|             padding: 3px 0; | ||||
|         } | ||||
|  | ||||
|         .pr-20 { | ||||
|             padding-right: 20px; | ||||
|         } | ||||
|  | ||||
|         .pr-10 { | ||||
|             padding-right: 10px; | ||||
|         } | ||||
|  | ||||
|         .pl-20 { | ||||
|             padding-left: 20px; | ||||
|         } | ||||
|  | ||||
|         .pl-10 { | ||||
|             padding-left: 10px; | ||||
|         } | ||||
|  | ||||
|         .pl-0 { | ||||
|             padding-left: 0; | ||||
|         } | ||||
|     </style> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
|     <div class="header-table"> | ||||
|     <div class="header-container"> | ||||
|         <table width="100%"> | ||||
|             <tr> | ||||
|                 <td class="header-center"> | ||||
|                 <td class="text-center"> | ||||
|                     @if($logo) | ||||
|                         <img class="header-logo" src="{{ $logo }}" alt="Company Logo"> | ||||
|                     @else | ||||
| @ -390,48 +359,44 @@ | ||||
|                 </td> | ||||
|             </tr> | ||||
|         </table> | ||||
|         <hr class="header-line" style="border: 0.620315px solid #E8E8E8;"/> | ||||
|         <hr class="header-bottom-divider" style="border: 0.620315px solid #E8E8E8;" /> | ||||
|     </div> | ||||
|     <div class="wrapper"> | ||||
|         <div class="address"> | ||||
|             <div class="company"> | ||||
|     <div class="content-wrapper"> | ||||
|         <div style="padding-top: 30px"> | ||||
|             <div class="company-address-container"> | ||||
|                 @include('app.pdf.invoice.partials.company-address') | ||||
|             </div> | ||||
|             <div class="job-add"> | ||||
|             <div class="invoice-details-container"> | ||||
|                 <table> | ||||
|                     <tr> | ||||
|                         <td class="textStyle1" style="text-align: left; color: #55547A">Invoice Number</td> | ||||
|                         <td class="textStyle2">  {{$invoice->invoice_number}}</td> | ||||
|                         <td class="attribute-label">Invoice Number</td> | ||||
|                         <td class="attribute-value">  {{$invoice->invoice_number}}</td> | ||||
|                     </tr> | ||||
|                     <tr> | ||||
|                         <td class="textStyle1" style="text-align: left; color: #55547A">Invoice Date </td> | ||||
|                         <td class="textStyle2">  {{$invoice->formattedInvoiceDate}}</td> | ||||
|                         <td class="attribute-label">Invoice Date </td> | ||||
|                         <td class="attribute-value">  {{$invoice->formattedInvoiceDate}}</td> | ||||
|                     </tr> | ||||
|                     <tr> | ||||
|                         <td class="textStyle1" style="text-align: left; color: #55547A">Due date</td> | ||||
|                         <td class="textStyle2">  {{$invoice->formattedDueDate}}</td> | ||||
|                         <td class="attribute-label">Due date</td> | ||||
|                         <td class="attribute-value">  {{$invoice->formattedDueDate}}</td> | ||||
|                     </tr> | ||||
|                 </table> | ||||
|             </div> | ||||
|             <div style="clear: both;"></div> | ||||
|         </div> | ||||
|         <div class="bill-add"> | ||||
|             <div class="bill-address-container"> | ||||
|                     @include('app.pdf.invoice.partials.billing-address') | ||||
|             </div> | ||||
|             @if($invoice->user->billingaddress) | ||||
|                 <div class="ship-address-container"> | ||||
|             @else | ||||
|                 <div class="ship-address-container " style="float:left;padding-left:0px;"> | ||||
|             @endif | ||||
|                 @include('app.pdf.invoice.partials.shipping-address') | ||||
|             </div> | ||||
|             <div style="clear: both;"></div> | ||||
|  | ||||
|         <div class="billing-address-container"> | ||||
|             @include('app.pdf.invoice.partials.billing-address') | ||||
|         </div> | ||||
|         <div style="position:relative"> | ||||
|  | ||||
|         <div class="shipping-address-container" @if($invoice->user->billingaddress) style="float:left;" @else style="float:left: padding-left: 0px;" @endif> | ||||
|             @include('app.pdf.invoice.partials.shipping-address') | ||||
|             @if($invoice->user->billingaddress) <div style="clear: both;"></div> @endif | ||||
|         </div> | ||||
|         <div style="position: relative; clear: both;"> | ||||
|             @include('app.pdf.invoice.partials.table') | ||||
|         </div> | ||||
|         @include('app.pdf.invoice.partials.notes') | ||||
|     </div> | ||||
| </body> | ||||
|  | ||||
| </html> | ||||
|  | ||||
| @ -1,10 +1,11 @@ | ||||
| <!DOCTYPE html> | ||||
| <html> | ||||
|  | ||||
| <head> | ||||
|     <title>Invoice</title> | ||||
|     {{-- <link href="https://fonts.googleapis.com/css?family=Poppins&display=swap" rel="stylesheet"> --}} | ||||
|     <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> | ||||
|     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | ||||
|     <style type="text/css"> | ||||
|         /* -- Base -- */ | ||||
|         body { | ||||
|             font-family: "DejaVu Sans"; | ||||
|         } | ||||
| @ -12,22 +13,22 @@ | ||||
|         html { | ||||
|             margin: 0px; | ||||
|             padding: 0px; | ||||
|             margin-top: 50px; | ||||
|         } | ||||
|  | ||||
|         table { | ||||
|             border-collapse: collapse; | ||||
|         } | ||||
|  | ||||
|         .header-left { | ||||
|             padding-top: 45px; | ||||
|             padding-bottom: 45px; | ||||
|             padding-left: 30px; | ||||
|             display:inline-block; | ||||
|             width:30%; | ||||
|         hr { | ||||
|             margin: 0 30px 0 30px; | ||||
|             color: rgba(0, 0, 0, 0.2); | ||||
|             border: 0.5px solid #EAF1FB; | ||||
|         } | ||||
|         @page { | ||||
|             margin-top: 60px !important; | ||||
|         } | ||||
|         .header-table { | ||||
|  | ||||
|         /* -- Header -- */ | ||||
|  | ||||
|         .header-container { | ||||
|             background: #817AE3; | ||||
|             position: absolute; | ||||
|             width: 100%; | ||||
| @ -35,351 +36,266 @@ | ||||
|             left: 0px; | ||||
|             top: -60px; | ||||
|         } | ||||
|  | ||||
|         .header-section-left { | ||||
|             padding-top: 45px; | ||||
|             padding-bottom: 45px; | ||||
|             padding-left: 30px; | ||||
|             display: inline-block; | ||||
|             width: 30%; | ||||
|         } | ||||
|  | ||||
|         .header-logo { | ||||
|             position: absolute; | ||||
|             height: 50px; | ||||
|             text-transform: capitalize; | ||||
|             color: #fff; | ||||
|         } | ||||
|         .header-right { | ||||
|             display:inline-block; | ||||
|             width:35%; | ||||
|             float:right; | ||||
|  | ||||
|         .header-section-right { | ||||
|             display: inline-block; | ||||
|             width: 35%; | ||||
|             float: right; | ||||
|             padding: 20px 30px 20px 0px; | ||||
|             text-align: right; | ||||
|             color:white; | ||||
|             color: white; | ||||
|         } | ||||
|  | ||||
|         } | ||||
|         .inv-flex{ | ||||
|             display:flex; | ||||
|         } | ||||
|         .inv-data{ | ||||
|             text-align:right; | ||||
|             margin-right:120px; | ||||
|         } | ||||
|         .inv-value{ | ||||
|             text-align:left; | ||||
|             margin-left:160px; | ||||
|         } | ||||
|         .header { | ||||
|             font-size: 20px; | ||||
|             color: rgba(0, 0, 0, 0.7); | ||||
|         } | ||||
|  | ||||
|         .TextColor1 { | ||||
|             font-size: 16px; | ||||
|             color: rgba(0, 0, 0, 0.5); | ||||
|         } | ||||
|         /*  -- Estimate Details -- */ | ||||
|  | ||||
|         .wrapper { | ||||
|            display: block; | ||||
|            margin-top: 60px; | ||||
|            padding-bottom: 20px; | ||||
|         } | ||||
|  | ||||
|         .address { | ||||
|             display: block; | ||||
|             padding-top: 20px; | ||||
|         } | ||||
|         .company { | ||||
|             padding: 0 0 0 30px; | ||||
|             display: inline; | ||||
|             float:left; | ||||
|             width:30%; | ||||
|         } | ||||
|  | ||||
|         .company h1 { | ||||
|             font-style: normal; | ||||
|             font-weight: bold; | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             letter-spacing: 0.05em; | ||||
|             margin-bottom: 0; | ||||
|         } | ||||
|  | ||||
|         .company-add { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
|             margin-top: 0px; | ||||
|         } | ||||
|  | ||||
|         /* -------------------------- */ | ||||
|         /* billing style */ | ||||
|         .bill-address-container { | ||||
|             display: block; | ||||
|             /* position: absolute; */ | ||||
|             float:right; | ||||
|             padding: 0 40px 0 0; | ||||
|         } | ||||
|  | ||||
|         .bill-to { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|             padding: 0px; | ||||
|             margin-bottom: 0px; | ||||
|         } | ||||
|  | ||||
|         .bill-user-name { | ||||
|             max-width: 250px | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             padding: 0px; | ||||
|             margin-top: 0px; | ||||
|             margin-bottom: 0px; | ||||
|         } | ||||
|  | ||||
|         .bill-user-address { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
|             padding: 0px; | ||||
|             margin: 0px; | ||||
|             width: 170px; | ||||
|         } | ||||
|         .bill-user-phone { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
|             padding: 0px; | ||||
|             margin: 0px; | ||||
|         } | ||||
|  | ||||
|         /* -------------------------- */ | ||||
|         /* shipping style */ | ||||
|         .ship-address-container { | ||||
|             display: block; | ||||
|             float:right; | ||||
|             padding: 0 30px 0 0; | ||||
|         } | ||||
|  | ||||
|         .ship-to { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|             padding: 0px; | ||||
|             margin-bottom: 0px; | ||||
|         } | ||||
|  | ||||
|         .ship-user-name { | ||||
|             max-width: 250px | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             padding: 0px; | ||||
|             margin-top: 0px; | ||||
|             margin-bottom: 0px; | ||||
|         } | ||||
|  | ||||
|         .ship-user-address { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
|             padding: 0px; | ||||
|             margin: 0px; | ||||
|             width: 170px; | ||||
|         } | ||||
|  | ||||
|         .ship-user-phone { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
|             padding: 0px; | ||||
|             margin: 0px; | ||||
|         } | ||||
|  | ||||
|         .job-add { | ||||
|             display: inline; | ||||
|             float: right; | ||||
|             width:40%; | ||||
|         } | ||||
|  | ||||
|         .amount-due { | ||||
|             background-color: #f2f2f2; | ||||
|         } | ||||
|  | ||||
|         .textRight { | ||||
|             text-align: right; | ||||
|         } | ||||
|  | ||||
|         .textLeft { | ||||
|             text-align: left; | ||||
|         } | ||||
|  | ||||
|         .textStyle1 { | ||||
|             font-size: 12; | ||||
|             font-weight: bold; | ||||
|             line-height:22px; | ||||
|             color: rgba(0, 0, 0, 0.8); | ||||
|         } | ||||
|  | ||||
|         .textStyle2 { | ||||
|             font-size: 12; | ||||
|             line-height:22px; | ||||
|             color: rgba(0, 0, 0, 0.7); | ||||
|         } | ||||
|  | ||||
|         .main-table-header td { | ||||
|             padding: 5px; | ||||
|             padding-bottom: 10px; | ||||
|         } | ||||
|  | ||||
|         .main-table-header { | ||||
|             border-bottom: 1px solid red; | ||||
|         } | ||||
|  | ||||
|         .table2 { | ||||
|             margin-top: 30px; | ||||
|             padding: 0px 30px 10px 30px; | ||||
|             page-break-before: avoid; | ||||
|             page-break-after: auto; | ||||
|         } | ||||
|  | ||||
|         hr { | ||||
|             margin: 0 30px 0 30px; | ||||
|             color:rgba(0, 0, 0, 0.2); | ||||
|             border: 0.5px solid #EAF1FB; | ||||
|         } | ||||
|  | ||||
|         .table2 hr { | ||||
|             height:0.1px; | ||||
|         } | ||||
|  | ||||
|         .ItemTableHeader { | ||||
|             font-size: 13.5; | ||||
|             text-align: center; | ||||
|             color: rgba(0, 0, 0, 0.85); | ||||
|             padding: 5px; | ||||
|         } | ||||
|  | ||||
|         tr.main-table-header th { | ||||
|             border-bottom: 0.620315px solid #E8E8E8; | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|         } | ||||
|  | ||||
|         tr.item-details td { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|         } | ||||
|  | ||||
|         .items { | ||||
|             font-size: 13; | ||||
|             color: rgba(0, 0, 0, 0.6); | ||||
|             text-align: center; | ||||
|             padding: 5px; | ||||
|             padding-top: 10px; | ||||
|         } | ||||
|  | ||||
|         .note-header { | ||||
|             font-size: 13; | ||||
|             color: rgba(0, 0, 0, 0.6); | ||||
|         } | ||||
|  | ||||
|         .note-text { | ||||
|             font-size: 10; | ||||
|             color: rgba(0, 0, 0, 0.6); | ||||
|         } | ||||
|  | ||||
|         .padd8 { | ||||
|             padding-top: 8px; | ||||
|             padding-bottom: 8px; | ||||
|         } | ||||
|  | ||||
|         .padd2 { | ||||
|             padding-top: 2px; | ||||
|             padding-bottom: 2px; | ||||
|         } | ||||
|  | ||||
|         .table3 { | ||||
|             border: 1px solid #EAF1FB; | ||||
|             border-top: none; | ||||
|             box-sizing: border-box; | ||||
|             width: 630px; | ||||
|             page-break-inside: avoid; | ||||
|             page-break-before: auto; | ||||
|             page-break-after: auto; | ||||
|         } | ||||
|  | ||||
|         .text-per-item-table3 { | ||||
|             border: 1px solid #EAF1FB; | ||||
|             border-top: none; | ||||
|             padding-right: 30px; | ||||
|             box-sizing: border-box; | ||||
|             width: 260px; | ||||
|             /* height: 100px; */ | ||||
|             position: absolute; | ||||
|             right: -25; | ||||
|         } | ||||
|  | ||||
|         .inv-item { | ||||
|             border-color: #d9d9d9; | ||||
|         } | ||||
|  | ||||
|         .no-border { | ||||
|             border: none; | ||||
|         } | ||||
|  | ||||
|         .desc { | ||||
|             font-weight: 100; | ||||
|             text-align: justify; | ||||
|             font-size: 10px; | ||||
|             margin-bottom: 15px; | ||||
|             margin-top:7px; | ||||
|             color:rgba(0, 0, 0, 0.85); | ||||
|         } | ||||
|  | ||||
|         .company-details{ | ||||
|         .invoice-details-container { | ||||
|             text-align: center; | ||||
|             width: 40%; | ||||
|         } | ||||
|  | ||||
|         .company-details h1 { | ||||
|             margin:0; | ||||
|             font-style: normal; | ||||
|             font-weight: 500; | ||||
|         .invoice-details-container h1 { | ||||
|             margin: 0; | ||||
|             font-size: 24px; | ||||
|             line-height: 36px; | ||||
|             text-align: right; | ||||
|         } | ||||
|  | ||||
|         .company-details h4 { | ||||
|             margin:0; | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|         .invoice-details-container h4 { | ||||
|             margin: 0; | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             text-align: right; | ||||
|         } | ||||
|  | ||||
|         .company-details h3 { | ||||
|              margin-bottom:1px; | ||||
|              margin-top:0; | ||||
|         .invoice-details-container h3 { | ||||
|             margin-bottom: 1px; | ||||
|             margin-top: 0; | ||||
|         } | ||||
|  | ||||
|         /* -- Content Wrapper -- */ | ||||
|  | ||||
|         .content-wrapper { | ||||
|             display: block; | ||||
|             margin-top: 60px; | ||||
|             padding-bottom: 20px; | ||||
|         } | ||||
|  | ||||
|         .address-container { | ||||
|             display: block; | ||||
|             padding-top: 20px; | ||||
|         } | ||||
|  | ||||
|         /* -- Company -- */ | ||||
|  | ||||
|         .company-address-container { | ||||
|             padding: 0 0 0 30px; | ||||
|             display: inline; | ||||
|             float: left; | ||||
|             width: 30%; | ||||
|         } | ||||
|  | ||||
|         .company-address-container h1 { | ||||
|             font-weight: bold; | ||||
|             font-size: 15px; | ||||
|             letter-spacing: 0.05em; | ||||
|             margin-bottom: 0; | ||||
|             margin-top: 18px; | ||||
|         } | ||||
|  | ||||
|         .company-address{ | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
|             margin-top: 0px; | ||||
|         } | ||||
|  | ||||
|         /* -- Billing -- */ | ||||
|  | ||||
|         .billing-address-container { | ||||
|             display: block; | ||||
|             /* position: absolute; */ | ||||
|             float: right; | ||||
|             padding: 0 40px 0 0; | ||||
|         } | ||||
|  | ||||
|         .billing-address-label { | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|             padding: 0px; | ||||
|             margin-bottom: 0px; | ||||
|         } | ||||
|  | ||||
|         .billing-address-name { | ||||
|             max-width: 250px; | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             padding: 0px; | ||||
|             margin-top: 0px; | ||||
|             margin-bottom: 0px; | ||||
|         } | ||||
|  | ||||
|         .billing-address{ | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
|             padding: 0px; | ||||
|             margin: 0px; | ||||
|             width: 170px; | ||||
|         } | ||||
|  | ||||
|         /* -- Shipping -- */ | ||||
|  | ||||
|         .shipping-address-container { | ||||
|             display: block; | ||||
|             float: right; | ||||
|             padding: 0 30px 0 0; | ||||
|         } | ||||
|  | ||||
|         .shipping-address-label { | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|             padding: 0px; | ||||
|             margin-bottom: 0px; | ||||
|         } | ||||
|  | ||||
|         .shipping-address-name { | ||||
|             max-width: 250px; | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             padding: 0px; | ||||
|             margin-top: 0px; | ||||
|             margin-bottom: 0px; | ||||
|         } | ||||
|  | ||||
|         .shipping-address { | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
|             padding: 0px; | ||||
|             margin: 0px; | ||||
|             width: 170px; | ||||
|         } | ||||
|  | ||||
|         /* -- Items Table -- */ | ||||
|  | ||||
|         .items-table { | ||||
|             margin-top: 35px; | ||||
|             padding: 0px 30px 10px 30px; | ||||
|             page-break-before: avoid; | ||||
|             page-break-after: auto; | ||||
|         } | ||||
|  | ||||
|         .items-table hr { | ||||
|             height: 0.1px; | ||||
|         } | ||||
|  | ||||
|         .item-table-heading { | ||||
|             font-size: 13.5; | ||||
|             text-align: center; | ||||
|             color: rgba(0, 0, 0, 0.85); | ||||
|             padding: 5px; | ||||
|             color: #55547A; | ||||
|         } | ||||
|  | ||||
|         tr.item-table-heading-row th { | ||||
|             border-bottom: 0.620315px solid #E8E8E8; | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|         } | ||||
|  | ||||
|         tr.item-row td { | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|         } | ||||
|  | ||||
|         .item-cell { | ||||
|             font-size: 13; | ||||
|             text-align: center; | ||||
|             padding: 5px; | ||||
|             padding-top: 10px; | ||||
|             color: #040405; | ||||
|         } | ||||
|  | ||||
|         .item-description { | ||||
|             color: #595959; | ||||
|             font-size: 9px; | ||||
|             line-height: 12px; | ||||
|         } | ||||
|  | ||||
|         /* -- Total Display Table -- */ | ||||
|  | ||||
|         .total-display-container { | ||||
|             padding: 0 25px; | ||||
|         } | ||||
|  | ||||
|         .item-cell-table-hr { | ||||
|             margin: 0 25px 0 30px; | ||||
|         } | ||||
|  | ||||
|         .total-display-table { | ||||
|             box-sizing: border-box; | ||||
|             page-break-inside: avoid; | ||||
|             page-break-before: auto; | ||||
|             page-break-after: auto; | ||||
|             margin-left: 500px; | ||||
|             border: 1px solid #EAF1FB; | ||||
|             border-top: none; | ||||
|         } | ||||
|  | ||||
|         .total-table-attribute-label { | ||||
|             font-size: 12px; | ||||
|             color: #55547A; | ||||
|             text-align: left; | ||||
|             padding-left: 10px; | ||||
|         } | ||||
|  | ||||
|         .total-table-attribute-value { | ||||
|             font-weight: 500; | ||||
|             text-align: right; | ||||
|             font-size: 12px; | ||||
|             color: #040405; | ||||
|             padding-right: 10px; | ||||
|             padding-top: 2px; | ||||
|             padding-bottom: 2px; | ||||
|         } | ||||
|  | ||||
|         .total-border-left { | ||||
|             border: 1px solid #E8E8E8 !important; | ||||
|             border-right: 0px !important; | ||||
|             padding-top: 0px; | ||||
|             padding: 8px !important; | ||||
|         } | ||||
|  | ||||
|         .total-border-right { | ||||
|             border: 1px solid #E8E8E8 !important; | ||||
|             border-left: 0px !important; | ||||
|             padding-top: 0px; | ||||
|             padding: 8px !important; | ||||
|         } | ||||
|  | ||||
|         /* -- Notes -- */ | ||||
|  | ||||
|         .notes { | ||||
|             font-style: normal; | ||||
|             font-weight: 300; | ||||
|             font-size: 12px; | ||||
|             color: #595959; | ||||
|             margin-top: 15px; | ||||
| @ -390,8 +306,6 @@ | ||||
|         } | ||||
|  | ||||
|         .notes-label { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             letter-spacing: 0.05em; | ||||
| @ -401,23 +315,79 @@ | ||||
|             padding-bottom: 10px; | ||||
|         } | ||||
|  | ||||
|         /* -- Helpers -- */ | ||||
|  | ||||
|         .text-primary { | ||||
|             color: #5851DB; | ||||
|         } | ||||
|  | ||||
|         .text-center { | ||||
|             text-align: center | ||||
|         } | ||||
|  | ||||
|         table .text-left { | ||||
|             text-align: left; | ||||
|         } | ||||
|  | ||||
|         table .text-right { | ||||
|             text-align: right; | ||||
|         } | ||||
|  | ||||
|         .border-0 { | ||||
|             border: none; | ||||
|         } | ||||
|  | ||||
|         .py-2 { | ||||
|             padding-top: 2px; | ||||
|             padding-bottom: 2px; | ||||
|         } | ||||
|  | ||||
|         .py-8 { | ||||
|             padding-top: 8px; | ||||
|             padding-bottom: 8px; | ||||
|         } | ||||
|  | ||||
|         .py-3 { | ||||
|             padding: 3px 0; | ||||
|         } | ||||
|  | ||||
|         .pr-20 { | ||||
|             padding-right: 20px; | ||||
|         } | ||||
|  | ||||
|         .pr-10 { | ||||
|             padding-right: 10px; | ||||
|         } | ||||
|  | ||||
|         .pl-20 { | ||||
|             padding-left: 20px; | ||||
|         } | ||||
|  | ||||
|         .pl-10 { | ||||
|             padding-left: 10px; | ||||
|         } | ||||
|  | ||||
|         .pl-0 { | ||||
|             padding-left: 0; | ||||
|         } | ||||
|     </style> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
|     <div class="header-table"> | ||||
|     <div class="header-container"> | ||||
|         <table width="100%"> | ||||
|             <tr> | ||||
|                 @if($logo) | ||||
|                     <td width="60%" class="header-left"> | ||||
|                         <img class="header-logo" src="{{ $logo }}" alt="Company Logo"> | ||||
|                 @else | ||||
|                     <td width="60%" class="header-left" style="padding-top: 0px;"> | ||||
|                         @if($invoice->user->company) | ||||
|                             <h1 class="header-logo"> {{$invoice->user->company->name}} </h1> | ||||
|                         @endif | ||||
|                 @endif | ||||
|                 <td width="60%" class="header-section-left"> | ||||
|                     <img class="header-logo" src="{{ $logo }}" alt="Company Logo"> | ||||
|                     @else | ||||
|                 <td width="60%" class="header-section-left" style="padding-top: 0px;"> | ||||
|                     @if($invoice->user->company) | ||||
|                     <h1 class="header-logo"> {{$invoice->user->company->name}} </h1> | ||||
|                     @endif | ||||
|                     @endif | ||||
|                 </td> | ||||
|                 <td width="40%" class="header-right company-details"> | ||||
|                 <td width="40%" class="header-section-right invoice-details-container"> | ||||
|                     <h1>Invoice</h1> | ||||
|                     <h4>{{$invoice->invoice_number}}</h4> | ||||
|                     <h4>{{$invoice->formattedInvoiceDate}}</h4> | ||||
| @ -426,25 +396,26 @@ | ||||
|         </table> | ||||
|     </div> | ||||
|     <hr> | ||||
|     <div class="wrapper"> | ||||
|         <div class="address"> | ||||
|             <div class="company"> | ||||
|     <div class="content-wrapper"> | ||||
|         <div class="address-container"> | ||||
|             <div class="company-address-container"> | ||||
|                 @include('app.pdf.invoice.partials.company-address') | ||||
|             </div> | ||||
|             <div class="ship-address-container"> | ||||
|             <div class="shipping-address-container"> | ||||
|                 @include('app.pdf.invoice.partials.shipping-address') | ||||
|             </div> | ||||
|             @if($invoice->user->shippingaddress) | ||||
|                 <div class="bill-address-container"> | ||||
|             @else | ||||
|                 <div class="bill-address-container" style="float:right;padding-right:0px;"> | ||||
|             @endif | ||||
|                 @include('app.pdf.invoice.partials.billing-address') | ||||
|             <div class="billing-address-container"> | ||||
|                 @else | ||||
|                 <div class="billing-address-container" style="float:right;padding-right:0px;"> | ||||
|                     @endif | ||||
|                     @include('app.pdf.invoice.partials.billing-address') | ||||
|                 </div> | ||||
|                 <div style="clear: both;"></div> | ||||
|             </div> | ||||
|             <div style="clear: both;"></div> | ||||
|             @include('app.pdf.invoice.partials.table') | ||||
|             @include('app.pdf.invoice.partials.notes') | ||||
|         </div> | ||||
|         @include('app.pdf.invoice.partials.table') | ||||
|         @include('app.pdf.invoice.partials.notes') | ||||
|     </div> | ||||
| </body> | ||||
|  | ||||
| </html> | ||||
|  | ||||
| @ -1,11 +1,13 @@ | ||||
| <!DOCTYPE html> | ||||
| <html> | ||||
|  | ||||
| <head> | ||||
|     <title>Invoice</title> | ||||
|     {{-- <link href="https://fonts.googleapis.com/css?family=Poppins&display=swap" rel="stylesheet"> --}} | ||||
|     <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> | ||||
|     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | ||||
|  | ||||
|     <style type="text/css"> | ||||
|         /* -- Base -- */ | ||||
|  | ||||
|         body { | ||||
|             font-family: "DejaVu Sans"; | ||||
|         } | ||||
| @ -13,146 +15,134 @@ | ||||
|         html { | ||||
|             margin: 0px; | ||||
|             padding: 0px; | ||||
|             margin-top: 50px; | ||||
|         } | ||||
|  | ||||
|         table { | ||||
|             border-collapse: collapse; | ||||
|         } | ||||
|  | ||||
|         .header-line { | ||||
|             color:rgba(0, 0, 0, 0.2); | ||||
|             position: absolute; | ||||
|             top: 80px; | ||||
|             left: 0px; | ||||
|             right: -70px; | ||||
|             width: 100%; | ||||
|         } | ||||
|  | ||||
|         hr { | ||||
|             color:rgba(0, 0, 0, 0.2); | ||||
|             color: rgba(0, 0, 0, 0.2); | ||||
|             border: 0.5px solid #EAF1FB; | ||||
|         } | ||||
|  | ||||
|         .items-table-hr{ | ||||
|             margin: 0 30px 0 30px; | ||||
|         /* -- Header -- */ | ||||
|  | ||||
|         .header-bottom-divider { | ||||
|             color: rgba(0, 0, 0, 0.2); | ||||
|             position: absolute; | ||||
|             top: 100px; | ||||
|             left: 0px; | ||||
|             width: 100%; | ||||
|         } | ||||
|  | ||||
|  | ||||
|         .header-left { | ||||
|         .header-section-left { | ||||
|             padding-top: 45px; | ||||
|             padding-bottom: 45px; | ||||
|             padding-left: 30px; | ||||
|             display:inline-block; | ||||
|             width:30%; | ||||
|             display: inline-block; | ||||
|             width: 30%; | ||||
|         } | ||||
|         .header-table { | ||||
|  | ||||
|         .header-container { | ||||
|             position: absolute; | ||||
|             width: 100%; | ||||
|             height: 150px; | ||||
|             left: 0px; | ||||
|             top: -60px; | ||||
|         } | ||||
|  | ||||
|         .header-logo { | ||||
|             position: absolute; | ||||
|             height: 50px; | ||||
|             text-transform: capitalize; | ||||
|             color: #817AE3; | ||||
|         } | ||||
|         .header-right { | ||||
|             display:inline-block; | ||||
|  | ||||
|         .header-section-right { | ||||
|             display: inline-block; | ||||
|             position: absolute; | ||||
|             right:0; | ||||
|             right: 0; | ||||
|             padding: 15px 30px 15px 0px; | ||||
|             float: right; | ||||
|         } | ||||
|         .inv-flex{ | ||||
|             display:flex; | ||||
|         } | ||||
|         .inv-data{ | ||||
|             text-align:right; | ||||
|             margin-right:120px; | ||||
|         } | ||||
|         .inv-value{ | ||||
|             text-align:left; | ||||
|             margin-left:160px; | ||||
|         } | ||||
|  | ||||
|         .header { | ||||
|             font-size: 20px; | ||||
|             color: rgba(0, 0, 0, 0.7); | ||||
|         } | ||||
|  | ||||
|         .TextColor1 { | ||||
|             font-size: 16px; | ||||
|             color: rgba(0, 0, 0, 0.5); | ||||
|         /* -- Company Address */ | ||||
|  | ||||
|         .company-address-container { | ||||
|             width: auto; | ||||
|             text-transform: capitalize; | ||||
|             margin-bottom: 2px; | ||||
|         } | ||||
|  | ||||
|         @page { | ||||
|             margin-top: 60px !important; | ||||
|         } | ||||
|         .wrapper { | ||||
|            display: block; | ||||
|            padding-top: 50px; | ||||
|            padding-bottom: 20px; | ||||
|         } | ||||
|  | ||||
|         .address { | ||||
|             display: inline-block; | ||||
|             padding-top: 100px; | ||||
|         } | ||||
|  | ||||
|         .bill-add { | ||||
|             display: block; | ||||
|             float:left; | ||||
|             width:40%; | ||||
|             padding: 0 0 0 30px; | ||||
|         } | ||||
|         .company { | ||||
|             padding-left: 30px; | ||||
|             display: inline; | ||||
|             float:left; | ||||
|             width:30%; | ||||
|         } | ||||
|  | ||||
|         .company h1 { | ||||
|             font-style: normal; | ||||
|             font-weight: bold; | ||||
|             font-size: 18px; | ||||
|          .company-address-container h1 { | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             letter-spacing: 0.05em; | ||||
|             margin-bottom: 0px; | ||||
|             margin-top: 10px; | ||||
|         } | ||||
|  | ||||
|         .company-add { | ||||
|             text-align: left; | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 10px; | ||||
|         .company-address { | ||||
|             margin-top: 2px; | ||||
|             font-size: 12px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
|             margin: 0px; | ||||
|         } | ||||
|  | ||||
|          /* -------------------------- */ | ||||
|         /* shipping style */ | ||||
|         .ship-to { | ||||
|         /* -- Content Wrapper  */ | ||||
|  | ||||
|         .content-wrapper { | ||||
|             display: block; | ||||
|             padding-top: 100px; | ||||
|             padding-bottom: 20px; | ||||
|         } | ||||
|  | ||||
|         .main-content { | ||||
|  | ||||
|         } | ||||
|  | ||||
|         .customer-address-container { | ||||
|             display: block; | ||||
|             float: left; | ||||
|             width: 40%; | ||||
|             padding: 0 0 0 30px; | ||||
|         } | ||||
|  | ||||
|         /* -- Shipping -- */ | ||||
|         .shipping-address-container { | ||||
|             float:right; | ||||
|             display: block; | ||||
|         } | ||||
|  | ||||
|         .shipping-address-container--left { | ||||
|             float:left; | ||||
|             display: block; | ||||
|             padding-left: 0; | ||||
|         } | ||||
|  | ||||
|         .shipping-address-label { | ||||
|             padding-top: 5px; | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|             margin-bottom: 0px; | ||||
|         } | ||||
|  | ||||
|         .ship-user-name { | ||||
|         .shipping-address-name { | ||||
|             padding: 0px; | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             margin: 0px; | ||||
|             max-width: 160px; | ||||
|         } | ||||
|  | ||||
|         .ship-user-address { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|         .shipping-address { | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
| @ -160,237 +150,156 @@ | ||||
|             width: 160px; | ||||
|         } | ||||
|  | ||||
|         .ship-user-phone { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
|             margin: 0px; | ||||
|         /* -- Billing -- */ | ||||
|  | ||||
|         .billing-address-container { | ||||
|             display: block; | ||||
|             float: left; | ||||
|         } | ||||
|  | ||||
|          /* -------------------------- */ | ||||
|         /* billing style */ | ||||
|         .bill-to { | ||||
|         .billing-address-label { | ||||
|             padding-top: 5px; | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|             margin-bottom: 0px; | ||||
|         } | ||||
|  | ||||
|         .bill-user-name { | ||||
|         .billing-address-name { | ||||
|             padding: 0px; | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             margin: 0px; | ||||
|             max-width: 160px; | ||||
|         } | ||||
|  | ||||
|         .bill-user-address { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
|             margin:0px; | ||||
|             width: 160px; | ||||
|         } | ||||
|  | ||||
|         .bill-user-phone { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|         .billing-address { | ||||
|             font-size: 10px; | ||||
|             line-height: 15px; | ||||
|             color: #595959; | ||||
|             margin: 0px; | ||||
|             width: 160px; | ||||
|         } | ||||
|  | ||||
|         /*  -- Estimate Details -- */ | ||||
|  | ||||
|         .job-add { | ||||
|         .invoice-details-container { | ||||
|             display: block; | ||||
|             float: right; | ||||
|             padding: 20px 30px 0 0; | ||||
|         } | ||||
|         .amount-due { | ||||
|             background-color: #f2f2f2; | ||||
|         } | ||||
|  | ||||
|         .textRight { | ||||
|             text-align: right; | ||||
|         } | ||||
|  | ||||
|         .textLeft { | ||||
|         .attribute-label { | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|             text-align: left; | ||||
|             color: #55547A | ||||
|         } | ||||
|  | ||||
|         .textStyle1 { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|         } | ||||
|  | ||||
|         .textStyle2 { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|         .attribute-value { | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|             text-align: right; | ||||
|         } | ||||
|         .main-table-header td { | ||||
|             padding: 10px; | ||||
|         } | ||||
|         .main-table-header { | ||||
|             border-bottom: 1px solid red; | ||||
|         } | ||||
|         tr.main-table-header th { | ||||
|             font-style: normal; | ||||
|             font-weight: 600; | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|         } | ||||
|         tr.item-details td { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|         } | ||||
|         .table2 { | ||||
|  | ||||
|         /* -- Items Table -- */ | ||||
|  | ||||
|         .items-table { | ||||
|             margin-top: 35px; | ||||
|             padding: 0px 30px 10px 30px; | ||||
|             page-break-before: avoid; | ||||
|             page-break-after: auto; | ||||
|         } | ||||
|  | ||||
|         .table2 hr { | ||||
|             height:0.1px; | ||||
|         .items-table hr { | ||||
|             height: 0.1px; | ||||
|         } | ||||
|  | ||||
|         .ItemTableHeader { | ||||
|         .item-table-heading { | ||||
|             font-size: 13.5; | ||||
|             text-align: center; | ||||
|             color: rgba(0, 0, 0, 0.85); | ||||
|             padding: 5px; | ||||
|             color: #55547A; | ||||
|         } | ||||
|  | ||||
|         .items { | ||||
|         tr.item-table-heading-row th { | ||||
|             border-bottom: 0.620315px solid #E8E8E8; | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|         } | ||||
|  | ||||
|         tr.item-row td { | ||||
|             font-size: 12px; | ||||
|             line-height: 18px; | ||||
|         } | ||||
|  | ||||
|         .item-cell { | ||||
|             font-size: 13; | ||||
|             color: rgba(0, 0, 0, 0.6); | ||||
|             text-align: center; | ||||
|             padding: 5px; | ||||
|             padding-top: 10px; | ||||
|             color: #040405; | ||||
|         } | ||||
|  | ||||
|         .note-header { | ||||
|             font-size: 13; | ||||
|             color: rgba(0, 0, 0, 0.6); | ||||
|         .item-description { | ||||
|             color: #595959; | ||||
|             font-size: 9px; | ||||
|             line-height: 12px; | ||||
|         } | ||||
|  | ||||
|         .note-text { | ||||
|             font-size: 10; | ||||
|             color: rgba(0, 0, 0, 0.6); | ||||
|         .item-cell-table-hr { | ||||
|             margin: 0 30px 0 30px; | ||||
|         } | ||||
|  | ||||
|         .padd8 { | ||||
|             padding-top: 8px; | ||||
|             padding-bottom: 8px; | ||||
|         /* -- Total Display Table -- */ | ||||
|  | ||||
|         .total-display-container { | ||||
|             padding: 0 25px; | ||||
|         } | ||||
|  | ||||
|         .padd2 { | ||||
|  | ||||
|         .total-display-table { | ||||
|             box-sizing: border-box; | ||||
|             page-break-inside: avoid; | ||||
|             page-break-before: auto; | ||||
|             page-break-after: auto; | ||||
|             margin-left: 500px; | ||||
|             margin-top: 20px; | ||||
|         } | ||||
|  | ||||
|         .total-table-attribute-label { | ||||
|             font-size: 12px; | ||||
|             color: #55547A; | ||||
|             text-align: left; | ||||
|             padding-left: 10px; | ||||
|         } | ||||
|  | ||||
|         .total-table-attribute-value { | ||||
|             font-weight: bold; | ||||
|             text-align: right; | ||||
|             font-size: 12px; | ||||
|             color: #040405; | ||||
|             padding-right: 10px; | ||||
|             padding-top: 2px; | ||||
|             padding-bottom: 2px; | ||||
|         } | ||||
|  | ||||
|         .table3 { | ||||
|             border: 1px solid #EAF1FB; | ||||
|             border-top: none; | ||||
|             box-sizing: border-box; | ||||
|             width: 630px; | ||||
|             page-break-inside: avoid; | ||||
|             page-break-before: auto; | ||||
|             page-break-after: auto; | ||||
|         .total-border-left { | ||||
|             border: 1px solid #E8E8E8 !important; | ||||
|             border-right: 0px !important; | ||||
|             padding-top: 0px; | ||||
|             padding: 8px !important; | ||||
|         } | ||||
|  | ||||
|         .text-per-item-table3 { | ||||
|             border: 1px solid #EAF1FB; | ||||
|             border-top: none; | ||||
|             padding-right: 30px; | ||||
|             box-sizing: border-box; | ||||
|             width: 260px; | ||||
|             /* height: 100px; */ | ||||
|             position: absolute; | ||||
|             right: -25; | ||||
|         } | ||||
|  | ||||
|         td.invoice-total1 { | ||||
|             text-align:left; | ||||
|             padding: 15px 0 15px 10px; | ||||
|             font-size:12px; | ||||
|             line-height: 18px; | ||||
|             color: #55547A; | ||||
|             border-bottom:1px solid #E8E8E8; | ||||
|             border-top:1px solid #E8E8E8; | ||||
|             border-left:1px solid #E8E8E8; | ||||
|         } | ||||
|  | ||||
|         td.invoice-total2 { | ||||
|             font-weight: 500; | ||||
|             text-align: right; | ||||
|             font-size:12px; | ||||
|             line-height: 18px; | ||||
|             padding: 15px 10px 15px 0; | ||||
|             color: #5851DB; | ||||
|             border-bottom:1px solid #E8E8E8; | ||||
|             border-top:1px solid #E8E8E8; | ||||
|             border-right:1px solid #E8E8E8; | ||||
|         } | ||||
|  | ||||
|         .inv-item { | ||||
|             border-color: #d9d9d9; | ||||
|         } | ||||
|  | ||||
|         .no-border { | ||||
|             border: none; | ||||
|         } | ||||
|         .desc { | ||||
|             font-weight: 100; | ||||
|             text-align: justify; | ||||
|             font-size: 10px; | ||||
|             margin-bottom: 15px; | ||||
|             margin-top:7px; | ||||
|             color:rgba(0, 0, 0, 0.85); | ||||
|         } | ||||
|         .company-details h1 { | ||||
|             margin:0; | ||||
|             font-style: normal; | ||||
|             font-weight: bold; | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             letter-spacing: 0.05em; | ||||
|             text-align: left; | ||||
|             max-width: 220px; | ||||
|         } | ||||
|         .company-details h4 { | ||||
|             margin:0; | ||||
|             font-style: normal; | ||||
|             font-weight: 100; | ||||
|             font-size: 18px; | ||||
|             line-height: 25px; | ||||
|             text-align: right; | ||||
|         } | ||||
|         .company-details h3 { | ||||
|              margin-bottom:1px; | ||||
|              margin-top:0; | ||||
|         } | ||||
|         tr.total td { | ||||
|             border-bottom:1px solid #E8E8E8; | ||||
|             border-top:1px solid #E8E8E8; | ||||
|         .total-border-right { | ||||
|             border: 1px solid #E8E8E8 !important; | ||||
|             border-left: 0px !important; | ||||
|             padding-top: 0px; | ||||
|             padding: 8px !important; | ||||
|         } | ||||
|  | ||||
|         /* -- Notes -- */ | ||||
|         .notes { | ||||
|             font-style: normal; | ||||
|             font-weight: 300; | ||||
|             font-size: 12px; | ||||
|             color: #595959; | ||||
|             margin-top: 15px; | ||||
| @ -401,8 +310,6 @@ | ||||
|         } | ||||
|  | ||||
|         .notes-label { | ||||
|             font-style: normal; | ||||
|             font-weight: normal; | ||||
|             font-size: 15px; | ||||
|             line-height: 22px; | ||||
|             letter-spacing: 0.05em; | ||||
| @ -412,67 +319,122 @@ | ||||
|             padding-bottom: 10px; | ||||
|         } | ||||
|  | ||||
|          /* -- Helpers -- */ | ||||
|  | ||||
|         .text-primary { | ||||
|             color: #5851DB; | ||||
|         } | ||||
|  | ||||
|         .text-center { | ||||
|             text-align: center | ||||
|         } | ||||
|  | ||||
|         table .text-left { | ||||
|             text-align: left; | ||||
|         } | ||||
|  | ||||
|         table .text-right { | ||||
|             text-align: right; | ||||
|         } | ||||
|  | ||||
|         .border-0 { | ||||
|             border: none; | ||||
|         } | ||||
|  | ||||
|         .py-2 { | ||||
|             padding-top: 2px; | ||||
|             padding-bottom: 2px; | ||||
|         } | ||||
|  | ||||
|         .py-8 { | ||||
|             padding-top: 8px; | ||||
|             padding-bottom: 8px; | ||||
|         } | ||||
|  | ||||
|         .py-3 { | ||||
|             padding: 3px 0; | ||||
|         } | ||||
|  | ||||
|         .pr-20 { | ||||
|             padding-right: 20px; | ||||
|         } | ||||
|  | ||||
|         .pr-10 { | ||||
|             padding-right: 10px; | ||||
|         } | ||||
|  | ||||
|         .pl-20 { | ||||
|             padding-left: 20px; | ||||
|         } | ||||
|  | ||||
|         .pl-10 { | ||||
|             padding-left: 10px; | ||||
|         } | ||||
|  | ||||
|         .pl-0 { | ||||
|             padding-left: 0; | ||||
|         } | ||||
|     </style> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
|     <div class="header-table"> | ||||
|     <div class="header-container"> | ||||
|         <table width="100%"> | ||||
|             <tr> | ||||
|                 @if($logo) | ||||
|                     <td class="header-left"> | ||||
|                 <td class="header-section-left"> | ||||
|                     @if($logo) | ||||
|                         <img class="header-logo" src="{{ $logo }}" alt="Company Logo"> | ||||
|                     @else | ||||
|                         @if($invoice->user->company) | ||||
|                         <td class="header-left" style="padding-top:0px;"> | ||||
|                             <h1 class="header-logo"> {{$invoice->user->company->name}} </h1> | ||||
|                         @endif | ||||
|                         <h1 class="header-logo"> {{$invoice->user->company->name}} </h1> | ||||
|                     @endif | ||||
|                 </td> | ||||
|                 <td class="header-right company-details"> | ||||
|                 <td class="header-section-right company-address-container"> | ||||
|                     @include('app.pdf.invoice.partials.company-address') | ||||
|                 </td> | ||||
|             </tr> | ||||
|         </table> | ||||
|     </div> | ||||
|  | ||||
|     <hr class="header-line"> | ||||
|     <hr class="header-bottom-divider"> | ||||
|  | ||||
|     <div class="wrapper"> | ||||
|         <div class="address"> | ||||
|             <div class="bill-add"> | ||||
|                 <div style="float:left;"> | ||||
|     <div class="content-wrapper"> | ||||
|         <div class="main-content"> | ||||
|             <div class="customer-address-container"> | ||||
|                 <div class="billing-address-container"> | ||||
|                     @include('app.pdf.invoice.partials.billing-address') | ||||
|                 </div> | ||||
|                 @if($invoice->user->billingaddress) | ||||
|                     <div style="float:right;"> | ||||
|                 <div class="shipping-address-container"> | ||||
|                 @else | ||||
|                     <div style="float:left;"> | ||||
|                 <div class="shipping-address-container--left"> | ||||
|                 @endif | ||||
|                     @include('app.pdf.invoice.partials.shipping-address') | ||||
|                         @include('app.pdf.invoice.partials.shipping-address') | ||||
|                     </div> | ||||
|                     <div style="clear: both;"></div> | ||||
|                 </div> | ||||
|  | ||||
|                 <div class="invoice-details-container"> | ||||
|                     <table> | ||||
|                         <tr> | ||||
|                             <td class="attribute-label">Invoice Number</td> | ||||
|                             <td class="attribute-value">  {{$invoice->invoice_number}}</td> | ||||
|                         </tr> | ||||
|                         <tr> | ||||
|                             <td class="attribute-label">Invoice Date </td> | ||||
|                             <td class="attribute-value">  {{$invoice->formattedInvoiceDate}}</td> | ||||
|                         </tr> | ||||
|                         <tr> | ||||
|                             <td class="attribute-label">Due date</td> | ||||
|                             <td class="attribute-value">  {{$invoice->formattedDueDate}}</td> | ||||
|                         </tr> | ||||
|                     </table> | ||||
|                 </div> | ||||
|                 <div style="clear: both;"></div> | ||||
|             </div> | ||||
|  | ||||
|             <div class="job-add"> | ||||
|                 <table> | ||||
|                     <tr> | ||||
|                         <td class="textStyle1" style="text-align: left; color: #55547A">Invoice Number</td> | ||||
|                         <td class="textStyle2">  {{$invoice->invoice_number}}</td> | ||||
|                     </tr> | ||||
|                     <tr> | ||||
|                         <td class="textStyle1" style="text-align: left; color: #55547A">Invoice Date </td> | ||||
|                         <td class="textStyle2">  {{$invoice->formattedInvoiceDate}}</td> | ||||
|                     </tr> | ||||
|                     <tr> | ||||
|                         <td class="textStyle1" style="text-align: left; color: #55547A">Due date</td> | ||||
|                         <td class="textStyle2">  {{$invoice->formattedDueDate}}</td> | ||||
|                     </tr> | ||||
|                 </table> | ||||
|             </div> | ||||
|             <div style="clear: both;"></div> | ||||
|             @include('app.pdf.invoice.partials.table') | ||||
|             @include('app.pdf.invoice.partials.notes') | ||||
|         </div> | ||||
|         @include('app.pdf.invoice.partials.table') | ||||
|         @include('app.pdf.invoice.partials.notes') | ||||
|     </div> | ||||
| </body> | ||||
|  | ||||
| </html> | ||||
|  | ||||
| @ -1,11 +1,11 @@ | ||||
| @if($invoice->user->billingaddress) | ||||
|     <p class="bill-to">Bill To,</p> | ||||
|     <p class="billing-address-label">Bill To,</p> | ||||
|     @if($invoice->user->billingaddress->name) | ||||
|         <p class="bill-user-name"> | ||||
|         <p class="billing-address-name"> | ||||
|             {{$invoice->user->billingaddress->name}} | ||||
|         </p> | ||||
|     @endif | ||||
|     <p class="bill-user-address"> | ||||
|     <p class="billing-address"> | ||||
|         @if($invoice->user->billingaddress->address_street_1) | ||||
|             {!! nl2br(htmlspecialchars($invoice->user->billingaddress->address_street_1)) !!}<br> | ||||
|         @endif | ||||
| @ -25,7 +25,7 @@ | ||||
|             {{$invoice->user->billingaddress->country->name}}<br> | ||||
|         @endif | ||||
|         @if($invoice->user->billingaddress->phone) | ||||
|             <p class="bill-user-phone"> | ||||
|             <p class="billing-address"> | ||||
|                 Phone :{{$invoice->user->billingaddress->phone}} | ||||
|             </p> | ||||
|         @endif | ||||
|  | ||||
| @ -3,7 +3,7 @@ | ||||
| @endif | ||||
|  | ||||
| @if($company_address) | ||||
|     <p class="company-add"> | ||||
|     <p class="company-address"> | ||||
|         @if($company_address->addresses[0]['address_street_1']) | ||||
|             {!! nl2br(htmlspecialchars($company_address->addresses[0]['address_street_1'])) !!} <br> | ||||
|         @endif | ||||
|  | ||||
| @ -1,11 +1,11 @@ | ||||
| @if($invoice->user->shippingaddress) | ||||
|     <p class="ship-to">Ship To,</p> | ||||
|     <p class="shipping-address-label">Ship To,</p> | ||||
|     @if($invoice->user->shippingaddress->name) | ||||
|         <p class="ship-user-name"> | ||||
|         <p class="shipping-address-name"> | ||||
|             {{$invoice->user->shippingaddress->name}} | ||||
|         </p> | ||||
|     @endif | ||||
|     <p class="ship-user-address"> | ||||
|     <p class="shipping-address"> | ||||
|         @if($invoice->user->shippingaddress->address_street_1) | ||||
|             {!! nl2br(htmlspecialchars($invoice->user->shippingaddress->address_street_1)) !!}<br> | ||||
|         @endif | ||||
| @ -30,8 +30,8 @@ | ||||
|             {{$invoice->user->shippingaddress->country->name}}<br> | ||||
|         @endif | ||||
|  | ||||
|         @if($invoice->user->phone) | ||||
|             <p class="ship-user-phone"> | ||||
|         @if($invoice->user->shippingaddress->phone) | ||||
|             <p class="shipping-address"> | ||||
|                 Phone :{{$invoice->user->shippingaddress->phone}} | ||||
|             </p> | ||||
|         @endif | ||||
|  | ||||
| @ -1,46 +1,49 @@ | ||||
| <table width="100%" class="table2" cellspacing="0" border="0"> | ||||
|     <tr class="main-table-header"> | ||||
|         <th width="2%" class="ItemTableHeader" style="text-align: right; color: #55547A; padding-right: 20px">#</th> | ||||
|         <th width="40%" class="ItemTableHeader" style="text-align: left; color: #55547A; padding-left: 0px">Items</th> | ||||
|         <th class="ItemTableHeader" style="text-align: right; color: #55547A; padding-right: 20px">Quantity</th> | ||||
|         <th class="ItemTableHeader" style="text-align: right; color: #55547A; padding-right: 20px">Price</th> | ||||
| <table width="100%" class="items-table" cellspacing="0" border="0"> | ||||
|     <tr class="item-table-heading-row"> | ||||
|         <th width="2%" class="item-table-heading text-right pr-20">#</th> | ||||
|         <th width="40%" class="item-table-heading text-left pl-0">Items</th> | ||||
|         <th class="item-table-heading text-right pr-20">Quantity</th> | ||||
|         <th class="item-table-heading pr-20 text-right">Price</th> | ||||
|         @if($invoice->discount_per_item === 'YES') | ||||
|         <th class="ItemTableHeader" style="text-align: right; color: #55547A; padding-left: 10px">Discount</th> | ||||
|         <th class="item-table-heading text-right pl-10">Discount</th> | ||||
|         @endif | ||||
|         <th class="ItemTableHeader" style="text-align: right; color: #55547A;">Amount</th> | ||||
|         <th class="item-table-heading text-right">Amount</th> | ||||
|     </tr> | ||||
|     @php | ||||
|         $index = 1 | ||||
|     @endphp | ||||
|     @foreach ($invoice->items as $item) | ||||
|         <tr class="item-details"> | ||||
|         <tr class="item-row"> | ||||
|             <td | ||||
|                 class="inv-item items" | ||||
|                 style="text-align: right; color: #040405; padding-right: 20px; vertical-align: top;" | ||||
|                 class="item-cell text-right pr-20" | ||||
|                 style="vertical-align: top;" | ||||
|             > | ||||
|                 {{$index}} | ||||
|             </td> | ||||
|             <td | ||||
|                 class="inv-item items" | ||||
|                 style="text-align: left; color: #040405;padding-left: 0px" | ||||
|                 class="item-cell text-left pl-0" | ||||
|                 style="vertical-align: top;" | ||||
|             > | ||||
|                 <span>{{ $item->name }}</span><br> | ||||
|                 <span style="text-align: left; color: #595959; font-size: 9px; font-weight:300; line-height: 12px;">{!! nl2br(htmlspecialchars($item->description)) !!}</span> | ||||
|                 <span class="item-description">{!! nl2br(htmlspecialchars($item->description)) !!}</span> | ||||
|             </td> | ||||
|             <td | ||||
|                 class="inv-item items" | ||||
|                 style="text-align: right; color: #040405; padding-right: 20px" | ||||
|                 class="item-cell pr-20 text-right" | ||||
|                 style="vertical-align: top;" | ||||
|             > | ||||
|                 {{$item->quantity}} | ||||
|             </td> | ||||
|             <td | ||||
|                 class="inv-item items" | ||||
|                 style="text-align: right; color: #040405; padding-right: 20px" | ||||
|                 class="item-cell text-right pr-20" | ||||
|                 style="vertical-align: top;" | ||||
|             > | ||||
|                 {!! format_money_pdf($item->price, $invoice->user->currency) !!} | ||||
|             </td> | ||||
|             @if($invoice->discount_per_item === 'YES') | ||||
|                 <td class="inv-item items" style="text-align: right; color: #040405; padding-left: 10px"> | ||||
|                 <td | ||||
|                     class="item-cell text-right pl-10" | ||||
|                     style="vertical-align: top;" | ||||
|                 > | ||||
|                     @if($item->discount_type === 'fixed') | ||||
|                         {!! format_money_pdf($item->discount_val, $invoice->user->currency) !!} | ||||
|                     @endif | ||||
| @ -50,8 +53,8 @@ | ||||
|                 </td> | ||||
|             @endif | ||||
|             <td | ||||
|                 class="inv-item items" | ||||
|                 style="text-align: right; color: #040405;" | ||||
|                 class="item-cell text-right" | ||||
|                 style="vertical-align: top;" | ||||
|             > | ||||
|                 {!! format_money_pdf($item->total, $invoice->user->currency) !!} | ||||
|             </td> | ||||
| @ -62,74 +65,74 @@ | ||||
|     @endforeach | ||||
| </table> | ||||
|  | ||||
| <hr class="items-table-hr"> | ||||
| <hr class="item-cell-table-hr"> | ||||
|  | ||||
| <table width="100%" cellspacing="0px" style="margin-left:420px; margin-top: 10px" border="0" class="table3 @if(count($invoice->items) > 12) page-break @endif"> | ||||
|     <tr> | ||||
|         <td class="no-border" style="color: #55547A; padding-left:10px;  font-size:12px;">Subtotal</td> | ||||
|         <td class="no-border items padd2" | ||||
|             style="padding-right:10px; text-align: right;  font-size:12px; color: #040405; font-weight: 500;">{!! format_money_pdf($invoice->sub_total, $invoice->user->currency) !!}</td> | ||||
|     </tr> | ||||
|  | ||||
|     @if ($invoice->tax_per_item === 'YES') | ||||
|         @for ($i = 0; $i < count($labels); $i++) | ||||
|             <tr> | ||||
|                 <td class="no-border" style="padding-left:10px; text-align:left; font-size:12px;  color: #55547A;"> | ||||
|                     {{$labels[$i]}} | ||||
|                 </td> | ||||
|                 <td class="no-border items padd2" style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px;  color: #040405"> | ||||
|                     {!! format_money_pdf($taxes[$i], $invoice->user->currency) !!} | ||||
|                 </td> | ||||
|             </tr> | ||||
|         @endfor | ||||
|     @else | ||||
|         @foreach ($invoice->taxes as $tax) | ||||
|             <tr> | ||||
|                 <td class="no-border" style="padding-left:10px; text-align:left; font-size:12px;  color: #55547A;"> | ||||
|                     {{$tax->name.' ('.$tax->percent.'%)'}} | ||||
|                 </td> | ||||
|                 <td class="no-border items padd2" style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px;  color: #040405"> | ||||
|                     {!! format_money_pdf($tax->amount, $invoice->user->currency) !!} | ||||
|                 </td> | ||||
|             </tr> | ||||
|         @endforeach | ||||
|     @endif | ||||
|  | ||||
|     @if ($invoice->discount_per_item === 'NO') | ||||
| <div class="total-display-container"> | ||||
|     <table width="100%" cellspacing="0px" border="0" class="total-display-table @if(count($invoice->items) > 12) page-break @endif"> | ||||
|         <tr> | ||||
|             <td class="no-border" style="padding-left:10px; text-align:left; font-size:12px; color: #55547A;"> | ||||
|                 @if($invoice->discount_type === 'fixed') | ||||
|                     Discount | ||||
|                 @endif | ||||
|                 @if($invoice->discount_type === 'percentage') | ||||
|                     Discount ({{$invoice->discount}}%) | ||||
|                 @endif | ||||
|             </td> | ||||
|             <td class="no-border items padd2" style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px;  color: #040405"> | ||||
|                 @if($invoice->discount_type === 'fixed') | ||||
|                     {!! format_money_pdf($invoice->discount_val, $invoice->user->currency) !!} | ||||
|                 @endif | ||||
|                 @if($invoice->discount_type === 'percentage') | ||||
|                     {!! format_money_pdf($invoice->discount_val, $invoice->user->currency) !!} | ||||
|                 @endif | ||||
|             <td class="border-0 total-table-attribute-label">Subtotal</td> | ||||
|             <td class="border-0 item-cell py-2 total-table-attribute-value"> | ||||
|                 {!! format_money_pdf($invoice->sub_total, $invoice->user->currency) !!} | ||||
|             </td> | ||||
|         </tr> | ||||
|     @endif | ||||
|     <tr> | ||||
|         <td style="padding:3px 0px"></td> | ||||
|         <td style="padding:3px 0px"></td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|         <td class="no-border total-border-left" | ||||
|             style="padding-left:10px; padding-bottom:10px; text-align:left; padding-top:20px; font-size:12px;  color: #55547A;" | ||||
|         > | ||||
|             <label class="total-bottom"> Total </label> | ||||
|         </td> | ||||
|         <td | ||||
|             class="no-border total-border-right items padd8" | ||||
|             style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px;  padding-top:20px; color: #5851DB" | ||||
|         > | ||||
|             {!! format_money_pdf($invoice->total, $invoice->user->currency)!!} | ||||
|         </td> | ||||
|     </tr> | ||||
| </table> | ||||
|  | ||||
|         @if ($invoice->tax_per_item === 'YES') | ||||
|             @for ($i = 0; $i < count($labels); $i++) | ||||
|                 <tr> | ||||
|                     <td class="border-0 total-table-attribute-label"> | ||||
|                         {{$labels[$i]}} | ||||
|                     </td> | ||||
|                     <td class="border-0 item-cell py-2 total-table-attribute-value"> | ||||
|                         {!! format_money_pdf($taxes[$i], $invoice->user->currency) !!} | ||||
|                     </td> | ||||
|                 </tr> | ||||
|             @endfor | ||||
|         @else | ||||
|             @foreach ($invoice->taxes as $tax) | ||||
|                 <tr> | ||||
|                     <td class="border-0 total-table-attribute-label"> | ||||
|                         {{$tax->name.' ('.$tax->percent.'%)'}} | ||||
|                     </td> | ||||
|                     <td class="border-0 item-cell py-2 total-table-attribute-value"> | ||||
|                         {!! format_money_pdf($tax->amount, $invoice->user->currency) !!} | ||||
|                     </td> | ||||
|                 </tr> | ||||
|             @endforeach | ||||
|         @endif | ||||
|  | ||||
|         @if ($invoice->discount_per_item === 'NO') | ||||
|             <tr> | ||||
|                 <td class="border-0 total-table-attribute-label"> | ||||
|                     @if($invoice->discount_type === 'fixed') | ||||
|                         Discount | ||||
|                     @endif | ||||
|                     @if($invoice->discount_type === 'percentage') | ||||
|                         Discount ({{$invoice->discount}}%) | ||||
|                     @endif | ||||
|                 </td> | ||||
|                 <td class="border-0 item-cell py-2 total-table-attribute-value" > | ||||
|                     @if($invoice->discount_type === 'fixed') | ||||
|                         {!! format_money_pdf($invoice->discount_val, $invoice->user->currency) !!} | ||||
|                     @endif | ||||
|                     @if($invoice->discount_type === 'percentage') | ||||
|                         {!! format_money_pdf($invoice->discount_val, $invoice->user->currency) !!} | ||||
|                     @endif | ||||
|                 </td> | ||||
|             </tr> | ||||
|         @endif | ||||
|         <tr> | ||||
|             <td class="py-3"></td> | ||||
|             <td class="py-3"></td> | ||||
|         </tr> | ||||
|         <tr> | ||||
|             <td class="border-0 total-border-left total-table-attribute-label"> | ||||
|                 Total | ||||
|             </td> | ||||
|             <td | ||||
|                 class="border-0 total-border-right item-cell py-8 total-table-attribute-value text-primary" | ||||
|             > | ||||
|                 {!! format_money_pdf($invoice->total, $invoice->user->currency)!!} | ||||
|             </td> | ||||
|         </tr> | ||||
|     </table> | ||||
| </div> | ||||
|  | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user
	