mirror of
https://github.com/crater-invoice/crater.git
synced 2025-10-27 11:41: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