Compare commits

..

126 Commits

Author SHA1 Message Date
fcd992179e New translations en.json (Portuguese, Brazilian) 2023-08-12 08:19:36 +05:30
d057b27560 New translations en.json (Portuguese, Brazilian) 2023-08-07 20:19:25 +05:30
6c66f0634b New translations en.json (Portuguese, Brazilian) 2023-08-07 19:04:35 +05:30
b6eb1eef78 New translations en.json (Chinese Traditional) 2023-08-07 07:38:44 +05:30
da184cb13e New translations en.json (Indonesian) 2023-07-11 09:47:03 +05:30
ff8519764e New translations en.json (Indonesian) 2023-07-11 08:48:15 +05:30
55163888b3 New translations en.json (Thai) 2023-06-30 13:35:54 +05:30
0ea6bce713 New translations en.json (Thai) 2023-06-30 12:36:24 +05:30
c8ea2a7f3d New translations en.json (Indonesian) 2023-06-28 13:48:53 +05:30
078d928206 New translations en.json (Indonesian) 2023-06-28 12:45:33 +05:30
01f01b8607 New translations en.json (Indonesian) 2023-06-28 10:27:56 +05:30
1314821bb1 New translations en.json (Portuguese) 2023-06-24 05:39:29 +05:30
40d2d7435b New translations en.json (Portuguese) 2023-06-24 04:35:14 +05:30
36f334dc87 New translations en.json (Arabic) 2023-06-22 19:02:20 +05:30
dfd13bf9de New translations en.json (Vietnamese) 2023-03-21 09:35:54 +05:30
afb8cab71a New translations en.json (Indonesian) 2023-02-20 15:32:58 +05:30
6f0c9c6923 New translations en.json (Indonesian) 2023-02-20 14:37:28 +05:30
a7b1fe87ea New translations en.json (Vietnamese) 2023-02-20 09:06:22 +05:30
a2970402b9 New translations en.json (Dutch) 2023-01-31 03:48:53 +05:30
2934b9fc3f New translations en.json (Dutch) 2023-01-31 02:45:51 +05:30
ebf19636e1 New translations en.json (Dutch) 2023-01-31 00:13:27 +05:30
cbc13d4884 New translations en.json (Portuguese, Brazilian) 2023-01-19 03:18:36 +05:30
b02803e7c5 New translations en.json (Portuguese, Brazilian) 2023-01-19 00:07:06 +05:30
194a8cb235 New translations en.json (Slovenian) 2023-01-16 22:57:18 +05:30
8fd045e378 New translations en.json (Ukrainian) 2023-01-12 00:19:53 +05:30
7a11fbd02a New translations en.json (Ukrainian) 2023-01-11 21:44:54 +05:30
5bc213299f New translations en.json (Indonesian) 2023-01-09 09:51:37 +05:30
2b5b4ab603 New translations en.json (Indonesian) 2023-01-09 07:14:38 +05:30
8a47cab96c New translations en.json (Slovenian) 2023-01-02 04:05:02 +05:30
606fed3e68 New translations en.json (Indonesian) 2023-01-01 18:45:46 +05:30
d227ad4e6b New translations en.json (Indonesian) 2023-01-01 17:23:20 +05:30
835d61d73c New translations en.json (Slovenian) 2022-12-29 02:56:33 +05:30
6bb89db25e New translations en.json (Slovenian) 2022-12-29 01:50:14 +05:30
3f0fd04ad3 New translations en.json (Slovenian) 2022-12-28 23:14:40 +05:30
6c3e1b1135 New translations en.json (Dutch) 2022-12-20 02:01:06 +05:30
e331bc18ab New translations en.json (Slovenian) 2022-12-14 22:49:38 +05:30
67549fd299 New translations en.json (Polish) 2022-12-09 20:46:22 +05:30
e6cea15a5b New translations en.json (Polish) 2022-12-09 18:04:16 +05:30
9471cfbca3 New translations en.json (Slovenian) 2022-12-08 04:30:22 +05:30
e0da5e8eb8 New translations en.json (Slovenian) 2022-12-08 01:21:06 +05:30
1328e36306 New translations en.json (Dutch) 2022-11-25 05:47:55 +05:30
5a5ed65202 New translations en.json (Serbian (Latin)) 2022-11-19 10:57:31 +05:30
598e5801bc New translations en.json (Serbian (Latin)) 2022-11-19 08:42:25 +05:30
427fb7675f New translations en.json (German) 2022-11-13 21:21:02 +05:30
4ce313b10a New translations en.json (Spanish) 2022-11-11 23:16:29 +05:30
12d4107c13 New translations en.json (Spanish) 2022-11-11 22:16:50 +05:30
41ba8fc849 New translations en.json (Czech) 2022-11-08 00:58:08 +05:30
2ba2d83478 New translations en.json (Czech) 2022-11-07 22:05:50 +05:30
f421cd1677 New translations en.json (German) 2022-11-03 00:39:58 +05:30
16b4533892 New translations en.json (Portuguese, Brazilian) 2022-10-26 10:18:25 +05:30
3afdfe3fda New translations en.json (Portuguese, Brazilian) 2022-10-26 07:02:03 +05:30
ebdfd83b04 New translations en.json (Polish) 2022-10-13 22:59:48 +05:30
26ba2d8d28 New translations en.json (Croatian) 2022-10-13 18:34:22 +05:30
22377bc407 New translations en.json (Croatian) 2022-10-13 17:32:00 +05:30
65b7a2c78e New translations en.json (Italian) 2022-10-13 12:59:46 +05:30
d8ca49572b New translations en.json (Latvian) 2022-10-05 00:06:48 +05:30
f28d67629f New translations en.json (Latvian) 2022-10-04 21:56:25 +05:30
fa9c0824d2 New translations en.json (Latvian) 2022-10-04 00:32:20 +05:30
d8ad7d1c09 New translations en.json (Portuguese, Brazilian) 2022-09-10 03:40:23 +05:30
f3eba0ca98 New translations en.json (Portuguese, Brazilian) 2022-09-10 02:09:33 +05:30
0046ce1675 New translations en.json (Polish) 2022-09-01 03:43:25 +05:30
1ea4048e98 New translations en.json (Indonesian) 2022-08-31 18:04:54 +05:30
3922da67db New translations en.json (Indonesian) 2022-08-31 16:27:34 +05:30
d939c7340f New translations en.json (Croatian) 2022-08-27 23:30:48 +05:30
a1540dcbc1 New translations en.json (Portuguese) 2022-08-24 23:05:08 +05:30
df89e1d248 New translations en.json (Portuguese) 2022-08-22 04:17:10 +05:30
c4d79a8b63 New translations en.json (Portuguese) 2022-08-18 05:00:37 +05:30
5d875af7be New translations en.json (Portuguese) 2022-08-18 03:51:37 +05:30
9734ccf9fa New translations en.json (Portuguese, Brazilian) 2022-08-17 01:37:01 +05:30
8080fe86ca New translations en.json (Portuguese, Brazilian) 2022-08-17 00:37:08 +05:30
43b3f00dff New translations en.json (Ukrainian) 2022-08-05 04:14:30 +05:30
9f3b39a685 New translations en.json (French) 2022-08-04 23:25:53 +05:30
309b2e0888 New translations en.json (Portuguese) 2022-08-04 23:25:44 +05:30
ca60a4830d New translations en.json (Arabic) 2022-07-29 02:19:24 +05:30
ee96724b81 New translations en.json (Arabic) 2022-07-29 00:32:48 +05:30
c3250d6141 New translations en.json (Chinese Traditional) 2022-07-12 23:05:23 +05:30
d2a8477087 New translations en.json (Ukrainian) 2022-07-07 16:46:22 +05:30
718657b0a4 New translations en.json (Ukrainian) 2022-07-07 14:28:39 +05:30
1acac8f129 New translations en.json (Ukrainian) 2022-06-30 10:14:50 +05:30
176b207335 New translations en.json (Ukrainian) 2022-06-30 09:11:15 +05:30
77d7ae0fe4 New translations en.json (French) 2022-06-29 01:55:58 +05:30
fc222fc6de New translations en.json (Dutch) 2022-06-28 03:38:07 +05:30
fa9d28e66b New translations en.json (Dutch) 2022-06-28 02:42:41 +05:30
a87ef11edc New translations en.json (French) 2022-06-27 18:36:52 +05:30
221f272da9 New translations en.json (Ukrainian) 2022-06-27 15:50:41 +05:30
b022cbad59 New translations en.json (French) 2022-06-26 19:57:51 +05:30
d342bc9771 New translations en.json (Dutch) 2022-06-21 16:37:06 +05:30
c236012f4e New translations en.json (Russian) 2022-06-19 08:16:35 +05:30
c50a2a5988 New translations en.json (Russian) 2022-06-16 16:25:04 +05:30
f07f488148 New translations en.json (Russian) 2022-06-16 06:23:50 +05:30
46ba42478f New translations en.json (Thai) 2022-06-15 18:57:58 +05:30
ddfea9d827 New translations en.json (Dutch) 2022-06-11 17:49:35 +05:30
25aa4ac198 New translations en.json (Spanish) 2022-06-09 22:05:46 +05:30
2081580640 New translations en.json (Portuguese, Brazilian) 2022-06-04 21:31:48 +05:30
b20277d1b7 New translations en.json (Portuguese, Brazilian) 2022-06-04 20:25:30 +05:30
9fded639b9 New translations en.json (Czech) 2022-05-30 17:46:11 +05:30
a19266a29c New translations en.json (Spanish) 2022-05-29 05:35:33 +05:30
d07d2243a9 Update source file en.json 2022-05-29 05:35:30 +05:30
19a23983ab New translations en.json (Serbian (Latin)) 2022-05-28 12:01:36 +05:30
3545ebb7a4 New translations en.json (French) 2022-05-28 12:01:35 +05:30
e0ab4136a9 New translations en.json (Spanish) 2022-05-28 12:01:33 +05:30
7ee0ceba0c New translations en.json (Arabic) 2022-05-28 12:01:32 +05:30
2ca332f33c New translations en.json (Czech) 2022-05-28 12:01:31 +05:30
fd3a1524ad New translations en.json (German) 2022-05-28 12:01:30 +05:30
889df7b9a6 New translations en.json (Greek) 2022-05-28 12:01:29 +05:30
73f36981e4 New translations en.json (Finnish) 2022-05-28 12:01:28 +05:30
e3460384d0 New translations en.json (Italian) 2022-05-28 12:01:26 +05:30
a793d53b31 New translations en.json (Japanese) 2022-05-28 12:01:25 +05:30
59854f016b New translations en.json (Lithuanian) 2022-05-28 12:01:24 +05:30
411e2bf7b7 New translations en.json (Dutch) 2022-05-28 12:01:23 +05:30
fc46391dec New translations en.json (Polish) 2022-05-28 12:01:22 +05:30
15bfbfdaf3 New translations en.json (Romanian) 2022-05-28 12:01:21 +05:30
9d7cc7548a New translations en.json (Portuguese) 2022-05-28 12:01:20 +05:30
7e460249bc New translations en.json (Slovak) 2022-05-28 12:01:19 +05:30
fd68cea4de New translations en.json (Slovenian) 2022-05-28 12:01:18 +05:30
0268b808d5 New translations en.json (Swedish) 2022-05-28 12:01:16 +05:30
532422feca New translations en.json (Turkish) 2022-05-28 12:01:15 +05:30
f3cb1f6af6 New translations en.json (Chinese Traditional) 2022-05-28 12:01:14 +05:30
5b0e1fc5a8 New translations en.json (Vietnamese) 2022-05-28 12:01:13 +05:30
6f68f57791 New translations en.json (Indonesian) 2022-05-28 12:01:12 +05:30
6db63b3aae New translations en.json (Persian) 2022-05-28 12:01:11 +05:30
c8e7378725 New translations en.json (Croatian) 2022-05-28 12:01:08 +05:30
cf1e90aa40 New translations en.json (Latvian) 2022-05-28 12:01:06 +05:30
3d476f66f9 New translations en.json (Hindi) 2022-05-28 12:01:05 +05:30
5f0925416e New translations en.json (Russian) 2022-05-28 12:01:04 +05:30
a3a1f51d34 New translations en.json (Portuguese, Brazilian) 2022-05-28 12:01:03 +05:30
120 changed files with 8843 additions and 7435 deletions

View File

@ -1,162 +0,0 @@
name: Build PR Image
on:
pull_request:
types: [opened,synchronize,reopened,closed]
jobs:
build-application:
name: Build and Push `application`
runs-on: ubuntu-latest
if: ${{ github.event_name != 'pull_request' || github.event.action != 'closed' }}
outputs:
tags: ${{ steps.meta.outputs.tags }}
steps:
- name: Checkout git repo
uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Generate UUID image name
id: uuid
run: echo "UUID_TAG_APP=$(uuidgen)" >> $GITHUB_ENV
- name: Docker metadata
id: meta
uses: docker/metadata-action@v3
with:
images: registry.uffizzi.com/${{ env.UUID_TAG_APP }}
tags: type=raw,value=60d
- name: Build and Push Image to registry.uffizzi.com ephemeral registry
uses: docker/build-push-action@v2
with:
push: true
context: ./
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
file: ./uffizzi/Dockerfile
cache-from: type=gha
cache-to: type=gha,mode=max
build-nginx:
name: Build and Push `nginx`
runs-on: ubuntu-latest
if: ${{ github.event_name != 'pull_request' || github.event.action != 'closed' }}
outputs:
tags: ${{ steps.meta.outputs.tags }}
steps:
- name: Checkout git repo
uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Generate UUID image name
id: uuid
run: echo "UUID_TAG_NGINX=$(uuidgen)" >> $GITHUB_ENV
- name: Docker metadata
id: meta
uses: docker/metadata-action@v3
with:
images: registry.uffizzi.com/${{ env.UUID_TAG_NGINX }}
tags: type=raw,value=60d
- name: Build and Push Image to Uffizzi ephemeral registry
uses: docker/build-push-action@v2
with:
push: true
context: ./
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
file: ./uffizzi/nginx/Dockerfile
cache-from: type=gha
cache-to: type=gha,mode=max
build-crond:
name: Build and Push `crond`
runs-on: ubuntu-latest
if: ${{ github.event_name != 'pull_request' || github.event.action != 'closed' }}
outputs:
tags: ${{ steps.meta.outputs.tags }}
steps:
- name: Checkout git repo
uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Generate UUID image name
id: uuid
run: echo "UUID_TAG_CROND=$(uuidgen)" >> $GITHUB_ENV
- name: Docker metadata
id: meta
uses: docker/metadata-action@v3
with:
images: registry.uffizzi.com/${{ env.UUID_TAG_CROND }}
tags: type=raw,value=60d
- name: Build and Push Image to registry.uffizzi.com ephemeral registry
uses: docker/build-push-action@v2
with:
push: true
context: ./
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
file: ./uffizzi/crond/Dockerfile
cache-from: type=gha
cache-to: type=gha,mode=max
render-compose-file:
name: Render Docker Compose File
# Pass output of this workflow to another triggered by `workflow_run` event.
runs-on: ubuntu-latest
outputs:
compose-file-cache-key: ${{ steps.hash.outputs.hash }}
needs:
- build-application
- build-nginx
- build-crond
steps:
- name: Checkout git repo
uses: actions/checkout@v3
- name: Render Compose File
run: |
APP_IMAGE=$(echo ${{ needs.build-application.outputs.tags }})
export APP_IMAGE
NGINX_IMAGE=$(echo ${{ needs.build-nginx.outputs.tags }})
export NGINX_IMAGE
CROND_IMAGE=$(echo ${{ needs.build-crond.outputs.tags }})
export CROND_IMAGE
# Render simple template from environment variables.
envsubst < ./uffizzi/docker-compose.uffizzi.yml > docker-compose.rendered.yml
cat docker-compose.rendered.yml
- name: Upload Rendered Compose File as Artifact
uses: actions/upload-artifact@v3
with:
name: preview-spec
path: docker-compose.rendered.yml
retention-days: 2
- name: Serialize PR Event to File
run: |
cat << EOF > event.json
${{ toJSON(github.event) }}
EOF
- name: Upload PR Event as Artifact
uses: actions/upload-artifact@v3
with:
name: preview-spec
path: event.json
retention-days: 2
delete-preview:
name: Call for Preview Deletion
runs-on: ubuntu-latest
if: ${{ github.event.action == 'closed' }}
steps:
# If this PR is closing, we will not render a compose file nor pass it to the next workflow.
- name: Serialize PR Event to File
run: echo '${{ toJSON(github.event) }}' > event.json
- name: Upload PR Event as Artifact
uses: actions/upload-artifact@v3
with:
name: preview-spec
path: event.json
retention-days: 2

View File

@ -1,84 +0,0 @@
name: Deploy Uffizzi Preview
on:
workflow_run:
workflows:
- "Build PR Image"
types:
- completed
jobs:
cache-compose-file:
name: Cache Compose File
runs-on: ubuntu-latest
outputs:
compose-file-cache-key: ${{ env.COMPOSE_FILE_HASH }}
pr-number: ${{ env.PR_NUMBER }}
steps:
- name: 'Download artifacts'
# Fetch output (zip archive) from the workflow run that triggered this workflow.
uses: actions/github-script@v6
with:
script: |
let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: context.payload.workflow_run.id,
});
let matchArtifact = allArtifacts.data.artifacts.filter((artifact) => {
return artifact.name == "preview-spec"
})[0];
let download = await github.rest.actions.downloadArtifact({
owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: matchArtifact.id,
archive_format: 'zip',
});
let fs = require('fs');
fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/preview-spec.zip`, Buffer.from(download.data));
- name: 'Unzip artifact'
run: unzip preview-spec.zip
- name: Read Event into ENV
run: |
echo 'EVENT_JSON<<EOF' >> $GITHUB_ENV
cat event.json >> $GITHUB_ENV
echo 'EOF' >> $GITHUB_ENV
- name: Hash Rendered Compose File
id: hash
# If the previous workflow was triggered by a PR close event, we will not have a compose file artifact.
if: ${{ fromJSON(env.EVENT_JSON).action != 'closed' }}
run: echo "COMPOSE_FILE_HASH=$(md5sum docker-compose.rendered.yml | awk '{ print $1 }')" >> $GITHUB_ENV
- name: Cache Rendered Compose File
if: ${{ fromJSON(env.EVENT_JSON).action != 'closed' }}
uses: actions/cache@v3
with:
path: docker-compose.rendered.yml
key: ${{ env.COMPOSE_FILE_HASH }}
- name: Read PR Number From Event Object
id: pr
run: echo "PR_NUMBER=${{ fromJSON(env.EVENT_JSON).number }}" >> $GITHUB_ENV
- name: DEBUG - Print Job Outputs
if: ${{ runner.debug }}
run: |
echo "PR number: ${{ env.PR_NUMBER }}"
echo "Compose file hash: ${{ env.COMPOSE_FILE_HASH }}"
cat event.json
deploy-uffizzi-preview:
name: Use Remote Workflow to Preview on Uffizzi
needs:
- cache-compose-file
uses: UffizziCloud/preview-action/.github/workflows/reusable.yaml@v2.6.1
with:
# If this workflow was triggered by a PR close event, cache-key will be an empty string
# and this reusable workflow will delete the preview deployment.
compose-file-cache-key: ${{ needs.cache-compose-file.outputs.compose-file-cache-key }}
compose-file-cache-path: docker-compose.rendered.yml
server: https://app.uffizzi.com/
pr-number: ${{ needs.cache-compose-file.outputs.pr-number }}
permissions:
contents: read
pull-requests: write
id-token: write

1
.gitignore vendored
View File

@ -16,4 +16,3 @@ Homestead.yaml
.gitkeep
/public/docs
/.scribe
!storage/fonts/.gitkeep

View File

@ -1,4 +1,4 @@
FROM php:8.1-fpm
FROM php:7.4-fpm
# Arguments defined in docker-compose.yml
ARG user

View File

@ -103,7 +103,6 @@ class CustomerStatsController extends Controller
)
->whereCompany()
->whereCustomer($customer->id)
->where('status', '<>', Invoice::STATUS_DRAFT)
->sum('total');
$totalReceipts = Payment::whereBetween(
'payment_date',

View File

@ -104,7 +104,6 @@ class DashboardController extends Controller
'invoice_date',
[$startDate->format('Y-m-d'), $start->format('Y-m-d')]
)
->where('status', '<>', Invoice::STATUS_DRAFT)
->whereCompany()
->sum('base_total');
@ -142,7 +141,6 @@ class DashboardController extends Controller
$recent_due_invoices = Invoice::with('customer')
->whereCompany()
->where('base_due_amount', '>', 0)
->where('status', '<>', Invoice::STATUS_DRAFT)
->take(5)
->latest()
->get();

View File

@ -24,7 +24,6 @@ class InvoicesController extends Controller
$limit = $request->has('limit') ? $request->limit : 10;
$invoices = Invoice::whereCompany()
->whereTabFilters($request->tab_status)
->join('customers', 'customers.id', '=', 'invoices.customer_id')
->applyFilters($request->all())
->select('invoices.*', 'customers.name')

View File

@ -2,25 +2,24 @@
namespace Crater\Http\Controllers\V1\Admin\Report;
use PDF;
use Carbon\Carbon;
use Crater\Http\Controllers\Controller;
use Crater\Models\Company;
use Crater\Models\Currency;
use Crater\Models\CompanySetting;
use Crater\Models\Customer;
use Illuminate\Http\Request;
use Crater\Models\CompanySetting;
use Illuminate\Support\Facades\App;
use Crater\Http\Controllers\Controller;
use PDF;
class CustomerSalesReportController extends Controller
{
/**
* Handle the incoming request.
*
* @param \Illuminate\Http\Request $request
* @param string $hash
* @return \Illuminate\Http\JsonResponse
*/
* Handle the incoming request.
*
* @param \Illuminate\Http\Request $request
* @param string $hash
* @return \Illuminate\Http\JsonResponse
*/
public function __invoke(Request $request, $hash)
{
$company = Company::where('unique_hash', $hash)->first();
@ -57,7 +56,6 @@ class CustomerSalesReportController extends Controller
$dateFormat = CompanySetting::getSetting('carbon_date_format', $company->id);
$from_date = Carbon::createFromFormat('Y-m-d', $request->from_date)->format($dateFormat);
$to_date = Carbon::createFromFormat('Y-m-d', $request->to_date)->format($dateFormat);
$currency = Currency::findOrFail(CompanySetting::getSetting('currency', $company->id));
$colors = [
'primary_text_color',
@ -82,7 +80,6 @@ class CustomerSalesReportController extends Controller
'company' => $company,
'from_date' => $from_date,
'to_date' => $to_date,
'currency' => $currency,
]);
$pdf = PDF::loadView('app.pdf.reports.sales-customers');

View File

@ -2,25 +2,24 @@
namespace Crater\Http\Controllers\V1\Admin\Report;
use PDF;
use Carbon\Carbon;
use Crater\Models\Company;
use Crater\Models\Expense;
use Crater\Models\Currency;
use Illuminate\Http\Request;
use Crater\Models\CompanySetting;
use Illuminate\Support\Facades\App;
use Crater\Http\Controllers\Controller;
use Crater\Models\Company;
use Crater\Models\CompanySetting;
use Crater\Models\Expense;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use PDF;
class ExpensesReportController extends Controller
{
/**
* Handle the incoming request.
*
* @param \Illuminate\Http\Request $request
* @param string $hash
* @return \Illuminate\Http\JsonResponse
*/
* Handle the incoming request.
*
* @param \Illuminate\Http\Request $request
* @param string $hash
* @return \Illuminate\Http\JsonResponse
*/
public function __invoke(Request $request, $hash)
{
$company = Company::where('unique_hash', $hash)->first();
@ -44,7 +43,6 @@ class ExpensesReportController extends Controller
$dateFormat = CompanySetting::getSetting('carbon_date_format', $company->id);
$from_date = Carbon::createFromFormat('Y-m-d', $request->from_date)->format($dateFormat);
$to_date = Carbon::createFromFormat('Y-m-d', $request->to_date)->format($dateFormat);
$currency = Currency::findOrFail(CompanySetting::getSetting('currency', $company->id));
$colors = [
'primary_text_color',
@ -68,7 +66,6 @@ class ExpensesReportController extends Controller
'company' => $company,
'from_date' => $from_date,
'to_date' => $to_date,
'currency' => $currency,
]);
$pdf = PDF::loadView('app.pdf.reports.expenses');

View File

@ -2,25 +2,24 @@
namespace Crater\Http\Controllers\V1\Admin\Report;
use PDF;
use Carbon\Carbon;
use Crater\Models\Company;
use Crater\Models\Currency;
use Illuminate\Http\Request;
use Crater\Models\InvoiceItem;
use Crater\Models\CompanySetting;
use Illuminate\Support\Facades\App;
use Crater\Http\Controllers\Controller;
use Crater\Models\Company;
use Crater\Models\CompanySetting;
use Crater\Models\InvoiceItem;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use PDF;
class ItemSalesReportController extends Controller
{
/**
* Handle the incoming request.
*
* @param \Illuminate\Http\Request $request
* @param string $hash
* @return \Illuminate\Http\JsonResponse
*/
* Handle the incoming request.
*
* @param \Illuminate\Http\Request $request
* @param string $hash
* @return \Illuminate\Http\JsonResponse
*/
public function __invoke(Request $request, $hash)
{
$company = Company::where('unique_hash', $hash)->first();
@ -44,7 +43,6 @@ class ItemSalesReportController extends Controller
$dateFormat = CompanySetting::getSetting('carbon_date_format', $company->id);
$from_date = Carbon::createFromFormat('Y-m-d', $request->from_date)->format($dateFormat);
$to_date = Carbon::createFromFormat('Y-m-d', $request->to_date)->format($dateFormat);
$currency = Currency::findOrFail(CompanySetting::getSetting('currency', $company->id));
$colors = [
'primary_text_color',
@ -68,7 +66,6 @@ class ItemSalesReportController extends Controller
'company' => $company,
'from_date' => $from_date,
'to_date' => $to_date,
'currency' => $currency,
]);
$pdf = PDF::loadView('app.pdf.reports.sales-items');

View File

@ -2,26 +2,25 @@
namespace Crater\Http\Controllers\V1\Admin\Report;
use PDF;
use Carbon\Carbon;
use Crater\Http\Controllers\Controller;
use Crater\Models\Company;
use Crater\Models\CompanySetting;
use Crater\Models\Expense;
use Crater\Models\Payment;
use Crater\Models\Currency;
use Illuminate\Http\Request;
use Crater\Models\CompanySetting;
use Illuminate\Support\Facades\App;
use Crater\Http\Controllers\Controller;
use PDF;
class ProfitLossReportController extends Controller
{
/**
* Handle the incoming request.
*
* @param \Illuminate\Http\Request $request
* @param string $hash
* @return \Illuminate\Http\JsonResponse
*/
* Handle the incoming request.
*
* @param \Illuminate\Http\Request $request
* @param string $hash
* @return \Illuminate\Http\JsonResponse
*/
public function __invoke(Request $request, $hash)
{
$company = Company::where('unique_hash', $hash)->first();
@ -50,8 +49,6 @@ class ProfitLossReportController extends Controller
$dateFormat = CompanySetting::getSetting('carbon_date_format', $company->id);
$from_date = Carbon::createFromFormat('Y-m-d', $request->from_date)->format($dateFormat);
$to_date = Carbon::createFromFormat('Y-m-d', $request->to_date)->format($dateFormat);
$currency = Currency::findOrFail(CompanySetting::getSetting('currency', $company->id));
$colors = [
'primary_text_color',
@ -77,7 +74,6 @@ class ProfitLossReportController extends Controller
'company' => $company,
'from_date' => $from_date,
'to_date' => $to_date,
'currency' => $currency,
]);
$pdf = PDF::loadView('app.pdf.reports.profit-loss');

View File

@ -2,25 +2,24 @@
namespace Crater\Http\Controllers\V1\Admin\Report;
use PDF;
use Carbon\Carbon;
use Crater\Models\Tax;
use Crater\Models\Company;
use Crater\Models\Currency;
use Illuminate\Http\Request;
use Crater\Models\CompanySetting;
use Illuminate\Support\Facades\App;
use Crater\Http\Controllers\Controller;
use Crater\Models\Company;
use Crater\Models\CompanySetting;
use Crater\Models\Tax;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use PDF;
class TaxSummaryReportController extends Controller
{
/**
* Handle the incoming request.
*
* @param \Illuminate\Http\Request $request
* @param string $hash
* @return \Illuminate\Http\JsonResponse
*/
* Handle the incoming request.
*
* @param \Illuminate\Http\Request $request
* @param string $hash
* @return \Illuminate\Http\JsonResponse
*/
public function __invoke(Request $request, $hash)
{
$company = Company::where('unique_hash', $hash)->first();
@ -45,8 +44,6 @@ class TaxSummaryReportController extends Controller
$dateFormat = CompanySetting::getSetting('carbon_date_format', $company->id);
$from_date = Carbon::createFromFormat('Y-m-d', $request->from_date)->format($dateFormat);
$to_date = Carbon::createFromFormat('Y-m-d', $request->to_date)->format($dateFormat);
$currency = Currency::findOrFail(CompanySetting::getSetting('currency', $company->id));
$colors = [
'primary_text_color',
@ -71,7 +68,6 @@ class TaxSummaryReportController extends Controller
'company' => $company,
'from_date' => $from_date,
'to_date' => $to_date,
'currency' => $currency,
]);
$pdf = PDF::loadView('app.pdf.reports.tax-summary');

View File

@ -3,6 +3,7 @@
namespace Crater\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Str;
use Illuminate\Validation\Rule;
class CompaniesRequest extends FormRequest
@ -33,10 +34,6 @@ class CompaniesRequest extends FormRequest
'currency' => [
'required'
],
'slug' => [
'required',
Rule::unique('companies')
],
'address.name' => [
'nullable',
],
@ -71,11 +68,11 @@ class CompaniesRequest extends FormRequest
{
return collect($this->validated())
->only([
'name',
'slug'
'name'
])
->merge([
'owner_id' => $this->user()->id
'owner_id' => $this->user()->id,
'slug' => Str::slug($this->name)
])
->toArray();
}

View File

@ -30,8 +30,7 @@ class CompanyRequest extends FormRequest
Rule::unique('companies')->ignore($this->header('company'), 'id'),
],
'slug' => [
'required',
Rule::unique('companies')->ignore($this->header('company'), 'id'),
'nullable'
],
'address.country_id' => [
'required',

View File

@ -23,7 +23,7 @@ class EstimateResource extends JsonResource
'reference_number' => $this->reference_number,
'tax_per_item' => $this->tax_per_item,
'discount_per_item' => $this->discount_per_item,
'notes' => $this->notes,
'notes' => $this->getNotes(),
'discount' => $this->discount,
'discount_type' => $this->discount_type,
'discount_val' => $this->discount_val,

View File

@ -18,7 +18,7 @@ class PaymentResource extends JsonResource
'id' => $this->id,
'payment_number' => $this->payment_number,
'payment_date' => $this->payment_date,
'notes' => $this->notes,
'notes' => $this->getNotes(),
'amount' => $this->amount,
'unique_hash' => $this->unique_hash,
'invoice_id' => $this->invoice_id,

View File

@ -217,7 +217,7 @@ class Company extends Model implements HasMedia
'estimate_billing_address_format' => $billingAddressFormat,
'payment_company_address_format' => $companyAddressFormat,
'payment_from_customer_address_format' => $paymentFromCustomerAddress,
'currency' => request()->currency ?? 1,
'currency' => request()->currency ?? 13,
'time_zone' => 'Asia/Kolkata',
'language' => 'en',
'fiscal_year' => '1-12',

View File

@ -483,8 +483,7 @@ class Estimate extends Model implements HasMedia
'{ESTIMATE_DATE}' => $this->formattedEstimateDate,
'{ESTIMATE_EXPIRY_DATE}' => $this->formattedExpiryDate,
'{ESTIMATE_NUMBER}' => $this->estimate_number,
'{PDF_LINK}' => $this->estimatePdfUrl,
'{TOTAL_AMOUNT}' => format_money_pdf($this->total, $this->customer->currency)
'{ESTIMATE_REF_NUMBER}' => $this->reference_number,
];
}

View File

@ -240,7 +240,7 @@ class Expense extends Model implements HasMedia
}
if ($request->hasFile('attachment_receipt')) {
$expense->addMediaFromRequest('attachment_receipt')->toMediaCollection('receipts', 'local');
$expense->addMediaFromRequest('attachment_receipt')->toMediaCollection('receipts');
}
if ($request->customFields) {
@ -262,12 +262,12 @@ class Expense extends Model implements HasMedia
ExchangeRateLog::addExchangeRateLog($this);
}
if (isset($request->is_attachment_receipt_removed) && $request->is_attachment_receipt_removed == "true") {
if (isset($request->is_attachment_receipt_removed) && (bool) $request->is_attachment_receipt_removed) {
$this->clearMediaCollection('receipts');
}
if ($request->hasFile('attachment_receipt')) {
$this->clearMediaCollection('receipts');
$this->addMediaFromRequest('attachment_receipt')->toMediaCollection('receipts', 'local');
$this->addMediaFromRequest('attachment_receipt')->toMediaCollection('receipts');
}
if ($request->customFields) {

View File

@ -187,6 +187,16 @@ class Invoice extends Model implements HasMedia
return Carbon::parse($this->invoice_date)->format($dateFormat);
}
public function scopeWhereStatus($query, $status)
{
return $query->where('invoices.status', $status);
}
public function scopeWherePaidStatus($query, $status)
{
return $query->where('invoices.paid_status', $status);
}
public function scopeWhereDueStatus($query, $status)
{
return $query->whereIn('invoices.paid_status', [
@ -224,40 +234,6 @@ class Invoice extends Model implements HasMedia
$query->orderBy($orderByField, $orderBy);
}
public function scopeWhereStatus($query, $status)
{
return $query->where('invoices.status', $status);
}
public function scopeWherePaidStatus($query, $status)
{
return $query->where('invoices.paid_status', $status);
}
public function scopeWhereTabFilters($query, $status)
{
if ($status == "DRAFT") {
return $query->where('invoices.status', $status);
}
if ($status == "SENT") {
return $query->whereIn('invoices.status', [
self::STATUS_SENT,
self::STATUS_VIEWED,
self::STATUS_COMPLETED
]);
}
if ($status == 'DUE') {
return $query->whereIn('invoices.paid_status', [
self::STATUS_UNPAID,
self::STATUS_PARTIALLY_PAID,
]);
}
return ;
}
public function scopeApplyFilters($query, array $filters)
{
$filters = collect($filters);
@ -273,11 +249,17 @@ class Invoice extends Model implements HasMedia
$filters->get('status') == self::STATUS_PAID
) {
$query->wherePaidStatus($filters->get('status'));
} elseif ($filters->get('status') == 'DUE') {
$query->whereDueStatus($filters->get('status'));
} else {
$query->whereStatus($filters->get('status'));
}
}
if ($filters->get('paid_status')) {
$query->wherePaidStatus($filters->get('status'));
}
if ($filters->get('invoice_id')) {
$query->whereInvoice($filters->get('invoice_id'));
}
@ -669,9 +651,7 @@ class Invoice extends Model implements HasMedia
'{INVOICE_DATE}' => $this->formattedInvoiceDate,
'{INVOICE_DUE_DATE}' => $this->formattedDueDate,
'{INVOICE_NUMBER}' => $this->invoice_number,
'{PDF_LINK}' => $this->invoicePdfUrl,
'{DUE_AMOUNT}' => format_money_pdf($this->due_amount, $this->customer->currency),
'{TOTAL_AMOUNT}' => format_money_pdf($this->total, $this->customer->currency)
'{INVOICE_REF_NUMBER}' => $this->reference_number,
];
}

View File

@ -435,8 +435,7 @@ class Payment extends Model implements HasMedia
'{PAYMENT_DATE}' => $this->formattedPaymentDate,
'{PAYMENT_MODE}' => $this->paymentMethod ? $this->paymentMethod->name : null,
'{PAYMENT_NUMBER}' => $this->payment_number,
'{PDF_LINK}' => $this->paymentPdfUrl,
'{PAYMENT_AMOUNT}' => format_money_pdf($this->amount, $this->customer->currency)
'{PAYMENT_AMOUNT}' => $this->reference_number,
];
}

View File

@ -38,15 +38,15 @@
"barryvdh/laravel-ide-helper": "^2.6",
"beyondcode/laravel-dump-server": "^1.0",
"facade/ignition": "^2.3.6",
"friendsofphp/php-cs-fixer": "^3.8",
"fakerphp/faker": "^1.9.1",
"friendsofphp/php-cs-fixer": "^3.0",
"fzaninotto/faker": "^1.9.1",
"mockery/mockery": "^1.3.1",
"nunomaduro/collision": "^5.0",
"pestphp/pest": "^1.0",
"pestphp/pest-plugin-faker": "^1.0",
"pestphp/pest-plugin-laravel": "^1.0",
"pestphp/pest-plugin-parallel": "^0.2.1",
"phpunit/phpunit": "^9.3"
"phpunit/phpunit": "^9.0"
},
"autoload": {
"psr-4": {
@ -81,14 +81,11 @@
"config": {
"optimize-autoloader": true,
"preferred-install": "dist",
"sort-packages": true,
"allow-plugins": {
"pestphp/pest-plugin": true
}
"sort-packages": true
},
"extra": {
"laravel": {
"dont-discover": []
}
}
}
}

2361
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -71,7 +71,6 @@ return [
["code" => "cs", "name" => "Czech"],
["code" => "el", "name" => "Greek"],
["code" => "hr", "name" => "Crotian"],
["code" => "th", "name" => "ไทย"],
],
/*

View File

@ -170,7 +170,7 @@ class CountriesTableSeeder extends Seeder
['id' => 152,'code' => 'NR','name' => "Nauru",'phonecode' => 674],
['id' => 153,'code' => 'NP','name' => "Nepal",'phonecode' => 977],
['id' => 154,'code' => 'AN','name' => "Netherlands Antilles",'phonecode' => 599],
['id' => 155,'code' => 'NL','name' => "Netherlands",'phonecode' => 31],
['id' => 155,'code' => 'NL','name' => "Netherlands The",'phonecode' => 31],
['id' => 156,'code' => 'NC','name' => "New Caledonia",'phonecode' => 687],
['id' => 157,'code' => 'NZ','name' => "New Zealand",'phonecode' => 64],
['id' => 158,'code' => 'NI','name' => "Nicaragua",'phonecode' => 505],

View File

@ -1,7 +1,7 @@
FROM php:8.0-fpm-alpine
FROM php:7.4-fpm-alpine
RUN apk add --no-cache \
php8-bcmath
php7-bcmath
RUN docker-php-ext-install pdo pdo_mysql bcmath

View File

@ -27,7 +27,7 @@
"vite": "^2.6.1"
},
"dependencies": {
"@headlessui/vue": "^1.5.0",
"@headlessui/vue": "^1.4.0",
"@heroicons/vue": "^1.0.1",
"@popperjs/core": "^2.9.2",
"@stripe/stripe-js": "^1.21.2",
@ -48,8 +48,7 @@
"mini-svg-data-uri": "^1.3.3",
"moment": "^2.29.1",
"pinia": "^2.0.4",
"v-calendar": "3.0.0-alpha.8",
"v-money3": "3.16.1",
"v-money3": "^3.13.5",
"v-tooltip": "^4.0.0-alpha.1",
"vue": "^3.2.0-beta.5",
"vue-flatpickr-component": "^9.0.3",

View File

@ -6,17 +6,8 @@
<script setup>
import Chart from 'chart.js'
import {
ref,
reactive,
computed,
onMounted,
watchEffect,
inject,
watch,
} from 'vue'
import { ref, reactive, computed, onMounted, watchEffect, inject } from 'vue'
import { useCompanyStore } from '@/scripts/admin/stores/company'
import { useGlobalStore } from '@/scripts/admin/stores/global'
const utils = inject('utils')
@ -53,11 +44,9 @@ const props = defineProps({
},
})
const isDarkModeOn = document.documentElement.classList.contains('dark')
let myLineChart = null
const graph = ref(null)
const companyStore = useCompanyStore()
const globalStore = useGlobalStore()
const defaultCurrency = computed(() => {
return companyStore.selectedCompanyCurrency
})
@ -71,14 +60,6 @@ watchEffect(() => {
}
})
watch(
() => globalStore.isDarkModeOn,
() => {
myLineChart.reset()
updateColors()
}
)
onMounted(() => {
let context = graph.value.getContext('2d')
let options = reactive({
@ -100,8 +81,6 @@ onMounted(() => {
},
})
const salesColor = globalStore.isDarkModeOn ? '#ffffff' : '#040405'
let data = reactive({
labels: props.labels,
datasets: [
@ -110,16 +89,16 @@ onMounted(() => {
fill: false,
lineTension: 0.3,
backgroundColor: 'rgba(230, 254, 249)',
borderColor: salesColor,
borderColor: '#040405',
borderCapStyle: 'butt',
borderDash: [],
borderDashOffset: 0.0,
borderJoinStyle: 'miter',
pointBorderColor: salesColor,
pointBorderColor: '#040405',
pointBackgroundColor: '#fff',
pointBorderWidth: 1,
pointHoverRadius: 5,
pointHoverBackgroundColor: salesColor,
pointHoverBackgroundColor: '#040405',
pointHoverBorderColor: 'rgba(220,220,220,1)',
pointHoverBorderWidth: 2,
pointRadius: 4,
@ -215,12 +194,4 @@ function update() {
lazy: true,
})
}
function updateColors() {
const newColor = globalStore.isDarkModeOn ? '#ffffff' : '#040405'
myLineChart.data.datasets[0].borderColor = newColor
myLineChart.data.datasets[0].pointBorderColor = newColor
myLineChart.data.datasets[0].pointHoverBackgroundColor = newColor
}
</script>

View File

@ -64,7 +64,7 @@ function mergeExistingValues() {
if (props.isEdit) {
props.store[props.storeProp].fields.forEach((field) => {
const existingIndex = props.store[props.storeProp].customFields.findIndex(
(f) => f.id == field.custom_field_id
(f) => f.id === field.custom_field_id
)
if (existingIndex > -1) {

View File

@ -9,7 +9,7 @@ import { computed } from 'vue'
const props = defineProps({
modelValue: {
type: String,
default: moment().format('YYYY-MM-DD HH:mm'),
default: moment().format('YYYY-MM-DD hh:MM'),
},
})

View File

@ -17,7 +17,18 @@
<td class="px-5 py-4 text-left align-top">
<div class="flex justify-start">
<div
class="flex items-center justify-center w-5 h-5 mt-2 mr-2 text-gray-300 cursor-move handle"
class="
flex
items-center
justify-center
w-5
h-5
mt-2
text-gray-300
cursor-move
handle
mr-2
"
>
<DragIcon />
</div>
@ -97,7 +108,7 @@
<BaseIcon
name="ChevronDownIcon"
class="w-4 h-4 ml-1 text-gray-500"
class="w-4 h-4 text-gray-500 ml-1"
/>
</span>
</BaseButton>
@ -144,7 +155,7 @@
<BaseContentPlaceholders v-if="loading">
<BaseContentPlaceholdersText
:lines="1"
class="w-24 h-8 border rounded-md"
class="w-24 h-8 rounded-md border"
/>
</BaseContentPlaceholders>
@ -164,7 +175,6 @@
:ability="abilities.CREATE_INVOICE"
:store="store"
:store-prop="storeProp"
:discount="discount"
@update="updateTax"
/>
</td>

View File

@ -30,13 +30,24 @@
<template v-if="userStore.hasAbilities(ability)" #action>
<button
type="button"
class="flex items-center justify-center w-full px-2 py-2 bg-gray-200 border-none outline-none cursor-pointer "
class="
flex
items-center
justify-center
w-full
px-2
cursor-pointer
py-2
bg-gray-200
border-none
outline-none
"
@click="openTaxModal"
>
<BaseIcon name="CheckCircleIcon" class="h-5 text-primary-400" />
<label
class="ml-2 text-sm leading-none cursor-pointer text-primary-400"
class="ml-2 text-sm leading-none text-primary-400 cursor-pointer"
>{{ $t('invoices.add_new_tax') }}</label
>
</button>
@ -104,10 +115,6 @@ const props = defineProps({
type: Number,
default: 0,
},
discountedTotal: {
type: Number,
default: 0,
},
currency: {
type: [Object, String],
required: true,
@ -146,19 +153,19 @@ const filteredTypes = computed(() => {
})
const taxAmount = computed(() => {
if (localTax.compound_tax && props.discountedTotal) {
return ((props.discountedTotal + props.totalTax) * localTax.percent) / 100
if (localTax.compound_tax && props.total) {
return ((props.total + props.totalTax) * localTax.percent) / 100
}
if (props.discountedTotal && localTax.percent) {
return (props.discountedTotal * localTax.percent) / 100
if (props.total && localTax.percent) {
return (props.total * localTax.percent) / 100
}
return 0
})
watch(
() => props.discountedTotal,
() => props.total,
() => {
updateRowTax()
}

View File

@ -29,7 +29,14 @@
<label
v-else
class="flex items-center justify-center m-0 text-lg text-black uppercase "
class="
flex
items-center
justify-center
m-0
text-lg text-black
uppercase
"
>
<BaseFormatMoney
:amount="store.getSubTotal"
@ -59,7 +66,14 @@
<label
v-else-if="store[storeProp].tax_per_item === 'YES'"
class="flex items-center justify-center m-0 text-lg text-black uppercase "
class="
flex
items-center
justify-center
m-0
text-lg text-black
uppercase
"
>
<BaseFormatMoney :amount="tax.amount" :currency="defaultCurrency" />
</label>
@ -84,7 +98,7 @@
<BaseContentPlaceholders v-if="isLoading">
<BaseContentPlaceholdersText
:lines="1"
class="w-24 h-8 border rounded-md"
class="w-24 h-8 rounded-md border"
/>
</BaseContentPlaceholders>
<div v-else class="flex" style="width: 140px" role="group">
@ -100,7 +114,7 @@
<BaseDropdown position="bottom-end">
<template #activator>
<BaseButton
class="p-2 rounded-none rounded-tr-md rounded-br-md"
class="rounded-tr-md rounded-br-md p-2 rounded-none"
type="button"
variant="white"
>
@ -113,7 +127,7 @@
<BaseIcon
name="ChevronDownIcon"
class="w-4 h-4 ml-1 text-gray-500"
class="w-4 h-4 text-gray-500 ml-1"
/>
</span>
</BaseButton>
@ -166,7 +180,15 @@
</div>
<div
class="flex items-center justify-between w-full pt-2 mt-5 border-t border-gray-200 border-solid "
class="
flex
items-center
justify-between
w-full
pt-2
mt-5
border-t border-gray-200 border-solid
"
>
<BaseContentPlaceholders v-if="isLoading">
<BaseContentPlaceholdersText :lines="1" class="w-16 h-5" />
@ -182,7 +204,14 @@
</BaseContentPlaceholders>
<label
v-else
class="flex items-center justify-center text-lg uppercase text-primary-400"
class="
flex
items-center
justify-center
text-lg
uppercase
text-primary-400
"
>
<BaseFormatMoney :amount="store.getTotal" :currency="defaultCurrency" />
</label>
@ -305,7 +334,6 @@ function selectPercentage() {
function onSelectTax(selectedTax) {
let amount = 0
if (selectedTax.compound_tax && props.store.getSubtotalWithDiscount) {
amount = Math.round(
((props.store.getSubtotalWithDiscount + props.store.getTotalSimpleTax) *

View File

@ -48,24 +48,6 @@
/>
</BaseInputGroup>
<BaseInputGroup
:label="$tc('settings.company_info.company_slug')"
:help-text="$t('settings.company_info.company_slug_help_text')"
:error="
v$.newCompanyForm.slug.$error &&
v$.newCompanyForm.slug.$errors[0].$message
"
:content-loading="isFetchingInitialData"
required
>
<BaseInput
v-model="newCompanyForm.slug"
:invalid="v$.newCompanyForm.slug.$error"
:content-loading="isFetchingInitialData"
@input="v$.newCompanyForm.slug.$touch()"
/>
</BaseInputGroup>
<BaseInputGroup
:content-loading="isFetchingInitialData"
:label="$tc('settings.company_info.country')"
@ -148,7 +130,7 @@
<script setup>
import { useModalStore } from '@/scripts/stores/modal'
import { computed, onMounted, ref, reactive, watch } from 'vue'
import { computed, onMounted, ref, reactive } from 'vue'
import { useI18n } from 'vue-i18n'
import { required, minLength, helpers } from '@vuelidate/validators'
import { useVuelidate } from '@vuelidate/core'
@ -170,7 +152,6 @@ let companyLogoName = ref(null)
const newCompanyForm = reactive({
name: null,
slug: null,
currency: '',
address: {
country_id: null,
@ -181,9 +162,6 @@ const modalActive = computed(() => {
return modalStore.active && modalStore.componentName === 'CompanyModal'
})
const slugValidator = (value) => {
return value == slugify(value)
}
const rules = {
newCompanyForm: {
name: {
@ -193,17 +171,6 @@ const rules = {
minLength(3)
),
},
slug: {
required: helpers.withMessage(t('validation.required'), required),
minLength: helpers.withMessage(
t('validation.name_min_length', { count: 3 }),
minLength(3)
),
slugValidator: helpers.withMessage(
t('validation.invalid_slug'),
slugValidator
),
},
address: {
country_id: {
required: helpers.withMessage(t('validation.required'), required),
@ -276,7 +243,6 @@ async function submitCompanyData() {
function resetNewCompanyForm() {
newCompanyForm.name = ''
newCompanyForm.slug = ''
newCompanyForm.currency = ''
newCompanyForm.address.country_id = ''
@ -291,24 +257,4 @@ function closeCompanyModal() {
v$.value.$reset()
}, 300)
}
// watcher for if change company name then auto fill company slug value
watch(
() => newCompanyForm.name,
(currentValue) => {
newCompanyForm.slug = slugify(currentValue)
}
)
function slugify(string) {
return string
.toString()
.trim()
.toLowerCase()
.replace(/\s+/g, '-')
.replace(/[^\w\-]+/g, '')
.replace(/\-\-+/g, '-')
.replace(/^-+/, '')
.replace(/-+$/, '')
}
</script>

View File

@ -15,13 +15,6 @@
bg-gradient-to-r
from-primary-500
to-primary-400
dark:from-gray-700/70 dark:to-gray-800/70
bg-primary-500
dark:bg-transparent
dark:backdrop-blur-xl
dark:shadow-glass
dark:border
dark:border-white/10
"
>
<router-link
@ -60,7 +53,6 @@
cursor-pointer
md:hidden md:ml-0
hover:bg-gray-100
dark:bg-gray-800 dark:border-gray-500 dark:border
"
@click.prevent="onToggle"
>
@ -151,7 +143,7 @@
<template #activator>
<img
:src="previewAvatar"
class="block w-8 h-8 rounded md:h-9 md:w-9 object-cover"
class="block w-8 h-8 rounded md:h-9 md:w-9"
/>
</template>

View File

@ -15,9 +15,7 @@
leave-from="opacity-100"
leave-to="opacity-0"
>
<DialogOverlay
class="fixed inset-0 bg-gray-600 bg-opacity-75 dark:bg-gray-900/90"
/>
<DialogOverlay class="fixed inset-0 bg-gray-600 bg-opacity-75" />
</TransitionChild>
<TransitionChild
@ -29,9 +27,7 @@
leave-from="translate-x-0"
leave-to="-translate-x-full"
>
<div
class="relative flex flex-col flex-1 w-full max-w-xs bg-white dark:bg-gray-800"
>
<div class="relative flex flex-col flex-1 w-full max-w-xs bg-white">
<TransitionChild
as="template"
enter="ease-in-out duration-300"
@ -44,17 +40,18 @@
<div class="absolute top-0 right-0 pt-2 -mr-12">
<button
class="
flex
items-center
justify-center
w-10
h-10
ml-1
rounded-full
focus:outline-none
focus:ring-2
focus:ring-inset
focus:ring-white"
flex
items-center
justify-center
w-10
h-10
ml-1
rounded-full
focus:outline-none
focus:ring-2
focus:ring-inset
focus:ring-white
"
@click="globalStore.setSidebarVisibility(false)"
>
<span class="sr-only">Close sidebar</span>
@ -85,8 +82,8 @@
:to="item.link"
:class="[
hasActiveUrl(item.link)
? 'text-primary-500 border-primary-500 bg-gray-100 dark:shadow-glass dark:backdrop-blur-xl dark:hover:bg-gray-700 dark:bg-gray-700/50 dark:text-primary-400 dark:font-medium'
: 'text-black dark:text-gray-300',
? 'text-primary-500 border-primary-500 bg-gray-100 '
: 'text-black',
'cursor-pointer px-0 pl-4 py-3 border-transparent flex items-center border-l-4 border-solid text-sm not-italic font-medium',
]"
@click="globalStore.setSidebarVisibility(false)"
@ -103,10 +100,6 @@
/>
{{ $t(item.title) }}
</router-link>
<LightDarkSwitch
:show-label="false"
class="absolute right-6 top-6 !w-auto"
/>
</nav>
</div>
</div>
@ -120,16 +113,17 @@
<!-- DESKTOP MENU -->
<div
class="
hidden
w-56
h-screen
bg-white
border-r border-gray-200 border-solid
xl:w-64
md:fixed md:flex md:flex-col md:inset-y-0
pt-16
dark:border-gray-800
dark:bg-gray-800/80"
hidden
w-56
h-screen
pb-32
overflow-y-auto
bg-white
border-r border-gray-200 border-solid
xl:w-64
md:fixed md:flex md:flex-col md:inset-y-0
pt-16
"
>
<div
v-for="menu in globalStore.menuGroups"
@ -142,8 +136,8 @@
:to="item.link"
:class="[
hasActiveUrl(item.link)
? 'text-primary-500 border-primary-500 bg-gray-100 dark:border-primary-400 dark:shadow-glass dark:backdrop-blur-xl dark:hover:bg-gray-700 dark:bg-gray-700/50 dark:text-primary-400 dark:font-medium'
: 'text-black dark:hover:bg-transparent dark:hover:text-white dark:text-gray-300',
? 'text-primary-500 border-primary-500 bg-gray-100 '
: 'text-black',
'cursor-pointer px-0 pl-6 hover:bg-gray-50 py-3 group flex items-center border-l-4 border-solid border-transparent text-sm not-italic font-medium',
]"
>
@ -151,8 +145,8 @@
:name="item.icon"
:class="[
hasActiveUrl(item.link)
? 'text-primary-500 group-hover:text-primary-500 dark:text-primary-400 dark:group-hover:text-primary-500 '
: 'text-gray-400 group-hover:text-black dark:text-gray-400 dark:group-hover:text-white',
? 'text-primary-500 group-hover:text-primary-500 '
: 'text-gray-400 group-hover:text-black',
'mr-4 shrink-0 h-5 w-5 ',
]"
/>
@ -160,9 +154,6 @@
{{ $t(item.title) }}
</router-link>
</div>
<LightDarkSwitch
class="absolute bottom-0 py-4 border-t border-gray-200 dark:border-gray-700"
/>
</div>
</template>
@ -178,7 +169,6 @@ import {
import { useRoute } from 'vue-router'
import { useGlobalStore } from '@/scripts/admin/stores/global'
import LightDarkSwitch from '@/scripts/components/LightDarkSwitcher.vue'
const route = useRoute()
const globalStore = useGlobalStore()

View File

@ -184,20 +184,6 @@ export const useCompanyStore = (useWindow = false) => {
setDefaultCurrency(data) {
this.defaultCurrency = data.currency
},
checkCompanyHasCurrencyTransactions() {
return new Promise((resolve, reject) => {
axios
.get(`/api/v1/company/has-transactions`)
.then((response) => {
resolve(response)
})
.catch((err) => {
handleError(err)
reject(err)
})
})
},
},
})()
}

View File

@ -34,7 +34,6 @@ export const useGlobalStore = (useWindow = false) => {
isAppLoaded: false,
isSidebarOpen: false,
areCurrenciesLoading: false,
isDarkModeOn: false,
downloadReport: null,
}),
@ -71,8 +70,8 @@ export const useGlobalStore = (useWindow = false) => {
moduleStore.apiToken = response.data.global_settings.api_token
moduleStore.enableModules = response.data.modules
// company store
companyStore.companies = response.data.companies
// company store
companyStore.companies = response.data.companies
companyStore.selectedCompany = response.data.current_company
companyStore.setSelectedCompany(response.data.current_company)
companyStore.selectedCompanySettings =

View File

@ -2,23 +2,8 @@
<div>
<div
v-if="dashboardStore.isDashboardDataLoaded"
class="
grid
grid-cols-10
mt-8
bg-white
rounded shadow
dark:text-white
dark:backdrop-blur-xl
dark:shadow-glass
dark:border
dark:bg-opacity-70
dark:border-white/10
dark:bg-gray-800
relative
"
class="grid grid-cols-10 mt-8 bg-white rounded shadow"
>
<BaseDarkHighlight />
<!-- Chart -->
<div
class="
@ -69,7 +54,6 @@
lg:border-t-0 lg:text-right lg:col-span-3
xl:col-span-2
lg:grid-cols-1
dark:border-white/10
"
>
<div class="p-6">
@ -112,7 +96,15 @@
</span>
<br />
<span
class="block mt-1 text-xl font-semibold leading-8 lg:text-2xl text-red-400"
class="
block
mt-1
text-xl
font-semibold
leading-8
lg:text-2xl
text-red-400
"
>
<BaseFormatMoney
:amount="dashboardStore.totalExpenses"
@ -124,10 +116,8 @@
class="
col-span-3
p-6
border-t
border-gray-200 border-solid
border-t border-gray-200 border-solid
lg:col-span-1
dark:border-white/10
"
>
<span class="text-xs leading-5 lg:text-sm">
@ -142,7 +132,7 @@
font-semibold
leading-8
lg:text-2xl
text-primary-500 dark:text-primary-400
text-primary-500
"
>
<BaseFormatMoney

View File

@ -1,6 +1,6 @@
<template>
<BaseContentPlaceholders
class="grid grid-cols-10 mt-8 bg-white rounded shadow dark:bg-gray-800"
class="grid grid-cols-10 mt-8 bg-white rounded shadow"
>
<!-- Chart -->
<div
@ -29,7 +29,6 @@
text-center
border-t border-l border-gray-200 border-solid
lg:border-t-0 lg:text-right lg:col-span-3
dark:border-gray-600
xl:col-span-2
lg:grid-cols-1
"
@ -78,7 +77,6 @@
col-span-3
p-6
border-t border-gray-200 border-solid
dark:border-gray-600
lg:justify-end lg:items-end lg:col-span-1
"
>

View File

@ -12,24 +12,18 @@
hover:bg-gray-50
xl:p-4
lg:col-span-2
dark:backdrop-blur-xl
dark:shadow-glass
dark:border
dark:border-white/10
dark:bg-gray-800/70
"
:class="{ 'lg:!col-span-3': large }"
:to="route"
>
<div>
<span class="text-xl font-semibold leading-tight text-black xl:text-3xl dark:text-white">
<span class="text-xl font-semibold leading-tight text-black xl:text-3xl">
<slot />
</span>
<span class="block mt-1 text-sm leading-tight text-gray-500 xl:text-lg dark:text-gray-300">
<span class="block mt-1 text-sm leading-tight text-gray-500 xl:text-lg">
{{ label }}
</span>
</div>
<BaseDarkHighlight class="!bg-highlight/[.17] !top-5" />
<div class="flex items-center">
<component :is="iconComponent" class="w-10 h-10 xl:w-12 xl:h-12" />
</div>

View File

@ -1,7 +1,7 @@
<template>
<BaseContentPlaceholders
:rounded="true"
class="relative flex justify-between w-full p-3 bg-white rounded shadow lg:col-span-3 xl:p-4 dark:bg-gray-800"
class="relative flex justify-between w-full p-3 bg-white rounded shadow lg:col-span-3 xl:p-4"
>
<div>
<BaseContentPlaceholdersText

View File

@ -12,7 +12,6 @@
shadow
lg:col-span-2
xl:p-4
dark:bg-gray-800
"
>
<div>

View File

@ -32,8 +32,6 @@
:content-loading="isLoading"
:calendar-button="true"
calendar-button-icon="calendar"
:show-extra-options="true"
:source-date="estimateStore.newEstimate.estimate_date"
/>
</BaseInputGroup>

View File

@ -34,24 +34,6 @@
/>
</BaseInputGroup>
<BaseInputGroup
:label="$tc('wizard.company_slug')"
:help-text="$t('wizard.company_slug_help_text')"
:error="
v$.companyForm.slug.$error &&
v$.companyForm.slug.$errors[0].$message
"
required
>
<BaseInput
v-model="companyForm.slug"
:invalid="v$.companyForm.slug.$error"
type="text"
name="slug"
@input="v$.companyForm.slug.$touch()"
/>
</BaseInputGroup>
<BaseInputGroup
:label="$t('wizard.country')"
:error="
@ -75,7 +57,9 @@
track-by="name"
/>
</BaseInputGroup>
</div>
<div class="grid grid-cols-1 gap-4 mb-4 md:grid-cols-2 md:mb-6">
<BaseInputGroup :label="$t('wizard.state')">
<BaseInput
v-model="companyForm.address.state"
@ -160,9 +144,9 @@
</template>
<script setup>
import { ref, computed, onMounted, reactive, watch } from 'vue'
import { ref, computed, onMounted, reactive } from 'vue'
import { useI18n } from 'vue-i18n'
import { required, minLength, maxLength, helpers } from '@vuelidate/validators'
import { required, maxLength, helpers } from '@vuelidate/validators'
import { useVuelidate } from '@vuelidate/core'
import { useGlobalStore } from '@/scripts/admin/stores/global'
import { useCompanyStore } from '@/scripts/admin/stores/company'
@ -178,7 +162,6 @@ let logoFileName = ref(null)
const companyForm = reactive({
name: null,
slug: null,
address: {
address_street_1: '',
address_street_2: '',
@ -205,28 +188,10 @@ onMounted(async () => {
})?.id
})
const slugValidator = (value) => {
return value == slugify(value)
}
const rules = {
companyForm: {
name: {
required: helpers.withMessage(t('validation.required'), required),
minLength: helpers.withMessage(
t('validation.name_min_length', { count: 3 }),
minLength(3)
),
},
slug: {
required: helpers.withMessage(t('validation.required'), required),
minLength: helpers.withMessage(
t('validation.name_min_length', { count: 3 }),
minLength(3)
),
slugValidator: helpers.withMessage(
t('validation.invalid_slug'),
slugValidator
),
},
address: {
country_id: {
@ -284,24 +249,4 @@ async function next() {
emit('next', 7)
}
}
// watcher for if change company name then auto fill company slug value
watch(
() => companyForm.name,
(currentValue) => {
companyForm.slug = slugify(currentValue)
}
)
function slugify(string) {
return string
.toString()
.trim()
.toLowerCase()
.replace(/\s+/g, '-')
.replace(/[^\w\-]+/g, '')
.replace(/\-\-+/g, '-')
.replace(/^-+/, '')
.replace(/-+$/, '')
}
</script>

View File

@ -56,7 +56,7 @@
<BaseMultiselect
v-model="filters.status"
:groups="true"
:options="invoiceStatus"
:options="status"
searchable
:placeholder="$t('general.select_a_status')"
@update:modelValue="setActiveTab"
@ -130,27 +130,11 @@
"
>
<!-- Tabs -->
<BaseTabGroup
class="-mb-5"
:selected-index="selectedIndex"
@change="changeTabStatus"
>
<BaseTab
:title="invoiceTabStatus[0].title"
:tab-status="invoiceTabStatus[0].value"
/>
<BaseTab
:title="invoiceTabStatus[1].title"
:tab-status="invoiceTabStatus[1].value"
/>
<BaseTab
:title="invoiceTabStatus[2].title"
:tab-status="invoiceTabStatus[2].value"
/>
<BaseTab
:title="invoiceTabStatus[3].title"
:tab-status="invoiceTabStatus[3].value"
/>
<BaseTabGroup class="-mb-5" @change="setStatusFilter">
<BaseTab :title="$t('general.all')" filter="" />
<BaseTab :title="$t('general.draft')" filter="DRAFT" />
<BaseTab :title="$t('general.sent')" filter="SENT" />
<BaseTab :title="$t('general.due')" filter="DUE" />
</BaseTabGroup>
<BaseDropdown
@ -305,10 +289,10 @@ const utils = inject('$utils')
const table = ref(null)
const showFilters = ref(false)
const invoiceStatus = ref([
const status = ref([
{
label: 'Status',
options: ['DRAFT', 'SENT', 'VIEWED', 'COMPLETED'],
options: ['DRAFT', 'DUE', 'SENT', 'VIEWED', 'COMPLETED'],
},
{
label: 'Paid Status',
@ -316,29 +300,10 @@ const invoiceStatus = ref([
},
,
])
const invoiceTabStatus = {
0: {
title: t('general.all'),
value: '',
},
1: {
title: t('general.draft'),
value: 'DRAFT',
},
2: {
title: t('general.sent'),
value: 'SENT',
},
3: {
title: t('general.due'),
value: 'DUE',
},
}
const isRequestOngoing = ref(true)
const activeTab = ref('general.draft')
const router = useRouter()
const userStore = useUserStore()
const selectedIndex = ref(0)
let filters = reactive({
customer_id: '',
@ -346,7 +311,6 @@ let filters = reactive({
from_date: '',
to_date: '',
invoice_number: '',
tab_status: '',
})
const showEmptyScreen = computed(
@ -437,7 +401,6 @@ async function fetchData({ page, filter, sort }) {
from_date: filters.from_date,
to_date: filters.to_date,
invoice_number: filters.invoice_number,
tab_status: filters.tab_status,
orderByField: sort.fieldName || 'created_at',
orderBy: sort.order || 'desc',
page,
@ -460,9 +423,29 @@ async function fetchData({ page, filter, sort }) {
}
}
function changeTabStatus(val, index) {
filters.tab_status = val['tab-status']
selectedIndex.value = index
function setStatusFilter(val) {
if (activeTab.value == val.title) {
return true
}
activeTab.value = val.title
switch (val.title) {
case t('general.draft'):
filters.status = 'DRAFT'
break
case t('general.sent'):
filters.status = 'SENT'
break
case t('general.due'):
filters.status = 'DUE'
break
default:
filters.status = ''
break
}
}
function setFilters() {
@ -480,6 +463,8 @@ function clearFilter() {
filters.from_date = ''
filters.to_date = ''
filters.invoice_number = ''
activeTab.value = t('general.all')
}
async function removeMultipleInvoices() {
@ -520,21 +505,39 @@ function toggleFilter() {
function setActiveTab(val) {
switch (val) {
case 'DRAFT':
selectedIndex.value = 1
activeTab.value = t('general.draft')
break
case 'SENT':
activeTab.value = t('general.sent')
break
case 'DUE':
activeTab.value = t('general.due')
break
case 'SENT':
case 'VIEWED':
case 'COMPLETED':
activeTab.value = t('invoices.completed')
break
case 'PAID':
selectedIndex.value = 2
activeTab.value = t('invoices.paid')
break
case 'UNPAID':
activeTab.value = t('invoices.unpaid')
break
case 'PARTIALLY_PAID':
selectedIndex.value = 3
activeTab.value = t('invoices.partially_paid')
break
case 'VIEWED':
activeTab.value = t('invoices.viewed')
break
default:
activeTab.value = t('general.all')
break
}
filters.tab_status = invoiceTabStatus[selectedIndex.value].value
}
</script>

View File

@ -32,8 +32,6 @@
:content-loading="isLoading"
:calendar-button="true"
calendar-button-icon="calendar"
:show-extra-options="true"
:source-date="invoiceStore.newInvoice.invoice_date"
/>
</BaseInputGroup>

View File

@ -54,6 +54,8 @@
label="name"
:options="itemStore.itemUnits"
value-prop="id"
:can-deselect="false"
:can-clear="false"
:placeholder="$t('items.select_a_unit')"
searchable
track-by="name"

View File

@ -82,9 +82,9 @@
required
>
<BaseCustomerSelectInput
v-if="!isLoadingContent"
v-model="paymentStore.currentPayment.customer_id"
:content-loading="isLoadingContent"
v-if="!isLoadingContent"
:invalid="v$.currentPayment.customer_id.$error"
:placeholder="$t('customers.select_a_customer')"
show-action
@ -423,7 +423,7 @@ function onCustomerChange(customer_id) {
if (customer_id) {
let data = {
customer_id: customer_id,
tab_status: 'DUE',
status: 'DUE',
limit: 'all',
}
@ -446,11 +446,7 @@ function onCustomerChange(customer_id) {
paymentStore.currentPayment.selectedCustomer = res2.data.data
paymentStore.currentPayment.customer = res2.data.data
paymentStore.currentPayment.currency = res2.data.data.currency
if (
isEdit.value &&
!customerStore.editCustomer &&
paymentStore.currentPayment.customer_id
) {
if(isEdit.value && !customerStore.editCustomer && paymentStore.currentPayment.customer_id) {
customerStore.editCustomer = res2.data.data
}
}

View File

@ -28,19 +28,6 @@
/>
</BaseInputGroup>
<BaseInputGroup
:label="$tc('settings.company_info.company_slug')"
:help-text="$t('settings.company_info.company_slug_help_text')"
:error="v$.slug.$error && v$.slug.$errors[0].$message"
required
>
<BaseInput
v-model="companyForm.slug"
:invalid="v$.slug.$error"
@blur="v$.slug.$touch()"
/>
</BaseInputGroup>
<BaseInputGroup :label="$tc('settings.company_info.phone')">
<BaseInput v-model="companyForm.address.phone" />
</BaseInputGroup>
@ -173,7 +160,6 @@ let isSaving = ref(false)
const companyForm = reactive({
name: null,
slug: null,
logo: null,
address: {
address_street_1: '',
@ -207,14 +193,7 @@ const rules = computed(() => {
name: {
required: helpers.withMessage(t('validation.required'), required),
minLength: helpers.withMessage(
t('validation.name_min_length', { count: 3 }),
minLength(3)
),
},
slug: {
required: helpers.withMessage(t('validation.required'), required),
minLength: helpers.withMessage(
t('validation.name_min_length', { count: 3 }),
t('validation.name_min_length'),
minLength(3)
),
},

View File

@ -8,11 +8,7 @@
<BaseInputGroup
:content-loading="isFetchingInitialData"
:label="$tc('settings.preferences.currency')"
:help-text="
isCurrencyDisabled
? $t('settings.preferences.company_currency_unchangeable')
: ''
"
:help-text="$t('settings.preferences.company_currency_unchangeable')"
:error="v$.currency.$error && v$.currency.$errors[0].$message"
required
>
@ -25,7 +21,7 @@
:searchable="true"
track-by="name"
:invalid="v$.currency.$error"
:disabled="isCurrencyDisabled"
disabled
class="w-full"
>
</BaseMultiselect>
@ -191,7 +187,6 @@ const { t, tm } = useI18n()
let isSaving = ref(false)
let isDataSaving = ref(false)
let isFetchingInitialData = ref(false)
let isCurrencyDisabled = ref(true)
const settingsForm = reactive({ ...companyStore.selectedCompanySettings })
@ -287,14 +282,10 @@ setInitialData()
async function setInitialData() {
isFetchingInitialData.value = true
Promise.all([
companyStore.checkCompanyHasCurrencyTransactions(),
globalStore.fetchCurrencies(),
globalStore.fetchDateFormats(),
globalStore.fetchTimeZones(),
]).then(([res1]) => {
if (res1.data?.has_transactions == false) {
isCurrencyDisabled.value = false
}
isFetchingInitialData.value = false
})
}

View File

@ -1,101 +0,0 @@
<!-- This example requires Tailwind CSS v2.0+ -->
<script lang="ts" setup>
import { Switch, SwitchGroup, SwitchLabel } from '@headlessui/vue'
import { useGlobalStore } from '@/scripts/admin/stores/global'
import { computed, ref } from 'vue'
defineProps({
showLabel: {
type: Boolean,
default: true,
},
vertical: {
type: Boolean,
default: false,
},
})
const globalStore = useGlobalStore()
const enabled = ref(
localStorage.getItem('theme') === 'dark' ||
document.documentElement.classList.contains('dark')
)
globalStore.isDarkModeOn = enabled
function onChange(val) {
if (val) {
localStorage.theme = 'dark'
document.documentElement.classList.add('dark')
document.documentElement.style.setProperty('color-scheme', 'dark')
globalStore.isDarkModeOn = true
} else {
localStorage.theme = 'light'
document.documentElement.classList.remove('dark')
document.documentElement.style.setProperty('color-scheme', 'light')
globalStore.isDarkModeOn = false
}
}
</script>
<template>
<div class="w-full flex justify-center">
<SwitchGroup
as="div"
class="flex items-center"
:class="vertical ? 'flex-col justify-center' : 'flex-row'"
>
<Switch
v-model="enabled"
class="relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 dark:ring-offset-gray-700"
:class="[enabled ? 'bg-primary-600' : 'bg-gray-200']"
@update:modelValue="onChange"
>
<span class="sr-only">Use setting</span>
<span
class="pointer-events-none relative inline-block h-5 w-5 rounded-full bg-white shadow transform ring-0 transition ease-in-out duration-200"
:class="[enabled ? 'translate-x-5' : 'translate-x-0']"
>
<span
class="absolute inset-0 h-full w-full flex items-center justify-center transition-opacity"
:class="[
enabled
? 'opacity-0 ease-out duration-100'
: 'opacity-100 ease-in duration-200',
]"
aria-hidden="true"
>
<BaseIcon class="h-3 w-3 text-yellow-500" name="SunIcon" />
</span>
<span
class="absolute inset-0 h-full w-full flex items-center justify-center transition-opacity"
:class="[
enabled
? 'opacity-100 ease-in duration-200'
: 'opacity-0 ease-out duration-100',
]"
aria-hidden="true"
>
<BaseIcon class="h-3 w-3 text-primary-500" name="MoonIcon" />
</span>
</span>
</Switch>
<SwitchLabel
v-if="showLabel"
as="span"
class="cursor-pointer"
:class="vertical ? 'px-1 text-center mt-2' : 'ml-3'"
>
<span
v-if="enabled"
class="text-sm font-medium text-gray-500 dark:text-gray-400"
>
Dark Mode
</span>
<span v-else class="text-sm font-medium text-gray-500">
Light Mode
</span>
</SwitchLabel>
</SwitchGroup>
</div>
</template>

View File

@ -126,7 +126,7 @@ onMounted(() => {
})
const value = computed({
get: () => (props.modelValue ? props.modelValue : ''),
get: () => props.modelValue,
set: (value) => {
emit('update:modelValue', value)
},
@ -195,9 +195,7 @@ async function getFields() {
{ label: 'Date', value: 'INVOICE_DATE' },
{ label: 'Due Date', value: 'INVOICE_DUE_DATE' },
{ label: 'Number', value: 'INVOICE_NUMBER' },
{ label: 'PDF Link', value: 'PDF_LINK' },
{ label: 'Due Amount', value: 'DUE_AMOUNT' },
{ label: 'Total Amount', value: 'TOTAL_AMOUNT' },
{ label: 'Ref Number', value: 'INVOICE_REF_NUMBER' },
...invoiceFields.value.map((i) => ({
label: i.label,
value: i.slug,
@ -213,8 +211,7 @@ async function getFields() {
{ label: 'Date', value: 'ESTIMATE_DATE' },
{ label: 'Expiry Date', value: 'ESTIMATE_EXPIRY_DATE' },
{ label: 'Number', value: 'ESTIMATE_NUMBER' },
{ label: 'PDF Link', value: 'PDF_LINK' },
{ label: 'Total Amount', value: 'TOTAL_AMOUNT' },
{ label: 'Ref Number', value: 'ESTIMATE_REF_NUMBER' },
...estimateFields.value.map((i) => ({
label: i.label,
value: i.slug,
@ -231,7 +228,6 @@ async function getFields() {
{ label: 'Number', value: 'PAYMENT_NUMBER' },
{ label: 'Mode', value: 'PAYMENT_MODE' },
{ label: 'Amount', value: 'PAYMENT_AMOUNT' },
{ label: 'PDF Link', value: 'PDF_LINK' },
...paymentFields.value.map((i) => ({
label: i.label,
value: i.slug,

View File

@ -7,108 +7,52 @@
/>
</BaseContentPlaceholders>
<div v-else :class="computedContainerClass">
<date-picker
ref="vCalendar"
v-model="date"
:mode="mode"
:is24hr="time24hr"
class="w-full"
color="indigo"
:input-debounce="500"
:update-on-input="false"
:is-range="false"
trim-weeks
:is-required="isRequired"
:popover="{
visibility: disabled ? 'hidden' : 'focus',
showDelay: 0,
hideDelay: 1,
}"
:attributes="attrs"
:model-config="config"
:masks="masks"
:locale="global.locale"
<div v-else :class="computedContainerClass" class="relative flex flex-row">
<svg
v-if="showCalendarIcon && !hasIconSlot"
viewBox="0 0 20 20"
fill="currentColor"
class="
absolute
w-4
h-4
mx-2
my-2.5
text-sm
not-italic
font-black
text-gray-400
cursor-pointer
"
@click="onClickDp"
>
<template
#default="{ inputValue, inputEvents, togglePopover, hidePopover }"
>
<!-- calendar icon -->
<svg
v-if="showCalendarIcon && !hasIconSlot"
viewBox="0 0 20 20"
fill="currentColor"
class="
absolute
w-4
h-4
mx-2
my-2.5
text-sm
not-italic
font-black
text-gray-400
cursor-pointer
"
@click="togglePopover()"
>
<path
fill-rule="evenodd"
d="M6 2a1 1 0 00-1 1v1H4a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-1V3a1 1 0 10-2 0v1H7V3a1 1 0 00-1-1zm0 5a1 1 0 000 2h8a1 1 0 100-2H6z"
clip-rule="evenodd"
></path>
</svg>
<path
fill-rule="evenodd"
d="M6 2a1 1 0 00-1 1v1H4a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-1V3a1 1 0 10-2 0v1H7V3a1 1 0 00-1-1zm0 5a1 1 0 000 2h8a1 1 0 100-2H6z"
clip-rule="evenodd"
></path>
</svg>
<slot v-if="showCalendarIcon && hasIconSlot" name="icon" />
<slot v-if="showCalendarIcon && hasIconSlot" name="icon" />
<input
:value="inputValue"
:class="[defaultInputClass, inputInvalidClass, inputDisabledClass]"
readonly
v-on="inputEvents"
@blur="hidePopover()"
/>
</template>
<template v-if="showExtraOptions" #footer>
<div
class="bg-gray-100 grid grid-cols-3 gap-2 p-2 border-t rounded-b-lg"
>
<button type="button" class="extra-button" @click="moveToDate(sourceDate)">
{{ global.t('date_picker.same_day') }}
</button>
<button type="button" class="extra-button" @click="withInDays(7)">
{{ global.t('date_picker.within_7_days') }}
</button>
<button type="button" class="extra-button" @click="withInDays(15)">
{{ global.t('date_picker.within_15_days') }}
</button>
<button type="button" class="extra-button" @click="withInDays(30)">
{{ global.t('date_picker.within_30_days') }}
</button>
<button type="button" class="extra-button" @click="withInDays(45)">
{{ global.t('date_picker.within_45_days') }}
</button>
<button type="button" class="extra-button" @click="withInDays(60)">
{{ global.t('date_picker.within_60_days') }}
</button>
</div>
</template>
</date-picker>
<FlatPickr
ref="dp"
v-model="date"
v-bind="$attrs"
:disabled="disabled"
:config="config"
:class="[defaultInputClass, inputInvalidClass, inputDisabledClass]"
/>
</div>
</template>
<script type="text/babel" setup>
import { Calendar, DatePicker } from 'v-calendar'
import 'v-calendar/dist/style.css'
import FlatPickr from 'vue-flatpickr-component'
import 'flatpickr/dist/flatpickr.css'
import { computed, reactive, watch, ref, useSlots } from 'vue'
import { useCompanyStore } from '@/scripts/admin/stores/company'
import moment from 'moment'
const dp = ref(null)
const props = defineProps({
modelValue: {
@ -146,31 +90,36 @@ const props = defineProps({
defaultInputClass: {
type: String,
default:
'border-2 font-base pl-8 py-2 outline-none focus:ring-primary-400 focus:outline-none focus:border-primary-400 block w-full sm:text-sm border-gray-200 rounded-md text-black',
'font-base pl-8 py-2 outline-none focus:ring-primary-400 focus:outline-none focus:border-primary-400 block w-full sm:text-sm border-gray-200 rounded-md text-black',
},
time24hr: {
type: Boolean,
default: false,
},
isRequired: {
type: Boolean,
default: false,
},
showExtraOptions: {
type: Boolean,
default: false,
},
sourceDate: {
type: [String, Date],
default: () => new Date(),
}
})
const emit = defineEmits(['update:modelValue'])
const slots = useSlots()
const companyStore = useCompanyStore()
const { global } = window.i18n
const vCalendar = ref(null)
let config = reactive({
altInput: true,
enableTime: props.enableTime,
time_24hr: props.time24hr,
})
const date = computed({
get: () => props.modelValue,
set: (value) => {
emit('update:modelValue', value)
},
})
const carbonFormat = computed(() => {
return companyStore.selectedCompanySettings?.carbon_date_format
})
const hasIconSlot = computed(() => {
return !!slots.icon
@ -186,6 +135,7 @@ const inputInvalidClass = computed(() => {
if (props.invalid) {
return 'border-red-400 ring-red-400 focus:ring-red-400 focus:border-red-400'
}
return ''
})
@ -193,97 +143,35 @@ const inputDisabledClass = computed(() => {
if (props.disabled) {
return 'border border-solid rounded-md outline-none input-field box-border-2 base-date-picker-input placeholder-gray-400 bg-gray-200 text-gray-600 border-gray-200'
}
return ''
})
// to convert YYYY-MM-DD | YYYY-MM-DD HH:mm format
function convertYMDFormat(date) {
let format = props.enableTime ? 'YYYY-MM-DD HH:mm' : 'YYYY-MM-DD'
return date ? moment(date).format(format) : date
function onClickDp(params) {
dp.value.fp.open()
}
const date = computed({
get: () => props.modelValue,
set: (value) => {
emit('update:modelValue', value)
},
})
const mode = computed(() => {
return props.enableTime ? 'dateTime' : 'date'
})
const config = reactive({
type: 'string',
mask: 'YYYY-MM-DD', // Uses 'iso' if missing
//timeAdjust: '00:00:00',
})
const masks = reactive({
input: null,
inputDateTime: null,
inputDateTime24hr: null,
})
const attrs = reactive([
{
dates: new Date(),
highlight: {
fillMode: 'outline',
},
/* popover: {
label: 'Today Date',
visibility: 'hover',
}, */
},
])
const carbonFormat = computed(() => {
return companyStore.selectedCompanySettings?.moment_date_format
})
watch(
() => carbonFormat,
() => {
if (!props.enableTime) {
masks.input = carbonFormat.value ? carbonFormat.value : 'DD MMM YYYY'
config.mask = 'YYYY-MM-DD'
} else {
let timeFormat = 'HH:mm'
if (props.time24hr) {
masks.inputDateTime24hr = carbonFormat.value
? `${carbonFormat.value} ${timeFormat}`
: `DD MMM YYYY ${timeFormat}`
} else {
masks.inputDateTime = carbonFormat.value
? `${carbonFormat.value} ${timeFormat}`
: `DD MMM YYYY ${timeFormat}`
}
config.mask = `YYYY-MM-DD ${timeFormat}`
() => props.enableTime,
(val) => {
if (props.enableTime) {
config.enableTime = props.enableTime
}
},
{ immediate: true }
)
async function moveToDate(_date) {
const calendar = vCalendar.value
_date = _date ? _date : convertYMDFormat(new Date())
date.value = _date
// await calendar.move(_date)
calendar.hidePopover()
}
async function withInDays(noOfDays) {
if (!noOfDays) return false
let newDate = moment(props.sourceDate).add(noOfDays, 'days').toDate()
newDate = convertYMDFormat(newDate)
moveToDate(newDate)
}
watch(
() => carbonFormat,
() => {
if (!props.enableTime) {
config.altFormat = carbonFormat.value ? carbonFormat.value : 'd M Y'
} else {
config.altFormat = carbonFormat.value
? `${carbonFormat.value} H:i `
: 'd M Y H:i'
}
},
{ immediate: true }
)
</script>
<style scoped>
.extra-button {
@apply bg-primary-500 text-white text-sm font-semibold px-2 py-1 rounded hover:bg-primary-700;
}
</style>

View File

@ -1,10 +1,6 @@
<template>
<div>
<TabGroup
:selected-index="selectedIndex"
:default-index="defaultIndex"
@change="onChange"
>
<TabGroup :default-index="defaultIndex" @change="onChange">
<TabList
:class="[
'flex border-b border-grey-light',
@ -58,10 +54,6 @@ const props = defineProps({
type: Number,
default: 0,
},
selectedIndex: {
type: Number,
default: 0,
},
filter: {
type: String,
default: null,
@ -75,6 +67,6 @@ const slots = useSlots()
const tabs = computed(() => slots.default().map((tab) => tab.props))
function onChange(d) {
emit('change', tabs.value[d], d)
emit('change', tabs.value[d])
}
</script>

View File

@ -3,26 +3,23 @@
width="50"
height="50"
viewBox="0 0 50 50"
:class="colorClass"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<circle cx="25" cy="25" r="25" :class="bgColor" />
<circle cx="25" cy="25" r="25" fill="#EAF1FB" />
<path
d="M28.2656 23.0547C27.3021 24.0182 26.1302 24.5 24.75 24.5C23.3698 24.5 22.1849 24.0182 21.1953 23.0547C20.2318 22.0651 19.75 20.8802 19.75 19.5C19.75 18.1198 20.2318 16.9479 21.1953 15.9844C22.1849 14.9948 23.3698 14.5 24.75 14.5C26.1302 14.5 27.3021 14.9948 28.2656 15.9844C29.2552 16.9479 29.75 18.1198 29.75 19.5C29.75 20.8802 29.2552 22.0651 28.2656 23.0547ZM28.2656 25.75C29.6979 25.75 30.9219 26.2708 31.9375 27.3125C32.9792 28.3281 33.5 29.5521 33.5 30.9844V32.625C33.5 33.1458 33.3177 33.5885 32.9531 33.9531C32.5885 34.3177 32.1458 34.5 31.625 34.5H17.875C17.3542 34.5 16.9115 34.3177 16.5469 33.9531C16.1823 33.5885 16 33.1458 16 32.625V30.9844C16 29.5521 16.5078 28.3281 17.5234 27.3125C18.5651 26.2708 19.8021 25.75 21.2344 25.75H21.8984C22.8099 26.1667 23.7604 26.375 24.75 26.375C25.7396 26.375 26.6901 26.1667 27.6016 25.75H28.2656Z"
:class="color"
fill="currentColor"
/>
</svg>
</template>
<script setup>
const props = defineProps({
color: {
colorClass: {
type: String,
default: 'fill-primary-500 dark:fill-white',
},
bgColor: {
type: String,
default: 'fill-gray-100 dark:fill-primary-400',
default: 'text-primary-500',
},
})
</script>

View File

@ -6,24 +6,10 @@
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<circle :class="bgColor" cx="25" cy="25" r="25" />
<circle cx="25" cy="25" r="25" fill="#FDE4E5" />
<path
:class="color"
d="M27.2031 23.6016C28.349 23.9401 29.2083 24.6562 29.7812 25.75C30.3802 26.8438 30.4714 27.9766 30.0547 29.1484C29.7422 30.0078 29.2083 30.6979 28.4531 31.2188C27.6979 31.7135 26.8516 31.974 25.9141 32V33.875C25.9141 34.0573 25.849 34.2005 25.7188 34.3047C25.6146 34.4349 25.4714 34.5 25.2891 34.5H24.0391C23.8568 34.5 23.7005 34.4349 23.5703 34.3047C23.4661 34.2005 23.4141 34.0573 23.4141 33.875V32C22.1641 32 21.0443 31.6094 20.0547 30.8281C19.8984 30.6979 19.8073 30.5417 19.7812 30.3594C19.7552 30.1771 19.8203 30.0208 19.9766 29.8906L21.3047 28.5625C21.5651 28.3281 21.8255 28.3021 22.0859 28.4844C22.4766 28.7448 22.9193 28.875 23.4141 28.875H25.9922C26.3307 28.875 26.6042 28.7708 26.8125 28.5625C27.0469 28.3281 27.1641 28.0417 27.1641 27.7031C27.1641 27.1302 26.8906 26.7656 26.3438 26.6094L22.3203 25.4375C21.4349 25.1771 20.6927 24.7083 20.0938 24.0312C19.4948 23.3542 19.1432 22.5729 19.0391 21.6875C18.9349 20.4115 19.2995 19.3177 20.1328 18.4062C20.9922 17.4688 22.0599 17 23.3359 17H23.4141V15.125C23.4141 14.9427 23.4661 14.7995 23.5703 14.6953C23.7005 14.5651 23.8568 14.5 24.0391 14.5H25.2891C25.4714 14.5 25.6146 14.5651 25.7188 14.6953C25.849 14.7995 25.9141 14.9427 25.9141 15.125V17C27.1641 17 28.2839 17.3906 29.2734 18.1719C29.4297 18.3021 29.5208 18.4583 29.5469 18.6406C29.5729 18.8229 29.5078 18.9792 29.3516 19.1094L28.0234 20.4375C27.763 20.6719 27.5026 20.6979 27.2422 20.5156C26.8516 20.2552 26.4089 20.125 25.9141 20.125H23.3359C22.9974 20.125 22.7109 20.2422 22.4766 20.4766C22.2682 20.6849 22.1641 20.9583 22.1641 21.2969C22.1641 21.5312 22.2422 21.7526 22.3984 21.9609C22.5547 22.1693 22.75 22.3125 22.9844 22.3906L27.2031 23.6016Z"
fill="#FB7178"
/>
</svg>
</template>
<script setup>
const props = defineProps({
color: {
type: String,
default: 'fill-red-400 dark:fill-white',
},
bgColor: {
type: String,
default: 'fill-red-100 dark:fill-red-400',
},
})
</script>

View File

@ -5,24 +5,21 @@
viewBox="0 0 50 50"
fill="none"
xmlns="http://www.w3.org/2000/svg"
:class="colorClass"
>
<circle cx="25" cy="25" r="25" :class="bgColor" />
<circle cx="25" cy="25" r="25" fill="#EAF1FB" />
<path
d="M26.75 19.8125C26.75 20.0729 26.8411 20.2943 27.0234 20.4766C27.2057 20.6589 27.4271 20.75 27.6875 20.75H33V33.5625C33 33.8229 32.9089 34.0443 32.7266 34.2266C32.5443 34.4089 32.3229 34.5 32.0625 34.5H18.9375C18.6771 34.5 18.4557 34.4089 18.2734 34.2266C18.0911 34.0443 18 33.8229 18 33.5625V15.4375C18 15.1771 18.0911 14.9557 18.2734 14.7734C18.4557 14.5911 18.6771 14.5 18.9375 14.5H26.75V19.8125ZM33 19.2656V19.5H28V14.5H28.2344C28.4948 14.5 28.7161 14.5911 28.8984 14.7734L32.7266 18.6016C32.9089 18.7839 33 19.0052 33 19.2656Z"
:class="color"
fill="currentColor"
/>
</svg>
</template>
<script setup>
const props = defineProps({
color: {
colorClass: {
type: String,
default: 'fill-primary-500 dark:fill-white',
},
bgColor: {
type: String,
default: 'fill-gray-100 dark:fill-primary-400',
default: 'text-primary-500',
},
})
</script>

View File

@ -5,24 +5,21 @@
viewBox="0 0 50 50"
fill="none"
xmlns="http://www.w3.org/2000/svg"
:class="colorClass"
>
<circle cx="25" cy="25" r="25" :class="bgColor" />
<circle cx="25" cy="25" r="25" fill="#EAF1FB" />
<path
d="M28.25 24.5V27H20.75V24.5H28.25ZM31.7266 18.6016C31.9089 18.7839 32 19.0052 32 19.2656V19.5H27V14.5H27.2344C27.4948 14.5 27.7161 14.5911 27.8984 14.7734L31.7266 18.6016ZM25.75 19.8125C25.75 20.0729 25.8411 20.2943 26.0234 20.4766C26.2057 20.6589 26.4271 20.75 26.6875 20.75H32V33.5625C32 33.8229 31.9089 34.0443 31.7266 34.2266C31.5443 34.4089 31.3229 34.5 31.0625 34.5H17.9375C17.6771 34.5 17.4557 34.4089 17.2734 34.2266C17.0911 34.0443 17 33.8229 17 33.5625V15.4375C17 15.1771 17.0911 14.9557 17.2734 14.7734C17.4557 14.5911 17.6771 14.5 17.9375 14.5H25.75V19.8125ZM19.5 17.3125V17.9375C19.5 18.1458 19.6042 18.25 19.8125 18.25H22.9375C23.1458 18.25 23.25 18.1458 23.25 17.9375V17.3125C23.25 17.1042 23.1458 17 22.9375 17H19.8125C19.6042 17 19.5 17.1042 19.5 17.3125ZM19.5 19.8125V20.4375C19.5 20.6458 19.6042 20.75 19.8125 20.75H22.9375C23.1458 20.75 23.25 20.6458 23.25 20.4375V19.8125C23.25 19.6042 23.1458 19.5 22.9375 19.5H19.8125C19.6042 19.5 19.5 19.6042 19.5 19.8125ZM29.5 31.6875V31.0625C29.5 30.8542 29.3958 30.75 29.1875 30.75H26.0625C25.8542 30.75 25.75 30.8542 25.75 31.0625V31.6875C25.75 31.8958 25.8542 32 26.0625 32H29.1875C29.3958 32 29.5 31.8958 29.5 31.6875ZM29.5 23.875C29.5 23.6927 29.4349 23.5495 29.3047 23.4453C29.2005 23.3151 29.0573 23.25 28.875 23.25H20.125C19.9427 23.25 19.7865 23.3151 19.6562 23.4453C19.5521 23.5495 19.5 23.6927 19.5 23.875V27.625C19.5 27.8073 19.5521 27.9635 19.6562 28.0938C19.7865 28.1979 19.9427 28.25 20.125 28.25H28.875C29.0573 28.25 29.2005 28.1979 29.3047 28.0938C29.4349 27.9635 29.5 27.8073 29.5 27.625V23.875Z"
:class="color"
fill="currentColor"
/>
</svg>
</template>
<script setup>
const props = defineProps({
color: {
colorClass: {
type: String,
default: 'fill-primary-500 dark:fill-white',
},
bgColor: {
type: String,
default: 'fill-gray-100 dark:fill-primary-400',
default: 'text-primary-500',
},
})
</script>

View File

@ -7,12 +7,12 @@ export function usePopper(options) {
let popper = ref(null)
onMounted(() => {
watchEffect((onInvalidate) => {
watchEffect(onInvalidate => {
if (!container.value) return
if (!activator.value) return
let containerEl = container.value.el || container.value
let activatorEl = activator.value.$el || activator.value
let activatorEl = activator.value.el || activator.value
if (!(activatorEl instanceof HTMLElement)) return
if (!(containerEl instanceof HTMLElement)) return

View File

@ -4,7 +4,7 @@
"customers": "العملاء",
"items": "بضائع/خدمات",
"invoices": "الفواتير",
"recurring-invoices": "Recurring Invoices",
"recurring-invoices": "الفواتير المتكررة",
"expenses": "النفقات",
"estimates": "التقديرات",
"payments": "الدفوعات",
@ -12,7 +12,7 @@
"settings": "الإعدادات",
"logout": "تسجيل الخروج",
"users": "المستخدمون",
"modules": "Modules"
"modules": "الإضافات"
},
"general": {
"add_company": "أضف شركة",
@ -29,9 +29,9 @@
"to_date": "إلى تاريخ",
"from": "من",
"to": "إلى",
"ok": "Ok",
"yes": "Yes",
"no": "No",
"ok": "حسناً",
"yes": "نعم",
"no": "لا",
"sort_by": "ترتيب حسب",
"ascending": "تصاعدي",
"descending": "تنازلي",
@ -39,7 +39,7 @@
"body": "الجسم",
"message": "رسالة",
"send": "إرسال",
"preview": "Preview",
"preview": "معاينة",
"go_back": "إلى الخلف",
"back_to_login": "العودة إلى تسجيل الدخول؟",
"home": "الرئيسية",
@ -65,7 +65,7 @@
"sent": "ارسلت",
"all": "الكل",
"select_all": "تحديد الكل",
"select_template": "Select Template",
"select_template": "تحديد القالب",
"choose_file": "اضغط هنا لاختيار ملف",
"choose_template": "اختيار القالب",
"choose": "اختر",
@ -93,14 +93,14 @@
"no_note_found": "لم يتم العثور على الملاحظة",
"insert_note": "أدخل ملاحظة",
"copied_pdf_url_clipboard": "تم نسخ رابط PDF إلى الحافظة!",
"copied_url_clipboard": "Copied url to clipboard!",
"docs": "Docs",
"do_you_wish_to_continue": "Do you wish to continue?",
"note": "Note",
"pay_invoice": "Pay Invoice",
"login_successfully": "Logged in successfully!",
"logged_out_successfully": "Logged out successfully",
"mark_as_default": "Mark as default"
"copied_url_clipboard": "تم نسخ الرابط إلى الحافظة!",
"docs": "المستندات",
"do_you_wish_to_continue": "هل ترغب في المتابعة؟",
"note": "ملاحظة",
"pay_invoice": "سدد الفاتورة",
"login_successfully": "تم تسجيل الدخول بنجاح!",
"logged_out_successfully": "تم تسجيل الخروج",
"mark_as_default": "تحديد كافتراضي"
},
"dashboard": {
"select_year": "اختر السنة",
@ -109,7 +109,7 @@
"customers": "العملاء",
"invoices": "الفواتير",
"estimates": "التقديرات",
"payments": "Payments"
"payments": "المدفوعات"
},
"chart_info": {
"total_sales": "المبيعات",
@ -151,27 +151,27 @@
"no_results_found": "لم يتم العثور على نتائج"
},
"company_switcher": {
"label": "SWITCH COMPANY",
"no_results_found": "No Results Found",
"add_new_company": "Add new company",
"new_company": "New company",
"created_message": "Company created successfully"
"label": "تبديل الشركة",
"no_results_found": "لا توجد نتائج",
"add_new_company": "إضافة شركة جديدة",
"new_company": "شركة جديدة",
"created_message": "تم إنشاء الشركة بنجاح"
},
"dateRange": {
"today": "Today",
"this_week": "This Week",
"this_month": "This Month",
"this_quarter": "This Quarter",
"this_year": "This Year",
"previous_week": "Previous Week",
"previous_month": "Previous Month",
"previous_quarter": "Previous Quarter",
"previous_year": "Previous Year",
"custom": "Custom"
"today": "اليوم",
"this_week": "هذا الاسبوع",
"this_month": "هذا الشهر",
"this_quarter": "هذا الربع",
"this_year": "هذه السنة",
"previous_week": "الأسبوع السابق",
"previous_month": "الشهر الماضي",
"previous_quarter": "الربع السابق",
"previous_year": "السنة الماضية",
"custom": "مخصص"
},
"customers": {
"title": "العملاء",
"prefix": "Prefix",
"prefix": "البادئة",
"add_customer": "إضافة عميل",
"contacts_list": "قائمة العملاء",
"name": "الاسم",
@ -186,9 +186,9 @@
"phone": "الهاتف",
"website": "موقع الإنترنت",
"overview": "استعراض",
"invoice_prefix": "Invoice Prefix",
"estimate_prefix": "Estimate Prefix",
"payment_prefix": "Payment Prefix",
"invoice_prefix": "بادئة الفاتورة",
"estimate_prefix": "بادئة رقم التقدير",
"payment_prefix": "بادئة رقم الدفعة",
"enable_portal": "تفعيل البوابة",
"country": "الدولة",
"state": "الولاية/المنطقة",
@ -197,7 +197,7 @@
"added_on": "أضيف في",
"action": "إجراء",
"password": "كلمة المرور",
"confirm_password": "Confirm Password",
"confirm_password": "تأكيد كلمة المرور",
"street_number": "رقم الشارع",
"primary_currency": "العملة الرئيسية",
"description": "الوصف",
@ -208,10 +208,10 @@
"new_customer": "عميل جديد",
"edit_customer": "تعديل عميل",
"basic_info": "معلوات أساسية",
"portal_access": "Portal Access",
"portal_access_text": "Would you like to allow this customer to login to the Customer Portal?",
"portal_access_url": "Customer Portal Login URL",
"portal_access_url_help": "Please copy & forward the above given URL to your customer for providing access.",
"portal_access": "الوصول إلى بوابة العملاء",
"portal_access_text": "هل تريد السماح لهذا العميل بتسجيل الدخول إلى بوابة العملاء؟",
"portal_access_url": "رابط بوابة العملاء",
"portal_access_url_help": "يرجى نسخ وإعادة إرسال عنوان URL أعلاه إلى الزبون لتوفير الوصول.",
"billing_address": "عنوان الفوترة",
"shipping_address": "عنوان الشحن",
"copy_billing_address": "نسخ من عنوان الفوترة",
@ -231,9 +231,9 @@
"confirm_delete": "لن تتمكن من استرداد هذا العميل وجميع الفواتير والتقديرات والمدفوعات ذات الصلة. | لن تتمكن من استرداد هؤلاء العملاء وجميع الفواتير والتقديرات والمدفوعات ذات الصلة.",
"created_message": "تم إنشاء العملاء بنجاح",
"updated_message": "تم تحديث العملاء بنجاح",
"address_updated_message": "Address Information Updated succesfully",
"address_updated_message": "تم تحديث العنوان بنجاح",
"deleted_message": "تم حذف العملاء بنجاح | تم حذف العميل بنجاح",
"edit_currency_not_allowed": "Cannot change currency once transactions created."
"edit_currency_not_allowed": "لا يمكن تغيير العملة بمجرد إنشاء معاملة."
},
"items": {
"title": "الأصناف",
@ -265,8 +265,8 @@
},
"estimates": {
"title": "التقديرات",
"accept_estimate": "Accept Estimate",
"reject_estimate": "Reject Estimate",
"accept_estimate": "قبول التقدير",
"reject_estimate": "رفض التقدير",
"estimate": "تقدير | تقديرات",
"estimates_list": "قائمة التقديرات",
"days": "{days} أيام",
@ -318,10 +318,10 @@
},
"accepted": "مقبول",
"rejected": "مرفوض",
"expired": "Expired",
"expired": "انتهت مدة الصلاحية",
"sent": "مرسل",
"draft": "مسودة",
"viewed": "Viewed",
"viewed": "تمت المشاهدة",
"declined": "مرفوض",
"new_estimate": "تقدير جديد",
"add_new_estimate": "إضافة تقدير جديد",
@ -355,14 +355,14 @@
"select_an_item": "اكتب أو اختر الصنف",
"type_item_description": "اكتب وصف الصنف (اختياري)"
},
"mark_as_default_estimate_template_description": "If enabled, the selected template will be automatically selected for new estimates."
"mark_as_default_estimate_template_description": "في حالة التعفيل، سيتم اختيار القالب المحدد تلقائياً للتقديرات الجديدة."
},
"invoices": {
"title": "الفواتير",
"download": "Download",
"pay_invoice": "Pay Invoice",
"download": "تحميل",
"pay_invoice": "سدد الفاتورة",
"invoices_list": "قائمة الفواتير",
"invoice_information": "Invoice Information",
"invoice_information": "معلومات الفاتورة",
"days": "{days} أيام",
"months": "{months} أشهر",
"years": "{years} سنوات",
@ -397,13 +397,13 @@
"send_invoice": "إرسال الفاتورة",
"resend_invoice": "إعادة إرسال الفاتورة",
"invoice_template": "قالب الفاتورة",
"conversion_message": "Invoice cloned successful",
"conversion_message": "تم استنساخ الفاتورة بنجاح",
"template": "قالب",
"mark_as_sent": "تحديد كمرسل",
"confirm_send_invoice": "سيتم إرسال هذه الفاتورة بالبريد الألكتروني إلى العميل",
"invoice_mark_as_sent": "سيتم تحديد هذه الفاتورة كمرسلة",
"confirm_mark_as_accepted": "This invoice will be marked as Accepted",
"confirm_mark_as_rejected": "This invoice will be marked as Rejected",
"confirm_mark_as_accepted": "سيتم تحديد هذه الفاتورة كمقبولة",
"confirm_mark_as_rejected": "سيتم تحديد هذه الفاتورة كمرفوضة",
"confirm_send": "سيتم إرسال هذه الفاتورة بالبريد الألكتروني إلى العميل",
"invoice_date": "تاريخ الفاتورة",
"record_payment": "تسجيل مدفوعات",
@ -415,13 +415,13 @@
"update_invoice": "تحديث الفاتورة",
"add_new_tax": "إضافة ضريبة جديدة",
"no_invoices": "لا يوجد فواتير حتى الآن!",
"mark_as_rejected": "Mark as rejected",
"mark_as_accepted": "Mark as accepted",
"mark_as_rejected": "تحديد كمرفوض",
"mark_as_accepted": "تحديد كمقبول",
"list_of_invoices": "قائمة الفواتير .",
"select_invoice": "اختر الفاتورة",
"no_matching_invoices": "لا يوجد فواتير مطابقة!",
"mark_as_sent_successfully": "تم تحديد الفاتورة كمرسلة بنجاح",
"invoice_sent_successfully": "Invoice sent successfully",
"invoice_sent_successfully": "تم إرسال الفاتورة بنجاح",
"cloned_successfully": "تم استنساخ الفاتورة بنجاح",
"clone_invoice": "استنساخ الفاتورة",
"confirm_clone": "سيتم استنساخ هذه الفاتورة في فاتورة جديدة",
@ -447,14 +447,14 @@
"marked_as_sent_message": "تم إرسال الفاتورة بنجاح",
"something_went_wrong": "خطأ غير معروف!",
"invalid_due_amount_message": "المبلغ النهائي للفاتورة لا يمكن أن يكون أقل من المبلغ المطلوب لها. رجاءاً حدث الفاتورة أو قم بحذف المدفوعات المرتبطة بها للاستمرار.",
"mark_as_default_invoice_template_description": "If enabled, the selected template will be automatically selected for new invoices."
"mark_as_default_invoice_template_description": "في حالة التفعيل، سيتم اختيار القالب المحدد تلقائياً للفواتير الجديدة."
},
"recurring_invoices": {
"title": "Recurring Invoices",
"invoices_list": "Recurring Invoices List",
"days": "{days} Days",
"months": "{months} Month",
"years": "{years} Year",
"title": "الفواتير المتكررة",
"invoices_list": "الفواتير المتكررة",
"days": "{days} أيام",
"months": "{months} أشهر",
"years": "{years} سنوات",
"all": "All",
"paid": "Paid",
"unpaid": "Unpaid",
@ -1485,7 +1485,7 @@
"pdf_estimate_label": "تقدير",
"pdf_estimate_number": "رقم تقدير",
"pdf_estimate_date": "تاريخ التقدير",
"pdf_estimate_expire_date": "تاريخ انتهاء الصلاحية",
"pdf_estimate_expire_date": "Expiry Date",
"pdf_invoice_label": "الفاتورة",
"pdf_invoice_number": "رقم الفاتورة",
"pdf_invoice_date": "تاريخ الفاتورة",

View File

@ -112,7 +112,7 @@
"payments": "Platby"
},
"chart_info": {
"total_sales": "Slevy",
"total_sales": "Prodeje",
"total_receipts": "Doklady",
"total_expense": "Výdaje",
"net_income": "Čistý příjem",
@ -1485,7 +1485,7 @@
"pdf_estimate_label": "Odhad",
"pdf_estimate_number": "Číslo odhadu",
"pdf_estimate_date": "Datum odhadu",
"pdf_estimate_expire_date": "Doba platnosti",
"pdf_estimate_expire_date": "Datum expirace",
"pdf_invoice_label": "Faktura",
"pdf_invoice_number": "Číslo faktury",
"pdf_invoice_date": "Datum fakturace",
@ -1495,7 +1495,7 @@
"pdf_quantity_label": "Množství",
"pdf_price_label": "Cena",
"pdf_discount_label": "Sleva",
"pdf_amount_label": "Množství",
"pdf_amount_label": "Částka",
"pdf_subtotal": "Mezisoučet",
"pdf_total": "Celkem",
"pdf_payment_label": "Platba",

View File

@ -688,7 +688,7 @@
"other_modules": "Weitere Module",
"view_all": "Alle Anzeigen",
"no_reviews_found": "Für dieses Modul gibt es noch keine Bewertungen!",
"module_not_purchased": "Module Not Purchased",
"module_not_purchased": "Modul noch nicht erworben",
"module_not_found": "Modul nicht gefunden",
"version_not_supported": "This module version doesn't support the current version of Crater",
"last_updated": "Zuletzt aktualisiert am",
@ -1113,7 +1113,7 @@
"default_currency_error": "Diese Währung wird bereits in einem der aktiven Anbieter verwendet",
"exchange_help_text": "Wechselkurs eingeben um von {currency} nach {baseCurrency} zu konvertieren",
"currency_freak": "CurrencyFreaks",
"currency_layer": "Currency Layer",
"currency_layer": "Währungsebene",
"open_exchange_rate": "Open Exchange Rate",
"currency_converter": "Währungsumrechner",
"server": "Server",
@ -1150,8 +1150,8 @@
"payment_mode_added": "Zahlungsart hinzugefügt",
"payment_mode_updated": "Zahlungsart aktualisiert",
"payment_mode_confirm_delete": "Sie werden diese Zahlungsart nicht wiederherstellen können",
"payments_attached": "This payment method is already attached to payments. Please delete the attached payments to proceed with deletion.",
"expenses_attached": "This payment method is already attached to expenses. Please delete the attached expenses to proceed with deletion.",
"payments_attached": "Diese Zahlungsmethode ist bereits mit Zahlungen verknüpft. Bitte löschen Sie die angehängten Zahlungen, um mit der Löschung fortzufahren.",
"expenses_attached": "Diese Zahlungsmethode ist bereits mit Ausgaben verknüpft. Bitte löschen Sie die angehängten Ausgaben, um mit der Löschung fortzufahren.",
"deleted_message": "Zahlungsart erfolgreich gelöscht"
},
"expense_category": {
@ -1179,7 +1179,7 @@
"discount_per_item": "Rabatt pro Artikel ",
"discount_setting_description": "Aktivieren Sie diese Option, wenn Sie einzelnen Rechnungspositionen einen Rabatt hinzufügen möchten. Standardmäßig wird der Rabatt direkt zur Rechnung hinzugefügt.",
"expire_public_links": "Öffentliche Links automatisch ablaufen lassen",
"expire_setting_description": "Specify whether you would like to expire all the links sent by application to view invoices, estimates & payments, etc after a specified duration.",
"expire_setting_description": "Geben Sie an, ob Sie alle von der Anwendung gesendeten Links zur Ansicht von Rechnungen, Kostenvoranschlägen und Zahlungen usw. nach einer bestimmten Zeit ablaufen lassen möchten.",
"save": "Speichern",
"preference": "Präferenz | Präferenzen",
"general_settings": "Standardeinstellungen für das System.",
@ -1272,14 +1272,14 @@
"do_spaces_secret": "Do Spaces Secret",
"do_spaces_region": "Do Spaced Region",
"do_spaces_bucket": "Do Spaces Bucket",
"do_spaces_endpoint": "Do Spaces Endpoint",
"do_spaces_endpoint": "Do Spaces Endpunkt",
"do_spaces_root": "Do Spaced Root",
"dropbox_type": "Dropbox Typ",
"dropbox_token": "Dropbox Token",
"dropbox_key": "Dropbox Schlüssel",
"dropbox_secret": "Dropbox Secret",
"dropbox_app": "Dropbox App",
"dropbox_root": "Dropbox Root",
"dropbox_root": "Dropbox Root Verzeichnis",
"default_driver": "Standard-Treiber",
"is_default": "Standard",
"set_default_disk": "Als Standard festlegen",
@ -1485,7 +1485,7 @@
"pdf_estimate_label": "Angebot",
"pdf_estimate_number": "Angebotsnummer",
"pdf_estimate_date": "Angebotsdatum",
"pdf_estimate_expire_date": "Gültig bis",
"pdf_estimate_expire_date": "Zahlungsziel",
"pdf_invoice_label": "Rechnung",
"pdf_invoice_number": "Rechnungsnummer",
"pdf_invoice_date": "Rechnungsdatum",

View File

@ -1485,7 +1485,7 @@
"pdf_estimate_label": "Εκτίμηση",
"pdf_estimate_number": "Εκτίμηση Αριθμού",
"pdf_estimate_date": "Εκτιμώμενη ημ. επισκευής",
"pdf_estimate_expire_date": "Ημερομηνία λήξης",
"pdf_estimate_expire_date": "Expiry Date",
"pdf_invoice_label": "Τιμολόγιο",
"pdf_invoice_number": "Αριθμός τιμολογίου",
"pdf_invoice_date": "Ημ/νία Τιμολόγησης",

View File

@ -863,8 +863,6 @@
"company_info": {
"company_info": "Company info",
"company_name": "Company Name",
"company_slug": "Company Slug",
"company_slug_help_text": "A unique URL friendly name for your company (It will appear on Customer Portal URL)",
"company_logo": "Company Logo",
"section_description": "Information about your company that will be displayed on invoices, estimates and other documents created by Crater.",
"phone": "Phone",
@ -1326,8 +1324,6 @@
"company_info": "Company Information",
"company_info_desc": "This information will be displayed on invoices. Note that you can edit this later on settings page.",
"company_name": "Company Name",
"company_slug": "Company Slug",
"company_slug_help_text": "A unique URL friendly name for your company (It will appear on Customer Portal URL)",
"company_logo": "Company Logo",
"logo_preview": "Logo Preview",
"preferences": "Company Preferences",
@ -1458,8 +1454,7 @@
"at_least_one_ability": "Please select atleast one Permission.",
"valid_driver_key": "Please enter a valid {driver} key.",
"valid_exchange_rate": "Please enter a valid exchange rate.",
"company_name_not_same": "Company name must match with given name.",
"invalid_slug": "Invalid Slug"
"company_name_not_same": "Company name must match with given name."
},
"errors": {
"starter_plan": "This feature is available on Starter plan and onwards!",
@ -1527,13 +1522,5 @@
"pdf_bill_to": "Bill to,",
"pdf_ship_to": "Ship to,",
"pdf_received_from": "Received from:",
"pdf_tax_label": "Tax",
"date_picker": {
"same_day": "Same Day",
"within_7_days": "Within 7 Days",
"within_15_days": "Within 15 Days",
"within_30_days": "Within 30 Days",
"within_45_days": "Within 45 Days",
"within_60_days": "Within 60 Days"
}
"pdf_tax_label": "Tax"
}

View File

@ -1,6 +1,6 @@
{
"navigation": {
"dashboard": "Tablero",
"dashboard": "Panel de Control",
"customers": "Clientes",
"items": "Artículos",
"invoices": "Facturas",
@ -9,7 +9,7 @@
"estimates": "Presupuestos",
"payments": "Pagos",
"reports": "Informes",
"settings": "Ajustes",
"settings": "Configuración",
"logout": "Cerrar sesión",
"users": "Usuarios",
"modules": "Módulos"
@ -47,7 +47,7 @@
"delete": "Eliminar",
"edit": "Editar",
"view": "Ver",
"add_new_item": "Agregar ítem nuevo",
"add_new_item": "Agregar Nuevo Artículo",
"clear_all": "Limpiar todo",
"showing": "Mostrar",
"of": "de",
@ -87,7 +87,7 @@
"select_city": "Seleccionar ciudad",
"street_1": "Calle 1",
"street_2": "Calle 2",
"action_failed": "Accion Fallida",
"action_failed": "Acción Fallida",
"retry": "Procesar de nuevo",
"choose_note": "Elegir nota",
"no_note_found": "No se encontró ninguna nota",
@ -98,7 +98,7 @@
"do_you_wish_to_continue": "¿Deseas continuar?",
"note": "Nota",
"pay_invoice": "Pagar factura",
"login_successfully": "Logeado Satisfactoriamente!",
"login_successfully": "¡Sesión inciada con éxito!",
"logged_out_successfully": "Logeado Satisfactoriamente",
"mark_as_default": "Marcar como predeterminado"
},
@ -113,7 +113,7 @@
},
"chart_info": {
"total_sales": "Ventas",
"total_receipts": "Ingresos",
"total_receipts": "Recibos",
"total_expense": "Gastos",
"net_income": "Ingresos netos",
"year": "Seleccione año"
@ -1485,7 +1485,7 @@
"pdf_estimate_label": "Presupuestar",
"pdf_estimate_number": "Número de Presupuesto",
"pdf_estimate_date": "Fecha presupuesto",
"pdf_estimate_expire_date": "Fecha de caducidad",
"pdf_estimate_expire_date": "Fecha de vencimiento",
"pdf_invoice_label": "Factura",
"pdf_invoice_number": "Numero de factura",
"pdf_invoice_date": "Fecha de la factura",

View File

@ -1485,7 +1485,7 @@
"pdf_estimate_label": "Estimate",
"pdf_estimate_number": "Estimate Number",
"pdf_estimate_date": "Estimate Date",
"pdf_estimate_expire_date": "Expiry date",
"pdf_estimate_expire_date": "Expiry Date",
"pdf_invoice_label": "Invoice",
"pdf_invoice_number": "Invoice Number",
"pdf_invoice_date": "Invoice Date",

View File

@ -1485,7 +1485,7 @@
"pdf_estimate_label": "Tarjous",
"pdf_estimate_number": "Tarjousnumero",
"pdf_estimate_date": "Tarjouksen päiväys",
"pdf_estimate_expire_date": "Voimassaolo päivä",
"pdf_estimate_expire_date": "Expiry Date",
"pdf_invoice_label": "Lasku",
"pdf_invoice_number": "Laskunumero",
"pdf_invoice_date": "Laskun päiväys",

View File

@ -310,7 +310,7 @@
"confirm_mark_as_sent": "Ce devis sera marqué comme envoyé",
"confirm_mark_as_accepted": "Ce devis sera marqué comme accepté",
"confirm_mark_as_rejected": "Ce devis sera marqué comme rejeté",
"no_matching_estimates": "Aucune estimation correspondante !",
"no_matching_estimates": "Aucun devis correspondant !",
"mark_as_sent_successfully": "Devis marqué comme envoyé",
"send_estimate_successfully": "Devis envoyé",
"errors": {
@ -355,7 +355,7 @@
"select_an_item": "Sélectionnez un article",
"type_item_description": "Taper la description de l'article (facultatif)"
},
"mark_as_default_estimate_template_description": "If enabled, the selected template will be automatically selected for new estimates."
"mark_as_default_estimate_template_description": "Si activé, le modèle sélectionné sera automatiquement utilisé pour les nouvelles estimations."
},
"invoices": {
"title": "Factures",
@ -447,7 +447,7 @@
"marked_as_sent_message": "Facture supprimée | Factures supprimées",
"something_went_wrong": "quelque chose a mal tourné",
"invalid_due_amount_message": "Le paiement entré est supérieur au montant total dû pour cette facture. Veuillez vérifier et réessayer.",
"mark_as_default_invoice_template_description": "If enabled, the selected template will be automatically selected for new invoices."
"mark_as_default_invoice_template_description": "Si activé, le modèle sélectionné sera automatiquement utilisé pour les nouvelles factures."
},
"recurring_invoices": {
"title": "Factures récurrentes",
@ -526,7 +526,7 @@
"cloned_successfully": "Facture récurrente clonée",
"clone_invoice": "Dupliquer",
"confirm_clone": "Cette facture récurrente sera clonée dans une nouvelle facture récurrente",
"add_customer_email": "Please add an email address for this customer to send invoices automatically.",
"add_customer_email": "Veuillez ajouter une adresse e-mail pour ce client afin d'envoyer les factures automatiquement.",
"item": {
"title": "Nom",
"description": "Description",
@ -844,9 +844,9 @@
"secret": "Secret",
"mailgun_secret": "Secret Mailgun",
"mailgun_domain": "Domaine",
"mailgun_endpoint": "Mailgun Endpoint",
"ses_secret": "SES Secret",
"ses_key": "SES Key",
"mailgun_endpoint": "Endpoint de Mailgun",
"ses_secret": "Clé secrète SES",
"ses_key": "Clé SES",
"password": "Mot de passe",
"username": "Nom d'utilisateur",
"mail_config": "Envoi d'emails",
@ -1112,10 +1112,10 @@
"error": "Vous ne pouvez pas supprimer le fournisseur actif",
"default_currency_error": "Cette devise est déjà affectée à un fournisseur",
"exchange_help_text": "Veuillez entrer le taux de change pour convertir {currency} en {baseCurrency}",
"currency_freak": "Currency Freak",
"currency_freak": "Currency Freaks",
"currency_layer": "Currency Layer",
"open_exchange_rate": "Open Exchange Rate",
"currency_converter": "Currency Converter",
"open_exchange_rate": "Ouvrir le taux de change",
"currency_converter": "Convertisseur de devises",
"server": "Serveur",
"url": "URL",
"active": "Actif",
@ -1150,8 +1150,8 @@
"payment_mode_added": "Mode de paiement ajouté",
"payment_mode_updated": "Mode de paiement mis à jour",
"payment_mode_confirm_delete": "Vous ne pourrez pas récupérer ce mode de paiement",
"payments_attached": "This payment method is already attached to payments. Please delete the attached payments to proceed with deletion.",
"expenses_attached": "This payment method is already attached to expenses. Please delete the attached expenses to proceed with deletion.",
"payments_attached": "Ce moyen de paiement est déjà utilisé par des paiements. Merci de supprimer les paiements associés avant de procéder à la suppression.",
"expenses_attached": "Ce moyen de paiement est déjà utilisé par des dépenses. Merci de supprimer les dépenses associés avant de procéder à la suppression.",
"deleted_message": "Mode de paiement supprimé"
},
"expense_category": {
@ -1262,8 +1262,8 @@
"media_driver": "Stockage multimédia",
"media_root": "Répertoire média",
"aws_driver": "AWS",
"aws_key": "AWS Key",
"aws_secret": "AWS Secret",
"aws_key": "Clé AWS",
"aws_secret": "Clé secrète AWS",
"aws_region": "Région AWS",
"aws_bucket": "Bucket",
"aws_root": "Répertoire",
@ -1491,7 +1491,7 @@
"pdf_invoice_date": "Date",
"pdf_invoice_due_date": "Date déchéance",
"pdf_notes": "Notes de bas de page",
"pdf_items_label": "Articles",
"pdf_items_label": "Désignation",
"pdf_quantity_label": "Quantité",
"pdf_price_label": "Prix",
"pdf_discount_label": "Remise",

View File

@ -1485,7 +1485,7 @@
"pdf_estimate_label": "Estimate",
"pdf_estimate_number": "Estimate Number",
"pdf_estimate_date": "Estimate Date",
"pdf_estimate_expire_date": "Expiry date",
"pdf_estimate_expire_date": "Expiry Date",
"pdf_invoice_label": "Invoice",
"pdf_invoice_number": "Invoice Number",
"pdf_invoice_date": "Invoice Date",

View File

@ -4,7 +4,7 @@
"customers": "Klijenti",
"items": "Stavke",
"invoices": "Fakture",
"recurring-invoices": "Recurring Invoices",
"recurring-invoices": "Ponavljajuće fakture\n",
"expenses": "Rashodi",
"estimates": "Ponude",
"payments": "Uplate",
@ -12,7 +12,7 @@
"settings": "Postavke",
"logout": "Odjava",
"users": "Korisnici",
"modules": "Modules"
"modules": "Moduli"
},
"general": {
"add_company": "Dodaj tvrtku",
@ -30,8 +30,8 @@
"from": "Pošiljatelj",
"to": "Primatelj",
"ok": "Ok",
"yes": "Yes",
"no": "No",
"yes": "Da",
"no": "Ne",
"sort_by": "Posloži Po",
"ascending": "Rastuće",
"descending": "Padajuće",
@ -39,7 +39,7 @@
"body": "Tijelo",
"message": "Poruka",
"send": "Pošalji",
"preview": "Preview",
"preview": "Pregled",
"go_back": "Natrag",
"back_to_login": "Natrag na prijavu?",
"home": "Početna",
@ -65,7 +65,7 @@
"sent": "Poslano",
"all": "Sve",
"select_all": "Izaberi sve",
"select_template": "Select Template",
"select_template": "Odaberite predložak",
"choose_file": "Klikni ovdje da izabereš fajl",
"choose_template": "Izaberi predložak",
"choose": "Izaberi",
@ -93,13 +93,13 @@
"no_note_found": "Ne postoje spremljene napomene",
"insert_note": "Unesi bilješku",
"copied_pdf_url_clipboard": "Link do PDF fajla kopiran!",
"copied_url_clipboard": "Copied url to clipboard!",
"docs": "Docs",
"do_you_wish_to_continue": "Do you wish to continue?",
"note": "Note",
"pay_invoice": "Pay Invoice",
"login_successfully": "Logged in successfully!",
"logged_out_successfully": "Logged out successfully",
"copied_url_clipboard": "URL je kopiran u međuspremnik!",
"docs": "Dokumenti",
"do_you_wish_to_continue": "Želite li nastaviti?",
"note": "Bilješka",
"pay_invoice": "Plati račun",
"login_successfully": "Uspješno ste prijavljeni!\n",
"logged_out_successfully": "Uspješno odjavljen\n",
"mark_as_default": "Postavi kao zadano"
},
"dashboard": {
@ -109,7 +109,7 @@
"customers": "Klijenti",
"invoices": "Računi",
"estimates": "Ponude",
"payments": "Payments"
"payments": "Plaćanja"
},
"chart_info": {
"total_sales": "Prodaja",
@ -151,18 +151,18 @@
"no_results_found": "Nema rezultata"
},
"company_switcher": {
"label": "SWITCH COMPANY",
"no_results_found": "No Results Found",
"add_new_company": "Add new company",
"new_company": "New company",
"created_message": "Company created successfully"
"label": "IZABERI TVRTKU",
"no_results_found": "Nema rezultata\n",
"add_new_company": "Dodajte novu tvrtku\n",
"new_company": "Nova tvrtka\n",
"created_message": "Tvrtka uspješno stvorena\n"
},
"dateRange": {
"today": "Today",
"this_week": "This Week",
"this_month": "This Month",
"this_quarter": "This Quarter",
"this_year": "This Year",
"today": "Danas\n",
"this_week": "Danas\n",
"this_month": "Danas\n",
"this_quarter": "Danas\n",
"this_year": "Danas\n",
"previous_week": "Previous Week",
"previous_month": "Previous Month",
"previous_quarter": "Previous Quarter",
@ -456,32 +456,32 @@
"months": "{months} Month",
"years": "{years} Year",
"all": "All",
"paid": "Paid",
"unpaid": "Unpaid",
"viewed": "Viewed",
"overdue": "Overdue",
"active": "Active",
"completed": "Completed",
"customer": "CUSTOMER",
"paid_status": "PAID STATUS",
"ref_no": "REF NO.",
"number": "NUMBER",
"paid": "Plaćeno",
"unpaid": "Ne plaćeno",
"viewed": "Pregledano",
"overdue": "Kašnjenja",
"active": "Aktivno",
"completed": "Završeno",
"customer": "KUPAC",
"paid_status": "STATUS PLAĆANJA",
"ref_no": "BR. REFERENCE",
"number": "BROJ",
"amount_due": "AMOUNT DUE",
"partially_paid": "Partially Paid",
"total": "Total",
"discount": "Discount",
"sub_total": "Sub Total",
"invoice": "Recurring Invoice | Recurring Invoices",
"invoice_number": "Recurring Invoice Number",
"next_invoice_date": "Next Invoice Date",
"ref_number": "Ref Number",
"contact": "Contact",
"add_item": "Add an Item",
"date": "Date",
"limit_by": "Limit by",
"limit_date": "Limit Date",
"limit_count": "Limit Count",
"count": "Count",
"partially_paid": "Djelomično plaćeno\n",
"total": "Ukupno",
"discount": "Popust",
"sub_total": "Popdzbroj",
"invoice": "Ponavljajuća faktura | Ponavjaljuća faktura",
"invoice_number": "Broj ponavljajuće fakture\n",
"next_invoice_date": "Datum sljedećeg računa",
"ref_number": "Broj reference",
"contact": "Kontakt",
"add_item": "Dodaj stavku",
"date": "Datum",
"limit_by": "Ograniči po",
"limit_date": "Vremenski rok",
"limit_count": "Broj ograničenja\n",
"count": "Brojač",
"status": "Status",
"select_a_status": "Select a status",
"working": "Working",
@ -1485,7 +1485,7 @@
"pdf_estimate_label": "Ponuda",
"pdf_estimate_number": "Broj Ponude",
"pdf_estimate_date": "Datum Ponude",
"pdf_estimate_expire_date": "Datum isteka Ponude",
"pdf_estimate_expire_date": "Expiry Date",
"pdf_invoice_label": "Faktura",
"pdf_invoice_number": "Broj Fakture",
"pdf_invoice_date": "Datum Fakture",

File diff suppressed because it is too large Load Diff

View File

@ -1485,7 +1485,7 @@
"pdf_estimate_label": "Estimate",
"pdf_estimate_number": "Estimate Number",
"pdf_estimate_date": "Estimate Date",
"pdf_estimate_expire_date": "Expiry date",
"pdf_estimate_expire_date": "Expiry Date",
"pdf_invoice_label": "Invoice",
"pdf_invoice_number": "Invoice Number",
"pdf_invoice_date": "Invoice Date",

View File

@ -17,7 +17,6 @@ import sk from './sk.json'
import vi from './vi.json'
import el from './el.json'
import hr from './hr.json'
import th from './th.json'
export default {
cs,
@ -38,6 +37,5 @@ export default {
vi,
pl,
el,
hr,
th
hr
}

View File

@ -1485,7 +1485,7 @@
"pdf_estimate_label": "Pasiūlymas",
"pdf_estimate_number": "Pasiūlymo numeris",
"pdf_estimate_date": "Pasiūlymo data",
"pdf_estimate_expire_date": "Galiojimo laikas",
"pdf_estimate_expire_date": "Expiry Date",
"pdf_invoice_label": "Sąskaita",
"pdf_invoice_number": "Invoice Number",
"pdf_invoice_date": "Invoice Date",

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
"customers": "Klanten",
"items": "Artikelen",
"invoices": "Facturen",
"recurring-invoices": "Periodieke factuur",
"recurring-invoices": "Periodieke facturen",
"expenses": "Uitgaven",
"estimates": "Offertes",
"payments": "Betalingen",
@ -28,16 +28,16 @@
"from_date": "Vanaf datum",
"to_date": "T/m datum",
"from": "Vanaf",
"to": "Naar.",
"ok": "Oké.",
"yes": "Ja.",
"no": "Nee.",
"to": "Naar",
"ok": "Oké",
"yes": "Ja",
"no": "Nee",
"sort_by": "Sorteer op",
"ascending": "Oplopend",
"descending": "Aflopend",
"subject": "Onderwerp",
"body": "Inhoud",
"message": "Bericht.",
"message": "Bericht",
"send": "Verstuur",
"preview": "Voorbeeld",
"go_back": "Ga terug",
@ -54,7 +54,7 @@
"actions": "Acties",
"subtotal": "SUBTOTAAL",
"discount": "KORTING",
"fixed": "Gemaakt",
"fixed": "Vast bedrag",
"percentage": "Percentage",
"tax": "BELASTING",
"total_amount": "TOTAALBEDRAG",
@ -85,17 +85,17 @@
"select_state": "Selecteer staat",
"select_country": "Selecteer land",
"select_city": "Selecteer stad",
"street_1": "straat 1",
"street_2": "Straat # 2",
"action_failed": "Actie: mislukt",
"retry": "Retr",
"street_1": "Straat 1",
"street_2": "Straat 2",
"action_failed": "Actie mislukt",
"retry": "Opnieuw proberen",
"choose_note": "Kies notitie",
"no_note_found": "Geen notitie gevonden",
"insert_note": "Notitie invoegen",
"copied_pdf_url_clipboard": "PDF link naar klembord gekopieerd!",
"copied_url_clipboard": "URL naar klembord gekopieerd!",
"docs": "Documenten",
"do_you_wish_to_continue": "Wilt u Doorgaan?",
"docs": "Documentatie",
"do_you_wish_to_continue": "Wil je doorgaan?",
"note": "Notitie",
"pay_invoice": "Betaal factuur",
"login_successfully": "Succesvol ingelogd!",
@ -526,7 +526,7 @@
"cloned_successfully": "Terugkerende factuur succesvol gekopieerd",
"clone_invoice": "Kopieer periodieke factuur",
"confirm_clone": "Deze periodieke factuur wordt gekopieerd naar een nieuwe periodieke factuur",
"add_customer_email": "Voeg een e-mailadres aan deze klant toe, zodat facturen automatisch verzonden kunnen worden.",
"add_customer_email": "Voeg een e-mailadres aan deze klant toe zodat facturen automatisch verzonden kunnen worden.",
"item": {
"title": "Item titel",
"description": "Beschrijving",
@ -1114,13 +1114,13 @@
"exchange_help_text": "Voer de wisselkoers in om te converteren van {currency} naar {baseCurrency}",
"currency_freak": "Valuta Freak",
"currency_layer": "Valuta-laag",
"open_exchange_rate": "Open Exchange Rate",
"open_exchange_rate": "Open wisselkoers",
"currency_converter": "Valuta omzetter",
"server": "Server",
"url": "URL",
"active": "Actief",
"currency_help_text": "This provider will only be used on above selected currencies",
"currency_in_used": "The following currencies are already active on another provider. Please remove these currencies from selection to activate this provider again."
"currency_help_text": "Deze aanbieder wordt alleen gebruikt voor de hier boven geselecteerde valuta",
"currency_in_used": "De volgende valuta zijn al actief bij een andere aanbieder. Verwijder deze valuta uit de selectie om deze aanbieder opnieuw te activeren."
},
"tax_types": {
"title": "Belastingtypen",
@ -1143,16 +1143,16 @@
},
"payment_modes": {
"title": "Betaalmethodes",
"description": "Modes of transaction for payments",
"add_payment_mode": "Add Payment Mode",
"edit_payment_mode": "Edit Payment Mode",
"mode_name": "Mode Name",
"description": "Modi van transacties voor betalingen",
"add_payment_mode": "Voeg betaalwijze toe",
"edit_payment_mode": "Wijzig betaalwijze",
"mode_name": "Modusnaam",
"payment_mode_added": "Betaalwijze toegevoegd",
"payment_mode_updated": "Payment Mode Updated",
"payment_mode_confirm_delete": "You will not be able to recover this Payment Mode",
"payments_attached": "This payment method is already attached to payments. Please delete the attached payments to proceed with deletion.",
"expenses_attached": "This payment method is already attached to expenses. Please delete the attached expenses to proceed with deletion.",
"deleted_message": "Payment Mode deleted successfully"
"payment_mode_updated": "Betaalwijze bijgewerkt",
"payment_mode_confirm_delete": "U kunt deze betalingsmodus niet herstellen",
"payments_attached": "Deze betalingsmethode is al gekoppeld aan betalingen. Verwijder de gekoppelde betalingen om verder te gaan met het verwijderen.",
"expenses_attached": "Deze betaalmethode is al gekoppeld aan uitgaven. Verwijder de gekoppelde kosten om door te gaan met het verwijderen.",
"deleted_message": "Betaalwijze succesvol verwijderd"
},
"expense_category": {
"title": "Onkostencategorieën",
@ -1178,8 +1178,8 @@
"discount_setting": "Kortingsinstelling",
"discount_per_item": "Korting per item",
"discount_setting_description": "Schakel dit in als u korting wilt toevoegen aan afzonderlijke factuuritems. Standaard wordt korting rechtstreeks aan de factuur toegevoegd.",
"expire_public_links": "Automatically Expire Public Links",
"expire_setting_description": "Specify whether you would like to expire all the links sent by application to view invoices, estimates & payments, etc after a specified duration.",
"expire_public_links": "Publieke links automatisch laten vervallen",
"expire_setting_description": "Geef aan of je alle links die eerder zijn verstuurd door de applicatie om facturen, offertes en betalingen te bekijken wilt laten verlopen na een bepaalde duur.",
"save": "Opslaan",
"preference": "Voorkeur | Voorkeuren",
"general_settings": "Standaardvoorkeuren voor het systeem.",
@ -1188,9 +1188,9 @@
"select_time_zone": "Selecteer Tijdzone",
"select_date_format": "Selecteer datum/tijdindeling",
"select_financial_year": "Selecteer financieel ja",
"recurring_invoice_status": "Recurring Invoice Status",
"create_status": "Create Status",
"active": "Active",
"recurring_invoice_status": "Status periodieke facturen",
"create_status": "Status aanmaken",
"active": "Actief",
"on_hold": "In wacht",
"update_status": "Updatestatus",
"completed": "Voltooid",
@ -1217,10 +1217,10 @@
"finishing_update": "Afwerking Update",
"update_failed": "Update mislukt",
"update_failed_text": "Sorry! Je update is mislukt op: {step} step ",
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating."
"update_warning": "Alle applicatiebestanden en de standaard sjabloonbestanden worden overschreven wanneer u de applicatie met behulp van dit hulpprogramma bijwerkt. Maak een reservekopie van uw sjablonen en database voordat u deze bijwerkt."
},
"backup": {
"title": "Backup | Backups",
"title": "Back-up | Back-ups",
"description": "De back-up is een zipfile met alle bestanden in de mappen die je opgeeft samen met een dump van je database",
"new_backup": "Nieuwe back-up",
"create_backup": "Backup maken",

View File

@ -2,7 +2,7 @@
"navigation": {
"dashboard": "Pulpit",
"customers": "Kontrahenci",
"items": "Pozycje",
"items": "Produkty",
"invoices": "Faktury",
"recurring-invoices": "Faktury cykliczne",
"expenses": "Wydatki",
@ -100,7 +100,7 @@
"pay_invoice": "Zapłać Fakturę",
"login_successfully": "Zalogowano pomyślnie!",
"logged_out_successfully": "Wylogowano pomyślnie",
"mark_as_default": "Mark as default"
"mark_as_default": "Oznacz jako domyślne"
},
"dashboard": {
"select_year": "Wybierz rok",
@ -355,7 +355,7 @@
"select_an_item": "Wpisz lub kliknij aby wybrać element",
"type_item_description": "Opis pozycji (opcjonalnie)"
},
"mark_as_default_estimate_template_description": "If enabled, the selected template will be automatically selected for new estimates."
"mark_as_default_estimate_template_description": "Jeśli włączone, wybrany szablon zostanie automatycznie wybrany dla nowych ofert."
},
"invoices": {
"title": "Faktury",
@ -447,7 +447,7 @@
"marked_as_sent_message": "Faktura oznaczona jako wysłana pomyślnie",
"something_went_wrong": "coś poszło nie tak",
"invalid_due_amount_message": "Całkowita kwota faktury nie może być mniejsza niż całkowita kwota zapłacona za tę fakturę. Proszę zaktualizować fakturę lub usunąć powiązane płatności, aby kontynuować.",
"mark_as_default_invoice_template_description": "If enabled, the selected template will be automatically selected for new invoices."
"mark_as_default_invoice_template_description": "Jeśli włączone, wybrany szablon zostanie automatycznie wybrany dla nowych faktur."
},
"recurring_invoices": {
"title": "Faktury cykliczne",
@ -526,7 +526,7 @@
"cloned_successfully": "Faktura Cykliczna sklonowana pomyślnie",
"clone_invoice": "Klonuj Fakturę Cykliczną",
"confirm_clone": "Ta faktura cykliczna zostanie sklonowana do nowej faktury cyklicznej",
"add_customer_email": "Please add an email address for this customer to send invoices automatically.",
"add_customer_email": "Dodaj adres e-mail dla tego klienta, aby wysyłać faktury automatycznie.",
"item": {
"title": "Tytuł pozycji",
"description": "Opis",
@ -1485,7 +1485,7 @@
"pdf_estimate_label": "Oferta",
"pdf_estimate_number": "Numer oferty",
"pdf_estimate_date": "Data oferty",
"pdf_estimate_expire_date": "Termin ważności",
"pdf_estimate_expire_date": "Data ważności",
"pdf_invoice_label": "Faktura",
"pdf_invoice_number": "Numer faktury",
"pdf_invoice_date": "Data faktury",

View File

@ -12,7 +12,7 @@
"settings": "Configurações",
"logout": "Encerrar sessão",
"users": "Usuários",
"modules": "Navegação → módulos"
"modules": "Módulos"
},
"general": {
"add_company": "Adicionar Empresa",
@ -29,13 +29,13 @@
"to_date": "Até a Data",
"from": "De",
"to": "Para",
"ok": "Geral → Ok",
"ok": "Ok",
"yes": "Sim",
"no": "Não",
"sort_by": "Ordenar por",
"ascending": "Crescente",
"descending": "Descendente",
"subject": "Sujeita",
"subject": "Assunto",
"body": "Corpo",
"message": "Mensagem",
"send": "Enviar",
@ -210,8 +210,8 @@
"basic_info": "Informação Básica",
"portal_access": "Clientes → Acessar portal",
"portal_access_text": "Clientes→ Texto do portal de acesso?",
"portal_access_url": "Customer Portal Login URL",
"portal_access_url_help": "Please copy & forward the above given URL to your customer for providing access.",
"portal_access_url": "URL de login do Portal do Cliente",
"portal_access_url_help": "Por favor, copie a URL fornecida acima e envie a seu cliente para fornecer acesso.",
"billing_address": "Endereço de cobrança",
"shipping_address": "Endereço de entrega",
"copy_billing_address": "Copiar Endereço de Faturamento",
@ -231,7 +231,7 @@
"confirm_delete": "Você não poderá recuperar este cliente e todas as faturas, orçamentos 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",
"address_updated_message": "Address Information Updated succesfully",
"address_updated_message": "Informações de endereço atualizadas com sucesso",
"deleted_message": "Cliente excluído com sucesso | Clientes excluídos com sucesso",
"edit_currency_not_allowed": "Não é possível alterar a moeda depois de criar transações."
},
@ -265,8 +265,8 @@
},
"estimates": {
"title": "Orçamentos",
"accept_estimate": "Accept Estimate",
"reject_estimate": "Reject Estimate",
"accept_estimate": "Aceitar Orçamento",
"reject_estimate": "Rejeitar Orçamento",
"estimate": "Orçamento | Orçamentos",
"estimates_list": "Lista de orçamentos",
"days": "{days} Dias",
@ -318,10 +318,10 @@
},
"accepted": "Aceito",
"rejected": "Rejeitado",
"expired": "Expired",
"expired": "Expirado",
"sent": "Enviado",
"draft": "Rascunho",
"viewed": "Viewed",
"viewed": "Visualizado",
"declined": "Rejeitado",
"new_estimate": "Novo orçamento",
"add_new_estimate": "Adicionar novo orçamento",
@ -355,14 +355,14 @@
"select_an_item": "Escreva ou clique para selecionar um item",
"type_item_description": "Descrição do Item (opcional)"
},
"mark_as_default_estimate_template_description": "If enabled, the selected template will be automatically selected for new estimates."
"mark_as_default_estimate_template_description": "Se habilitado, o modelo selecionado será automaticamente selecionado para novas estimativas."
},
"invoices": {
"title": "Faturas",
"download": "Download",
"pay_invoice": "Pay Invoice",
"download": "Baixar",
"pay_invoice": "Pagar Fatura",
"invoices_list": "Lista de faturas",
"invoice_information": "Invoice Information",
"invoice_information": "Informações da Fatura",
"days": "{days} dias",
"months": "{months} Mês",
"years": "{years} Ano",
@ -374,7 +374,7 @@
"completed": "Concluído",
"customer": "CLIENTE",
"paid_status": "STATUS PAGAMENTO",
"ref_no": "REF NO.",
"ref_no": "N° de Referência",
"number": "NÚMERO",
"amount_due": "VALOR DEVIDO",
"partially_paid": "Parcialmente Pago",
@ -447,7 +447,7 @@
"marked_as_sent_message": "Fatura marcada como enviada com sucesso",
"something_went_wrong": "algo deu errado",
"invalid_due_amount_message": "O valor total da fatura não pode ser menor que o valor total pago para esta fatura. Atualize a fatura ou exclua os pagamentos associados para continuar.",
"mark_as_default_invoice_template_description": "If enabled, the selected template will be automatically selected for new invoices."
"mark_as_default_invoice_template_description": "Se habilitado, o modelo selecionado será automaticamente selecionado para novas estimativas."
},
"recurring_invoices": {
"title": "Faturas Recorrentes",
@ -464,56 +464,56 @@
"completed": "Concluído",
"customer": "CLIENTE",
"paid_status": "STATUS PAGAMENTO",
"ref_no": "REF NO.",
"number": "NUMBER",
"amount_due": "AMOUNT DUE",
"partially_paid": "Partially Paid",
"ref_no": "N° de Referência",
"number": "NÚMERO",
"amount_due": "VALOR DEVIDO",
"partially_paid": "Parcialmente Pago",
"total": "Total",
"discount": "Discount",
"sub_total": "Sub Total",
"invoice": "Recurring Invoice | Recurring Invoices",
"invoice_number": "Recurring Invoice Number",
"next_invoice_date": "Next Invoice Date",
"ref_number": "Ref Number",
"contact": "Contact",
"add_item": "Add an Item",
"date": "Date",
"limit_by": "Limit by",
"limit_date": "Limit Date",
"limit_count": "Limit Count",
"count": "Count",
"discount": "Desconto",
"sub_total": "Subtotal",
"invoice": "Fatura Recorrente | Faturas Recorrentes",
"invoice_number": "Número da Fatura Recorrente",
"next_invoice_date": "Data da Próxima Fatura",
"ref_number": "Número de Referência",
"contact": "Contato",
"add_item": "Adicionar um Item",
"date": "Data",
"limit_by": "Limitar por",
"limit_date": "Data Limite",
"limit_count": "Quantidade Máxima",
"count": "Quantidade",
"status": "Status",
"select_a_status": "Select a status",
"working": "Working",
"on_hold": "On Hold",
"complete": "Completed",
"add_tax": "Add Tax",
"amount": "Amount",
"action": "Action",
"notes": "Notes",
"view": "View",
"basic_info": "Basic Info",
"send_invoice": "Send Recurring Invoice",
"auto_send": "Auto Send",
"resend_invoice": "Resend Recurring Invoice",
"invoice_template": "Recurring Invoice Template",
"conversion_message": "Recurring Invoice cloned successful",
"template": "Template",
"mark_as_sent": "Mark as sent",
"confirm_send_invoice": "This recurring invoice will be sent via email to the customer",
"invoice_mark_as_sent": "This recurring invoice will be marked as sent",
"confirm_send": "This recurring invoice will be sent via email to the customer",
"starts_at": "Start Date",
"due_date": "Invoice Due Date",
"record_payment": "Record Payment",
"add_new_invoice": "Add New Recurring Invoice",
"update_expense": "Update Expense",
"edit_invoice": "Edit Recurring Invoice",
"new_invoice": "New Recurring Invoice",
"send_automatically": "Send Automatically",
"send_automatically_desc": "Enable this, if you would like to send the invoice automatically to the customer when its created.",
"save_invoice": "Save Recurring Invoice",
"update_invoice": "Update Recurring Invoice",
"select_a_status": "Selecione o Status",
"working": "Processando",
"on_hold": "Pausado",
"complete": "Concluído",
"add_tax": "Adicionar Imposto",
"amount": "Valor",
"action": "Ação",
"notes": "Observações",
"view": "Ver",
"basic_info": "Informações Básicas",
"send_invoice": "Enviar Fatura Recorrente",
"auto_send": "Envio Automático",
"resend_invoice": "Reenviar Fatura Recorrente",
"invoice_template": "Modelo de Fatura Recorrente",
"conversion_message": "Fatura Recorrente clonada com sucesso",
"template": "Modelo",
"mark_as_sent": "Marcar como enviado",
"confirm_send_invoice": "Esta fatura recorrente será enviada por e-mail para o cliente",
"invoice_mark_as_sent": "Esta fatura recorrente será marcada como enviada",
"confirm_send": "Esta fatura recorrente será enviada por e-mail para o cliente",
"starts_at": "Data de início",
"due_date": "Vencimento da Fatura",
"record_payment": "Registrar Pagamento",
"add_new_invoice": "Adicionar nova fatura recorrente",
"update_expense": "Atualizar Despesa",
"edit_invoice": "Editar fatura recorrente",
"new_invoice": "Nova fatura recorrente",
"send_automatically": "Enviar automaticamente",
"send_automatically_desc": "Habilite isso, se você gostaria de enviar a fatura automaticamente para o cliente.",
"save_invoice": "Salvar fatura recorrente",
"update_invoice": "Atualizar fatura recorrente",
"add_new_tax": "Adicionar Novo Imposto",
"no_invoices": "Não há faturas recorrentes ainda!",
"mark_as_rejected": "Marcar como rejeitada",
@ -522,42 +522,42 @@
"select_invoice": "Selecionar Fatura",
"no_matching_invoices": "Não há faturas recorrentes correspondentes!",
"mark_as_sent_successfully": "Fatura recorrente marcada como enviada com sucesso",
"invoice_sent_successfully": "Recurring Invoice sent successfully",
"cloned_successfully": "Recurring Invoice cloned successfully",
"clone_invoice": "Clone Recurring Invoice",
"confirm_clone": "This recurring invoice will be cloned into a new Recurring Invoice",
"add_customer_email": "Please add an email address for this customer to send invoices automatically.",
"invoice_sent_successfully": "Fatura recorrente enviada com sucesso",
"cloned_successfully": "Fatura recorrente copiada com sucesso",
"clone_invoice": "Copiar Fatura Recorrente",
"confirm_clone": "Esta fatura recorrente será copiada em uma nova fatura recorrente",
"add_customer_email": "Por favor, adicione um endereço de e-mail para este cliente para enviar faturas automaticamente.",
"item": {
"title": "Item Title",
"description": "Description",
"quantity": "Quantity",
"price": "Price",
"discount": "Discount",
"title": "Titulo do item",
"description": "Descrição",
"quantity": "Quantidade",
"price": "Preço",
"discount": "Desconto",
"total": "Total",
"total_discount": "Total Discount",
"sub_total": "Sub Total",
"tax": "Tax",
"amount": "Amount",
"select_an_item": "Type or click to select an item",
"type_item_description": "Type Item Description (optional)"
"total_discount": "Desconto total",
"sub_total": "Subtotal",
"tax": "Imposto",
"amount": "Valor",
"select_an_item": "Digite ou clique para selecionar",
"type_item_description": "Descrição do Item (opcional)"
},
"frequency": {
"title": "Frequency",
"select_frequency": "Select Frequency",
"minute": "Minute",
"hour": "Hour",
"day_month": "Day of month",
"month": "Month",
"day_week": "Day of week"
"title": "Frequência",
"select_frequency": "Selecione a Frequência",
"minute": "Minuto",
"hour": "Hora",
"day_month": "Dia do mês",
"month": "Mês",
"day_week": "Dia da semana"
},
"confirm_delete": "You will not be able to recover this Invoice | You will not be able to recover these Invoices",
"created_message": "Recurring Invoice created successfully",
"updated_message": "Recurring Invoice updated successfully",
"deleted_message": "Recurring Invoice deleted successfully | Recurring Invoices deleted successfully",
"marked_as_sent_message": "Recurring Invoice marked as sent successfully",
"user_email_does_not_exist": "User email does not exist",
"something_went_wrong": "something went wrong",
"invalid_due_amount_message": "Total Recurring Invoice amount cannot be less than total paid amount for this Recurring Invoice. Please update the invoice or delete the associated payments to continue."
"confirm_delete": "Você não poderá recuperar esta fatura | Você não poderá recuperar essas faturas",
"created_message": "Fatura recorrente criada com sucesso",
"updated_message": "Fatura recorrente atualizada com sucesso",
"deleted_message": "Fatura recorrente excluída com sucesso | Faturas recorrentes excluídas com sucesso",
"marked_as_sent_message": "Fatura recorrente marcada como enviada com sucesso",
"user_email_does_not_exist": "E-mail de usuário não existe",
"something_went_wrong": "houve algo de errado",
"invalid_due_amount_message": "O valor total da fatura não pode ser menor que o valor total pago para esta fatura. Atualize a fatura ou exclua os pagamentos associados para continuar."
},
"payments": {
"title": "Pagamentos",
@ -603,7 +603,7 @@
"select_a_customer": "Selecione um cliente",
"expense_title": "Título",
"customer": "Cliente",
"currency": "Currency",
"currency": "Moeda",
"contact": "Contato",
"category": "Categoria",
"from_date": "A partir da Data",
@ -658,49 +658,49 @@
"retype_password": "Confirme a Senha"
},
"modules": {
"buy_now": "Buy Now",
"install": "Install",
"price": "Price",
"download_zip_file": "Download ZIP file",
"unzipping_package": "Unzipping Package",
"copying_files": "Copying Files",
"deleting_files": "Deleting Unused files",
"completing_installation": "Completing Installation",
"update_failed": "Update Failed",
"install_success": "Module has been installed successfully!",
"customer_reviews": "Reviews",
"license": "License",
"buy_now": "Compre agora",
"install": "Instalar",
"price": "Preço",
"download_zip_file": "Baixar arquivo ZIP",
"unzipping_package": "Descompactando pacote",
"copying_files": "Copiando arquivos",
"deleting_files": "Excluindo arquivos não utilizados",
"completing_installation": "Completando instalação",
"update_failed": "Atualização falhou",
"install_success": "Módulo foi instalado com sucesso!",
"customer_reviews": "Avaliações",
"license": "Licença",
"faq": "FAQ",
"monthly": "Monthly",
"yearly": "Yearly",
"updated": "Updated",
"version": "Version",
"disable": "Disable",
"module_disabled": "Module Disabled",
"enable": "Enable",
"module_enabled": "Module Enabled",
"update_to": "Update To",
"module_updated": "Module Updated Successfully!",
"title": "Modules",
"module": "Module | Modules",
"api_token": "API token",
"invalid_api_token": "Invalid API Token.",
"other_modules": "Other Modules",
"view_all": "View All",
"no_reviews_found": "There are no reviews for this module yet!",
"module_not_purchased": "Module Not Purchased",
"module_not_found": "Module Not Found",
"monthly": "Mensalmente",
"yearly": "Anual",
"updated": "Atualizado",
"version": "Versão",
"disable": "Desabilitar",
"module_disabled": "Módulo Desabilitado",
"enable": "Habilitar",
"module_enabled": "Módulo Habilitado",
"update_to": "Atualizar Para",
"module_updated": "Módulo atualizado com sucesso!",
"title": "Módulos",
"module": "Módulo | Módulos",
"api_token": "Token de API",
"invalid_api_token": "Token da API inválido.",
"other_modules": "Outros Módulos",
"view_all": "Ver todos",
"no_reviews_found": "Não há avaliações para este módulo ainda!",
"module_not_purchased": "Módulo não comprado",
"module_not_found": "Módulo não encontrado",
"version_not_supported": "This module version doesn't support the current version of Crater",
"last_updated": "Last Updated On",
"connect_installation": "Connect your installation",
"api_token_description": "Login to {url} and connect this installation by entering the API Token. Your purchased modules will show up here after the connection is established.",
"view_module": "View Module",
"update_available": "Update Available",
"purchased": "Purchased",
"installed": "Installed",
"no_modules_installed": "No Modules Installed Yet!",
"disable_warning": "All the settings for this particular will be reverted.",
"what_you_get": "What you get"
"last_updated": "Última atualização em",
"connect_installation": "Conecte sua instalação",
"api_token_description": "Faça login em {url} e conecte esta instalação digitando o Token da API. Os módulos comprados aparecerão aqui após a conexão ser estabelecida.",
"view_module": "Ver Módulo",
"update_available": "Atualização disponível",
"purchased": "Comprado",
"installed": "Instalado",
"no_modules_installed": "Nenhum módulo instalado ainda!",
"disable_warning": "Todas as configurações serão revertidas.",
"what_you_get": "O que você recebe?"
},
"users": {
"title": "Usuários",
@ -727,8 +727,8 @@
"created_message": "Usuário criado com sucesso",
"updated_message": "Usuário atualizado com sucesso",
"deleted_message": "Usuário excluído com sucesso | Usuários excluídos com sucesso",
"select_company_role": "Select Role for {company}",
"companies": "Companies"
"select_company_role": "Selecione o cargo da {company}",
"companies": "Empresas"
},
"reports": {
"title": "Relatório",
@ -801,16 +801,16 @@
"tax_types": "Tipos de Impostos",
"expense_category": "Categorias de Despesas",
"update_app": "Atualizar Aplicativo",
"backup": "Backup",
"backup": "Cópia de Segurança",
"file_disk": "Disco de Arquivos",
"custom_fields": "Os campos personalizados",
"payment_modes": "Meios de Pagamento",
"notes": "Observações",
"exchange_rate": "Exchange Rate",
"address_information": "Address Information"
"exchange_rate": "Taxa de Câmbio",
"address_information": "Informações de Endereço"
},
"address_information": {
"section_description": " You can update Your Address information using form below."
"section_description": " Você pode atualizar suas informações de endereço usando o formulário abaixo."
},
"title": "Configurações",
"setting": "Configuração | Configurações",
@ -872,13 +872,13 @@
"address": "Endereço",
"zip": "CEP",
"save": "Salvar",
"delete": "Delete",
"delete": "Excluir",
"updated_message": "Informações da Empresa atualizadas com sucesso",
"delete_company": "Delete Company",
"delete_company_description": "Once you delete your company, you will lose all the data and files associated with it permanently.",
"are_you_absolutely_sure": "Are you absolutely sure?",
"delete_company_modal_desc": "This action cannot be undone. This will permanently delete {company} and all of its associated data.",
"delete_company_modal_label": "Please type {company} to confirm"
"delete_company": "Excluir Empresa",
"delete_company_description": "Depois de excluir sua empresa, você perderá todos os dados e arquivos associados a ela permanentemente.",
"are_you_absolutely_sure": "Você tem certeza?",
"delete_company_modal_desc": "Esta ação não pode ser desfeita. Isto irá apagar permanentemente a {company} e todos os dados associados.",
"delete_company_modal_label": "Digite {company} para confirmar"
},
"custom_fields": {
"title": "Os campos personalizados",
@ -916,103 +916,103 @@
"ticked_by_default": "Marcado por padrão",
"updated_message": "Campo personalizado atualizado com sucesso",
"added_message": "Campo personalizado adicionado com sucesso",
"press_enter_to_add": "Press enter to add new option",
"model_in_use": "Cannot update model for fields which are already in use.",
"type_in_use": "Cannot update type for fields which are already in use."
"press_enter_to_add": "Aperte enter para adicionar uma nova opção",
"model_in_use": "Não é possível atualizar o modelo para campos que já estão em uso.",
"type_in_use": "Não é possível atualizar o tipo para os campos que já estão em uso."
},
"customization": {
"customization": "personalização",
"updated_message": "Informações da Empresa atualizadas com sucesso",
"save": "Salvar",
"insert_fields": "Insert Fields",
"learn_custom_format": "Learn how to use custom format",
"add_new_component": "Add New Component",
"component": "Component",
"Parameter": "Parameter",
"series": "Series",
"series_description": "To set a static prefix/postfix like 'INV' across your company. It supports character length of up to 6 chars.",
"series_param_label": "Series Value",
"delimiter": "Delimiter",
"delimiter_description": "Single character for specifying the boundary between 2 separate components. By default its set to -",
"delimiter_param_label": "Delimiter Value",
"date_format": "Date Format",
"date_format_description": "A local date and time field which accepts a format parameter. The default format: 'Y' renders the current year.",
"date_format_param_label": "Format",
"sequence": "Sequence",
"sequence_description": "Consecutive sequence of numbers across your company. You can specify the length on the given parameter.",
"sequence_param_label": "Sequence Length",
"customer_series": "Customer Series",
"customer_series_description": "To set a different prefix/postfix for each customer.",
"customer_sequence": "Customer Sequence",
"customer_sequence_description": "Consecutive sequence of numbers for each of your customer.",
"customer_sequence_param_label": "Sequence Length",
"random_sequence": "Random Sequence",
"random_sequence_description": "Random alphanumeric string. You can specify the length on the given parameter.",
"random_sequence_param_label": "Sequence Length",
"insert_fields": "Inserir Campos",
"learn_custom_format": "Aprenda a usar o formato personalizado",
"add_new_component": "Novo Componente",
"component": "Componente",
"Parameter": "Parâmetro",
"series": "Séries",
"series_description": "Para definir um prefixo/sufixo estático como 'INV' em sua empresa. Ele suporta o comprimento do caractere de até 6 caracteres.",
"series_param_label": "Valor da Série",
"delimiter": "Delimitador",
"delimiter_description": "Caractere único para especificar o limite entre 2 componentes separados. Por padrão é -",
"delimiter_param_label": "Valor Delimitador",
"date_format": "Formato de Data",
"date_format_description": "Um campo de data e hora local que aceita um parâmetro de formato. O formato padrão: 'Y' apresenta o ano atual.",
"date_format_param_label": "Formato",
"sequence": "Sequência",
"sequence_description": "Sequência consecutiva de números em sua empresa. Você pode especificar o comprimento nos parâmetros indicados.",
"sequence_param_label": "Comprimento da sequência",
"customer_series": "Série do Cliente",
"customer_series_description": "Para definir um prefixo/sufixo diferente para cada cliente.",
"customer_sequence": "Sequência do Cliente",
"customer_sequence_description": "Sequência consecutiva de números para cada um de seus clientes.",
"customer_sequence_param_label": "Comprimento da Sequência",
"random_sequence": "Sequência aleatória",
"random_sequence_description": "Cadeia alfanumérica aleatória. Você pode especificar o comprimento no parâmetro fornecido.",
"random_sequence_param_label": "Comprimento da Sequência",
"invoices": {
"title": "Faturas",
"invoice_number_format": "Invoice Number Format",
"invoice_number_format_description": "Customize how your invoice number gets generated automatically when you create a new invoice.",
"preview_invoice_number": "Preview Invoice Number",
"due_date": "Due Date",
"due_date_description": "Specify how due date is automatically set when you create an invoice.",
"due_date_days": "Invoice Due after days",
"set_due_date_automatically": "Set Due Date Automatically",
"set_due_date_automatically_description": "Enable this if you wish to set due date automatically when you create a new invoice.",
"default_formats": "Default Formats",
"default_formats_description": "Below given formats are used to fill up the fields automatically on invoice creation.",
"invoice_number_format": "Formato do Número da Fatura",
"invoice_number_format_description": "Personalize como o número da sua fatura é gerado automaticamente quando você cria uma nova fatura.",
"preview_invoice_number": "Pré-visualizar número da fatura",
"due_date": "Vencimento",
"due_date_description": "Especifique como a data de vencimento é definida automaticamente ao criar uma fatura.",
"due_date_days": "Número de dias antes do vencimento da fatura",
"set_due_date_automatically": "Definir Data de Vencimento Automaticamente",
"set_due_date_automatically_description": "Habilite isso se deseja definir a data de vencimento automaticamente ao criar uma fatura.",
"default_formats": "Formatos Padrão",
"default_formats_description": "Os formatos indicados abaixo são usados para preencher os campos automaticamente na criação da fatura.",
"default_invoice_email_body": "Corpo Padrão de Email de Fatura",
"company_address_format": "Formato de Endereço de Empresa",
"shipping_address_format": "Formato de Endereço de Envio",
"billing_address_format": "Formato de Endereço de Faturamento",
"invoice_email_attachment": "Enviar faturas como anexos",
"invoice_email_attachment_setting_description": "Ative esta opção se quiser anexar faturas no e-mail. Lembrando que quando habilitado, o botão 'Ver fatura' nos e-mails não será mais exibido.",
"invoice_settings_updated": "Invoice Settings updated successfully",
"retrospective_edits": "Retrospective Edits",
"allow": "Allow",
"disable_on_invoice_partial_paid": "Disable after partial payment is recorded",
"disable_on_invoice_paid": "Disable after full payment is recorded",
"disable_on_invoice_sent": "Disable after invoice is sent",
"retrospective_edits_description": " Based on your country's laws or your preference, you can restrict users from editing finalised invoices."
"invoice_settings_updated": "Configurações da fatura atualizadas com sucesso",
"retrospective_edits": "Edições Retrospectivas",
"allow": "Permitir",
"disable_on_invoice_partial_paid": "Desativar após registrar um pagamento parcial",
"disable_on_invoice_paid": "Desativar após registrar um pagamento completo",
"disable_on_invoice_sent": "Desativar após o envio da fatura",
"retrospective_edits_description": " Com base nas leis do seu país ou na sua preferência, é possível restringir os usuários de editar faturas finalizadas."
},
"estimates": {
"title": "Orçamentos",
"estimate_number_format": "Estimate Number Format",
"estimate_number_format_description": "Customize how your estimate number gets generated automatically when you create a new estimate.",
"preview_estimate_number": "Preview Estimate Number",
"expiry_date": "Expiry Date",
"expiry_date_description": "Specify how expiry date is automatically set when you create an estimate.",
"expiry_date_days": "Estimate Expires after days",
"set_expiry_date_automatically": "Set Expiry Date Automatically",
"set_expiry_date_automatically_description": "Enable this if you wish to set expiry date automatically when you create a new estimate.",
"default_formats": "Default Formats",
"default_formats_description": "Below given formats are used to fill up the fields automatically on estimate creation.",
"estimate_number_format": "Formato do Número de Orçamento",
"estimate_number_format_description": "Personalize como seu número de orçamento é gerado automaticamente quando você cria um orçamento.",
"preview_estimate_number": "Pré-visualizar Número de Orçamento",
"expiry_date": "Vencimento",
"expiry_date_description": "Especifique como a data de vencimento é definida automaticamente quando você cria um orçamento.",
"expiry_date_days": "Orçamento expira após dias",
"set_expiry_date_automatically": "Definir Data de Vencimento Automaticamente",
"set_expiry_date_automatically_description": "Habilite isso se desejar definir a data de vencimento automaticamente ao criar um orçamento.",
"default_formats": "Formatos Padrão",
"default_formats_description": "Os formatos indicados abaixo são usados para preencher os campos automaticamente na criação do orçamento.",
"default_estimate_email_body": "Corpo Padrão de Email de Orçamento",
"company_address_format": "Formato de Endereço de Empresa",
"shipping_address_format": "Formato de Endereço de Envio",
"billing_address_format": "Formato de Endereço de Faturamento",
"estimate_email_attachment": "Enviar orçamentos como anexos",
"estimate_email_attachment_setting_description": "Ative esta opção se quiser anexar orçamentos no e-mail. Lembrando que quando habilitado, o botão 'Ver orçamento' nos e-mails não será mais exibido.",
"estimate_settings_updated": "Estimate Settings updated successfully",
"convert_estimate_options": "Estimate Convert Action",
"convert_estimate_description": "Specify what happens to the estimate after it gets converted to an invoice.",
"no_action": "No action",
"delete_estimate": "Delete estimate",
"mark_estimate_as_accepted": "Mark estimate as accepted"
"estimate_settings_updated": "Configurações de orçamento atualizadas com sucesso",
"convert_estimate_options": "Ação de Conversão de Orçamento",
"convert_estimate_description": "Especifique o que acontece com o orçamento depois que ele é convertido em uma fatura.",
"no_action": "Nenhuma ação",
"delete_estimate": "Excluir orçamento",
"mark_estimate_as_accepted": "Marcar orçamento como aceito"
},
"payments": {
"title": "Pagamentos",
"payment_number_format": "Payment Number Format",
"payment_number_format_description": "Customize how your payment number gets generated automatically when you create a new payment.",
"preview_payment_number": "Preview Payment Number",
"default_formats": "Default Formats",
"default_formats_description": "Below given formats are used to fill up the fields automatically on payment creation.",
"payment_number_format": "Formato do Número de Pagamento",
"payment_number_format_description": "Personalize como seu número de pagamento é gerado automaticamente quando você cria um pagamento.",
"preview_payment_number": "Visualizar Número de Pagamento",
"default_formats": "Formato padrão",
"default_formats_description": "Os formatos abaixo são usados para preencher os campos automaticamente na criação de pagamentos.",
"default_payment_email_body": "Corpo Padrão de Email de Pagamento",
"company_address_format": "Formato de Endereço de Empresa",
"from_customer_address_format": "Formato de Endereço de Cliente Remetente",
"payment_email_attachment": "Enviar pagamentos como anexos",
"payment_email_attachment_setting_description": "Ative esta opção se quiser enviar em anexo os recibos de pagamento no e-mail. Lembrando que quando habilitado, o botão 'Ver Pagamento' nos e-mails não será mais exibido.",
"payment_settings_updated": "Payment Settings updated successfully"
"payment_settings_updated": "Configurações de Pagamento atualizada com sucesso"
},
"items": {
"title": "Itens",
@ -1072,55 +1072,55 @@
"please_enter_email": "Por favor digite um E-mail"
},
"roles": {
"title": "Roles",
"description": "Manage the roles & permissions of this company",
"save": "Save",
"add_new_role": "Add New Role",
"role_name": "Role Name",
"added_on": "Added on",
"add_role": "Add Role",
"edit_role": "Edit Role",
"name": "Name",
"permission": "Permission | Permissions",
"select_all": "Select All",
"none": "None",
"confirm_delete": "You will not be able to recover this Role",
"created_message": "Role created successfully",
"updated_message": "Role updated successfully",
"deleted_message": "Role deleted successfully",
"already_in_use": "Role is already in use"
"title": "Nível de Acesso",
"description": "Gerenciar os cargos e permissões desta empresa",
"save": "Salvar",
"add_new_role": "Criar Nível de Acesso",
"role_name": "Nome",
"added_on": "Adicionado em",
"add_role": "Adicionar função",
"edit_role": "Editar Função",
"name": "Nome",
"permission": "Permissão | Permissões",
"select_all": "Selecionar tudo",
"none": "Nenhum",
"confirm_delete": "Você não poderá recuperar este Cargo",
"created_message": "Cargo criado com sucesso",
"updated_message": "Cargo atualizado com sucesso",
"deleted_message": "Cargo deletado com sucesso",
"already_in_use": "Cargo já em uso"
},
"exchange_rate": {
"exchange_rate": "Exchange Rate",
"title": "Fix Currency Exchange issues",
"description": "Please enter exchange rate of all the currencies mentioned below to help Crater properly calculate the amounts in {currency}.",
"exchange_rate": "Taxa de Câmbio",
"title": "Corrigir problemas do câmbio",
"description": "Por favor, indique a taxa de câmbio de todas as moedas mencionadas abaixo para ajudar o Crater a calcular corretamente as quantidades em {currency}.",
"drivers": "Drivers",
"new_driver": "Add New Provider",
"edit_driver": "Edit Provider",
"new_driver": "Adicionar Fornecedor",
"edit_driver": "Editar fornecedor",
"select_driver": "Select Driver",
"update": "select exchange rate ",
"providers_description": "Configure your exchange rate providers here to automatically fetch the latest exchange rate on transactions.",
"key": "API Key",
"name": "Name",
"update": "selecione a taxa de câmbio ",
"providers_description": "Configure aqui a taxa de câmbio de seus fornecedores para buscar automaticamente a taxa de câmbio mais recente nas transações.",
"key": "Chave da API",
"name": "Nome",
"driver": "Driver",
"is_default": "IS DEFAULT",
"currency": "Currencies",
"is_default": "É PADRÃO",
"currency": "Moedas",
"exchange_rate_confirm_delete": "You will not be able to recover this driver",
"created_message": "Provider Created successfully",
"updated_message": "Provider Updated Successfully",
"deleted_message": "Provider Deleted Successfully",
"created_message": "Fornecedor criado com sucesso",
"updated_message": "Fornecedor Atualizado com Sucesso",
"deleted_message": "Fornecedor Excluído com Sucesso",
"error": " You cannot Delete Active Driver",
"default_currency_error": "This currency is already used in one of the Active Provider",
"exchange_help_text": "Enter exchange rate to convert from {currency} to {baseCurrency}",
"default_currency_error": "Esta moeda já é usada em um dos fornecedores ativos",
"exchange_help_text": "Digite a taxa de câmbio para converter de {currency} para {baseCurrency}",
"currency_freak": "Currency Freak",
"currency_layer": "Currency Layer",
"open_exchange_rate": "Open Exchange Rate",
"currency_converter": "Currency Converter",
"server": "Server",
"open_exchange_rate": "Abrir Taxa de Câmbio",
"currency_converter": "Conversor de moeda",
"server": "Servidor",
"url": "URL",
"active": "Active",
"currency_help_text": "This provider will only be used on above selected currencies",
"currency_in_used": "The following currencies are already active on another provider. Please remove these currencies from selection to activate this provider again."
"active": "Ativo",
"currency_help_text": "Este fornecedor será usado somente nas moedas selecionadas acima",
"currency_in_used": "As seguintes moedas já estão ativas em outro fornecedor. Remova essas moedas da seleção para ativar este fornecedor novamente."
},
"tax_types": {
"title": "Tipos de Impostos",
@ -1142,17 +1142,17 @@
"already_in_use": "O Imposto já está em uso"
},
"payment_modes": {
"title": "Payment Modes",
"description": "Modes of transaction for payments",
"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",
"payments_attached": "This payment method is already attached to payments. Please delete the attached payments to proceed with deletion.",
"expenses_attached": "This payment method is already attached to expenses. Please delete the attached expenses to proceed with deletion.",
"deleted_message": "Payment Mode deleted successfully"
"title": "Forma de Pagamento",
"description": "Modos de transação para pagamentos",
"add_payment_mode": "Adicionar Forma de Pagamento",
"edit_payment_mode": "Editar Forma de Pagamento",
"mode_name": "Nome da Forma de Pagamento",
"payment_mode_added": "Forma de Pagamento Adicionada",
"payment_mode_updated": "Forma de Pagamento Atualizada",
"payment_mode_confirm_delete": "Você não poderá recuperar esta Forma de Pagamento",
"payments_attached": "Este método de pagamento já está anexado aos pagamentos. Por favor, exclua os pagamentos anexados para prosseguir com a exclusão.",
"expenses_attached": "Este método de pagamento já está anexado às despesas. Por favor, apague as despesas anexadas para prosseguir com a exclusão.",
"deleted_message": "Forma de Pagamento excluída com sucesso"
},
"expense_category": {
"title": "Categoria de Despesa",
@ -1178,8 +1178,8 @@
"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.",
"expire_public_links": "Automatically Expire Public Links",
"expire_setting_description": "Specify whether you would like to expire all the links sent by application to view invoices, estimates & payments, etc after a specified duration.",
"expire_public_links": "Expirar Links Públicos Automaticamente",
"expire_setting_description": "Especifique se deseja expirar todos os links enviados pelo aplicativo para visualizar faturas, orçamentos, pagamentos e etc., após um período especificado.",
"save": "Salvar",
"preference": "Preferência | Preferências",
"general_settings": "Preferências padrão para o sistema.",
@ -1188,13 +1188,13 @@
"select_time_zone": "Selecione um fuso horário",
"select_date_format": "Selecionar um Formato de Data",
"select_financial_year": "Selecione o ano financeiro",
"recurring_invoice_status": "Recurring Invoice Status",
"create_status": "Create Status",
"active": "Active",
"on_hold": "On Hold",
"update_status": "Update Status",
"completed": "Completed",
"company_currency_unchangeable": "Company currency cannot be changed"
"recurring_invoice_status": "Status da fatura recorrente",
"create_status": "Criar Status",
"active": "Ativo",
"on_hold": "Em espera",
"update_status": "Atualizar Status",
"completed": "Concluído",
"company_currency_unchangeable": "Moeda da empresa não pode ser alterada"
},
"update_app": {
"title": "Atualizar Aplicativo",
@ -1217,10 +1217,10 @@
"finishing_update": "Acabando a Atualização",
"update_failed": "Atualização falhou",
"update_failed_text": "Desculpa! Sua atualização falhou no passo: {step}",
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating."
"update_warning": "Todos os arquivos de aplicativo e arquivos de modelo padrão serão substituídos quando você atualizar o aplicativo usando este utilitário. Faça um backup de seus templates e banco de dados antes de atualizar."
},
"backup": {
"title": "Backup | Backups",
"title": "Cópia de segurança | Cópias de segurança",
"description": "O backup é um arquivo zip que contém todos os arquivos nas pastas que você especificou juntamente com um arquivo de backup de sua base de dados",
"new_backup": "Adicionar Novo Backup",
"create_backup": "Criar Backup",
@ -1248,7 +1248,7 @@
"created_at": "criado em",
"dropbox": "dropbox",
"name": "Nome",
"driver": "Driver",
"driver": "Motorista",
"disk_type": "Tipo",
"disk_name": "Nome do disco",
"new_disk": "Adicionar novo disco",
@ -1301,16 +1301,16 @@
"invalid_disk_credentials": "Credencial inválida para o disco selecionado"
},
"taxations": {
"add_billing_address": "Enter Billing Address",
"add_shipping_address": "Enter Shipping Address",
"add_company_address": "Enter Company Address",
"modal_description": "The information below is required in order to fetch sales tax.",
"add_address": "Add Address for fetching sales tax.",
"address_placeholder": "Example: 123, My Street",
"city_placeholder": "Example: Los Angeles",
"state_placeholder": "Example: CA",
"zip_placeholder": "Example: 90024",
"invalid_address": "Please provide valid address details."
"add_billing_address": "Endereço de Cobrança do Cliente",
"add_shipping_address": "Endereço de Entrega do Cliente",
"add_company_address": "Insira o Endereço da Empresa",
"modal_description": "As informações abaixo são necessárias para obter o imposto sobre vendas.",
"add_address": "Adicionar endereço para buscar o imposto sobre vendas.",
"address_placeholder": "Exemplo: 123, Minha Rua",
"city_placeholder": "Exemplo: Los Angeles",
"state_placeholder": "Exemplo: CA",
"zip_placeholder": "Exemplo: 90024",
"invalid_address": "Forneça detalhes do endereço válido."
}
},
"wizard": {
@ -1328,7 +1328,7 @@
"logo_preview": "Pré-visualizar Logotipo",
"preferences": "Preferências",
"preferences_desc": "Preferências padrão para o sistema.",
"currency_set_alert": "The company's currency cannot be changed later.",
"currency_set_alert": "A moeda da empresa não pode ser alterada mais tarde.",
"country": "País",
"state": "Estado",
"city": "Cidade",
@ -1372,7 +1372,7 @@
"app_domain": "Domínio do Aplicativo",
"verify_now": "Verificar Agora",
"success": "Domínio Verificado com Sucesso.",
"failed": "Domain verification failed. Please enter valid domain name.",
"failed": "Falha na verificação de domínio. Digite um nome de domínio válido.",
"verify_and_continue": "Verificar e Continuar"
},
"mail": {
@ -1425,7 +1425,7 @@
"not_yet": "Ainda não? Envie novamente",
"password_min_length": "A senha deve ter {count} caracteres",
"name_min_length": "O nome deve ter pelo menos {count} letras.",
"prefix_min_length": "Prefix must have at least {count} letters.",
"prefix_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.",
@ -1440,7 +1440,7 @@
"price_minvalue": "O preço deve ser maior que 0.",
"amount_maxlength": "Valor não deve ter mais de 20 dígitos.",
"amount_minvalue": "O valor deve ser maior que 0.",
"discount_maxlength": "Discount should not be greater than max discount",
"discount_maxlength": "Desconto não deve ser maior que o máximo de desconto",
"description_maxlength": "A descrição não deve ter mais que 255 caracteres.",
"subject_maxlength": "O assunto não deve ter mais que 100 caracteres.",
"message_maxlength": "A mensagem não deve ter mais que 255 caracteres.",
@ -1451,41 +1451,41 @@
"prefix_maxlength": "O prefixo não deve ter mais que 5 caracteres.",
"something_went_wrong": "algo deu errado",
"number_length_minvalue": "O valor deve ser maior que 0",
"at_least_one_ability": "Please select atleast one Permission.",
"valid_driver_key": "Please enter a valid {driver} key.",
"valid_exchange_rate": "Please enter a valid exchange rate.",
"company_name_not_same": "Company name must match with given name."
"at_least_one_ability": "Você deve selecionar ao menos uma permissão.",
"valid_driver_key": "Por favor, insira uma chave válida de {driver}.",
"valid_exchange_rate": "Por favor digite a taxa de câmbio.",
"company_name_not_same": "O nome da empresa deve corresponder com o nome fornecido."
},
"errors": {
"starter_plan": "This feature is available on Starter plan and onwards!",
"invalid_provider_key": "Please Enter Valid Provider API Key.",
"estimate_number_used": "The estimate number has already been taken.",
"invoice_number_used": "The invoice number has already been taken.",
"payment_attached": "This invoice already has a payment attached to it. Make sure to delete the attached payments first in order to go ahead with the removal.",
"payment_number_used": "The payment number has already been taken.",
"name_already_taken": "The name has already been taken.",
"receipt_does_not_exist": "Receipt does not exist.",
"customer_cannot_be_changed_after_payment_is_added": "Customer cannot be change after payment is added",
"invalid_credentials": "Invalid Credentials.",
"not_allowed": "Not Allowed",
"login_invalid_credentials": "These credentials do not match our records.",
"enter_valid_cron_format": "Please enter a valid cron format",
"email_could_not_be_sent": "Email could not be sent to this email address.",
"invalid_address": "Please enter a valid address.",
"invalid_key": "Please enter valid key.",
"invalid_state": "Please enter a valid state.",
"invalid_city": "Please enter a valid city.",
"invalid_postal_code": "Please enter a valid zip.",
"invalid_format": "Please enter valid query string format.",
"api_error": "Server not responding.",
"feature_not_enabled": "Feature not enabled.",
"request_limit_met": "Api request limit exceeded.",
"address_incomplete": "Incomplete Address"
"starter_plan": "Este recurso está disponível no plano de Starter!",
"invalid_provider_key": "Por favor, insira uma chave de API do provedor válido.",
"estimate_number_used": "O número de pagamento já está em uso.",
"invoice_number_used": "O número da fatura já está em uso.",
"payment_attached": "Uma das faturas selecionadas já possui um pagamento anexado. Certifique-se de excluir os pagamentos anexados primeiro, para continuar com a exclusão.",
"payment_number_used": "O número de pagamento já está em uso.",
"name_already_taken": "O nome já está em uso.",
"receipt_does_not_exist": "O recibo não existe.",
"customer_cannot_be_changed_after_payment_is_added": "O cliente não pode ser alterado após o pagamento ser adicionado",
"invalid_credentials": "Credenciais inválidas",
"not_allowed": "Não permitido",
"login_invalid_credentials": "Credenciais não correspondem aos nossos registros.",
"enter_valid_cron_format": "Por favor, insira um formato de URL válida",
"email_could_not_be_sent": "Não foi possível enviar o e-mail para este endereço de e-mail.",
"invalid_address": "Por favor, insira um endereço de e-mail válido.",
"invalid_key": "Favor inserir uma chave válida.",
"invalid_state": "Por favor, insira um estado válido.",
"invalid_city": "Por favor, insira uma cidade válida.",
"invalid_postal_code": "Por favor, insira um CEP válido.",
"invalid_format": "Por favor, insira o formato de texto de consulta válido.",
"api_error": "O servidor não está respondendo",
"feature_not_enabled": "Recurso não ativado.",
"request_limit_met": "Limite de solicitações excedido",
"address_incomplete": "Endereço Incompleto"
},
"pdf_estimate_label": "Orçamento",
"pdf_estimate_number": "Numero do Orçamento",
"pdf_estimate_date": "Data do Orçamento",
"pdf_estimate_expire_date": "Data de expiração",
"pdf_estimate_expire_date": "Validade",
"pdf_invoice_label": "Fatura",
"pdf_invoice_number": "Número da fatura",
"pdf_invoice_date": "Data da Fatura",
@ -1522,5 +1522,5 @@
"pdf_bill_to": "Cobrar a,",
"pdf_ship_to": "Envie a,",
"pdf_received_from": "Remetente:",
"pdf_tax_label": "Tax"
"pdf_tax_label": "Imposto"
}

View File

@ -1485,7 +1485,7 @@
"pdf_estimate_label": "Estimate",
"pdf_estimate_number": "Estimate Number",
"pdf_estimate_date": "Estimate Date",
"pdf_estimate_expire_date": "Expiry date",
"pdf_estimate_expire_date": "Expiry Date",
"pdf_invoice_label": "Invoice",
"pdf_invoice_number": "Invoice Number",
"pdf_invoice_date": "Invoice Date",

File diff suppressed because it is too large Load Diff

View File

@ -1485,7 +1485,7 @@
"pdf_estimate_label": "Cenový odhad",
"pdf_estimate_number": "Číslo cenového odhadu",
"pdf_estimate_date": "Dátum cenového odhadu",
"pdf_estimate_expire_date": "Platnosť cenového odhadu",
"pdf_estimate_expire_date": "Expiry Date",
"pdf_invoice_label": "Faktúra",
"pdf_invoice_number": "Číslo faktúry",
"pdf_invoice_date": "Dátum vystavenia",

File diff suppressed because it is too large Load Diff

View File

@ -12,7 +12,7 @@
"settings": "Podešavanja",
"logout": "Odjavi se",
"users": "Korisnici",
"modules": "Modules"
"modules": "Moduli"
},
"general": {
"add_company": "Dodaj kompaniju",
@ -30,8 +30,8 @@
"from": "Pošiljalac",
"to": "Primalac",
"ok": "Ok",
"yes": "Yes",
"no": "No",
"yes": "Da",
"no": "Ne",
"sort_by": "Rasporedi Po",
"ascending": "Rastuće",
"descending": "Opadajuće",
@ -39,7 +39,7 @@
"body": "Telo",
"message": "Poruka",
"send": "Pošalji",
"preview": "Preview",
"preview": "Pregled",
"go_back": "Idi nazad",
"back_to_login": "Nazad na prijavu?",
"home": "Početna",
@ -95,9 +95,9 @@
"copied_pdf_url_clipboard": "Link do PDF fajla kopiran!",
"copied_url_clipboard": "Copied url to clipboard!",
"docs": "Docs",
"do_you_wish_to_continue": "Do you wish to continue?",
"note": "Note",
"pay_invoice": "Pay Invoice",
"do_you_wish_to_continue": "Da li želite nastaviti?",
"note": "Bilješka",
"pay_invoice": "Plati račun",
"login_successfully": "Logged in successfully!",
"logged_out_successfully": "Logged out successfully",
"mark_as_default": "Mark as default"
@ -318,10 +318,10 @@
},
"accepted": "Prihvaćeno",
"rejected": "Odbijeno",
"expired": "Expired",
"expired": "Istekao",
"sent": "Poslato",
"draft": "U izradi",
"viewed": "Viewed",
"viewed": "Pregledano",
"declined": "Odbijeno",
"new_estimate": "Nova Profaktura",
"add_new_estimate": "Dodaj novu Profakturu",
@ -1485,7 +1485,7 @@
"pdf_estimate_label": "Profaktura",
"pdf_estimate_number": "Broj Profakture",
"pdf_estimate_date": "Datum Profakture",
"pdf_estimate_expire_date": "Datum isteka Profakture",
"pdf_estimate_expire_date": "Expiry Date",
"pdf_invoice_label": "Faktura",
"pdf_invoice_number": "Broj Fakture",
"pdf_invoice_date": "Datum Fakture",

View File

@ -1485,7 +1485,7 @@
"pdf_estimate_label": "Kostnadsförslag",
"pdf_estimate_number": "Kostnadsförslagsnummer",
"pdf_estimate_date": "Kostnadsförslagsdatum",
"pdf_estimate_expire_date": "Utgångsdatum",
"pdf_estimate_expire_date": "Expiry Date",
"pdf_invoice_label": "Faktura",
"pdf_invoice_number": "Fakturanummer",
"pdf_invoice_date": "Fakturadatum",

File diff suppressed because it is too large Load Diff

View File

@ -1485,7 +1485,7 @@
"pdf_estimate_label": "Estimate",
"pdf_estimate_number": "Estimate Number",
"pdf_estimate_date": "Estimate Date",
"pdf_estimate_expire_date": "Expiry date",
"pdf_estimate_expire_date": "Expiry Date",
"pdf_invoice_label": "Invoice",
"pdf_invoice_number": "Invoice Number",
"pdf_invoice_date": "Invoice Date",

File diff suppressed because it is too large Load Diff

View File

@ -12,7 +12,7 @@
"settings": "Cài đặt",
"logout": "Đăng xuất",
"users": "Người dùng",
"modules": "Modules"
"modules": "Các Mô-Đun"
},
"general": {
"add_company": "Thêm công ty",
@ -93,7 +93,7 @@
"no_note_found": "Không tìm thấy ghi chú",
"insert_note": "Chèn ghi chú",
"copied_pdf_url_clipboard": "Đã sao chép url PDF vào khay nhớ tạm!",
"copied_url_clipboard": "Copied url to clipboard!",
"copied_url_clipboard": "Đã sao chép url vào khay nhớ tạm!",
"docs": "Tài liệu",
"do_you_wish_to_continue": "Bạn có muốn tiếp tục không?",
"note": "Ghi chú",
@ -1485,7 +1485,7 @@
"pdf_estimate_label": "Ước tính",
"pdf_estimate_number": "Số ước tính",
"pdf_estimate_date": "Ngày ước tính",
"pdf_estimate_expire_date": "Ngày hết hạn",
"pdf_estimate_expire_date": "Expiry Date",
"pdf_invoice_label": "Hóa đơn",
"pdf_invoice_number": "Số hóa đơn",
"pdf_invoice_date": "Ngày lập hóa đơn",

View File

@ -93,14 +93,14 @@
"no_note_found": "沒有找到備註",
"insert_note": "插入備註",
"copied_pdf_url_clipboard": "複製PDF位址到剪貼簿!",
"copied_url_clipboard": "Copied url to clipboard!",
"copied_url_clipboard": "將網址複製到剪貼簿!",
"docs": "文檔",
"do_you_wish_to_continue": "你確定要繼續?",
"note": "備註",
"pay_invoice": "Pay Invoice",
"login_successfully": "Logged in successfully!",
"logged_out_successfully": "Logged out successfully",
"mark_as_default": "Mark as default"
"pay_invoice": "支付發票",
"login_successfully": "已成功登入!",
"logged_out_successfully": "已成功登出",
"mark_as_default": "標記為預設值"
},
"dashboard": {
"select_year": "選擇年份",
@ -109,7 +109,7 @@
"customers": "客户",
"invoices": "發票",
"estimates": "報價",
"payments": "Payments"
"payments": "付款"
},
"chart_info": {
"total_sales": "銷售",
@ -208,10 +208,10 @@
"new_customer": "新客戶",
"edit_customer": "編輯客戶",
"basic_info": "基本資料",
"portal_access": "Portal Access",
"portal_access_text": "Would you like to allow this customer to login to the Customer Portal?",
"portal_access_url": "Customer Portal Login URL",
"portal_access_url_help": "Please copy & forward the above given URL to your customer for providing access.",
"portal_access": "門戶訪問",
"portal_access_text": "您想允許此客戶登入客戶門戶嗎?",
"portal_access_url": "客戶門戶登入URL",
"portal_access_url_help": "請將上述給定的URL複製並轉發給您的客戶以提供訪問許可權。",
"billing_address": "帳單地址",
"shipping_address": "送貨地址",
"copy_billing_address": "由帳單複製",
@ -231,7 +231,7 @@
"confirm_delete": "你將不能夠還原此客戶, 以及此客戶相關的發票, 報價及付款. | 你將不能夠還原此客戶, 以及此客戶相關的發票, 報價及付款.",
"created_message": "成功新增客戶",
"updated_message": "成功更新客戶",
"address_updated_message": "Address Information Updated succesfully",
"address_updated_message": "地址資訊已成功更新",
"deleted_message": "成功刪除客戶 | 成功刪除客戶",
"edit_currency_not_allowed": "交易一旦創建後就不能改變貨幣!"
},
@ -265,8 +265,8 @@
},
"estimates": {
"title": "報價",
"accept_estimate": "Accept Estimate",
"reject_estimate": "Reject Estimate",
"accept_estimate": "接受估價",
"reject_estimate": "拒絕估算",
"estimate": "報價 | 報價",
"estimates_list": "報價列表",
"days": "{days} 天",
@ -318,10 +318,10 @@
},
"accepted": "已接受",
"rejected": "已拒絕",
"expired": "Expired",
"expired": "已過期",
"sent": "傳送",
"draft": "草稿",
"viewed": "Viewed",
"viewed": "已檢視",
"declined": "拒絕",
"new_estimate": "新報價",
"add_new_estimate": "新增報價",
@ -355,14 +355,14 @@
"select_an_item": "輸入或點擊去選擇商品",
"type_item_description": "商品詳情(可選)"
},
"mark_as_default_estimate_template_description": "If enabled, the selected template will be automatically selected for new estimates."
"mark_as_default_estimate_template_description": "如果啟用,所選模板將自動選擇新的估算。"
},
"invoices": {
"title": "發票",
"download": "Download",
"pay_invoice": "Pay Invoice",
"download": "下載",
"pay_invoice": "支付發票",
"invoices_list": "發票列表",
"invoice_information": "Invoice Information",
"invoice_information": "發票資訊",
"days": "{days} 天",
"months": "{months} 月",
"years": "{years} 年",
@ -447,7 +447,7 @@
"marked_as_sent_message": "發票已標示為成功傳送",
"something_went_wrong": "出現錯誤",
"invalid_due_amount_message": "發票總額不能少於支付總額. 請更新發票或刪除相關支付再繼續.",
"mark_as_default_invoice_template_description": "If enabled, the selected template will be automatically selected for new invoices."
"mark_as_default_invoice_template_description": "如果啟用,所選模板將自動選擇新發票"
},
"recurring_invoices": {
"title": "定期發票",
@ -464,11 +464,11 @@
"completed": "已完成",
"customer": "客戶",
"paid_status": "付款狀態",
"ref_no": "REF NO.",
"number": "NUMBER",
"amount_due": "AMOUNT DUE",
"partially_paid": "Partially Paid",
"total": "Total",
"ref_no": "參考號碼",
"number": "",
"amount_due": "到期金額",
"partially_paid": "部分支付",
"total": "總計",
"discount": "Discount",
"sub_total": "Sub Total",
"invoice": "Recurring Invoice | Recurring Invoices",
@ -504,16 +504,16 @@
"invoice_mark_as_sent": "This recurring invoice will be marked as sent",
"confirm_send": "This recurring invoice will be sent via email to the customer",
"starts_at": "Start Date",
"due_date": "Invoice Due Date",
"record_payment": "Record Payment",
"add_new_invoice": "Add New Recurring Invoice",
"update_expense": "Update Expense",
"edit_invoice": "Edit Recurring Invoice",
"new_invoice": "New Recurring Invoice",
"send_automatically": "Send Automatically",
"send_automatically_desc": "Enable this, if you would like to send the invoice automatically to the customer when its created.",
"save_invoice": "Save Recurring Invoice",
"update_invoice": "Update Recurring Invoice",
"due_date": "發票到期日期",
"record_payment": "紀錄付款",
"add_new_invoice": "添加定期發票",
"update_expense": "更新支出",
"edit_invoice": "編輯定期發票",
"new_invoice": "添加定期發票",
"send_automatically": "自動發送",
"send_automatically_desc": "如果您希望在建立發票時自動將發票發送給客戶,請啟用此選項。",
"save_invoice": "保存定期發票",
"update_invoice": "更新定期發票",
"add_new_tax": "Add New Tax",
"no_invoices": "No Recurring Invoices yet!",
"mark_as_rejected": "Mark as rejected",
@ -1485,7 +1485,7 @@
"pdf_estimate_label": "報價",
"pdf_estimate_number": "報價單號",
"pdf_estimate_date": "報價日期",
"pdf_estimate_expire_date": "有效日期",
"pdf_estimate_expire_date": "Expiry Date",
"pdf_invoice_label": "發票",
"pdf_invoice_number": "發票號碼",
"pdf_invoice_date": "發票日期",

View File

@ -17,7 +17,7 @@
<meta name="csrf-token" content="{{ csrf_token() }}">
<!-- Module Styles -->
@foreach (\Crater\Services\Module\ModuleFacade::allStyles() as $name => $path)
@foreach(\Crater\Services\Module\ModuleFacade::allStyles() as $name => $path)
<link rel="stylesheet" href="/modules/styles/{{ $name }}">
@endforeach
@ -25,8 +25,8 @@
</head>
<body
class="h-full overflow-hidden bg-gray-100 dark:bg-gray-900 dark:text-white font-base
@if (isset($current_theme)) theme-{{ $current_theme }} @else theme-{{ get_app_setting('admin_portal_theme') ?? 'crater' }} @endif ">
class="h-full overflow-hidden bg-gray-100 font-base
@if(isset($current_theme)) theme-{{ $current_theme }} @else theme-{{get_app_setting('admin_portal_theme') ?? 'crater'}} @endif ">
<!-- Module Scripts -->
@foreach (\Crater\Services\Module\ModuleFacade::allScripts() as $name => $path)
@ -38,14 +38,6 @@
@endforeach
<script type="module">
if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.classList.add('dark')
document.documentElement.style.setProperty('color-scheme', 'dark');
} else {
document.documentElement.classList.remove('dark')
document.documentElement.style.setProperty('color-scheme', 'light')
}
@if(isset($customer_logo))
window.customer_logo = "/storage/{{$customer_logo}}"
@ -65,12 +57,12 @@
window.login_page_description = "{{$login_page_description}}"
@endif
@endif
@if(isset($copyright_text))
window.copyright_text = "{{$copyright_text}}"
@endif
@endif
window.Crater.start()
</script>

View File

@ -386,10 +386,6 @@
}
</style>
@if (App::isLocale('th'))
@include('app.pdf.locale.th')
@endif
</head>
<body>

View File

@ -408,10 +408,6 @@
}
</style>
@if (App::isLocale('th'))
@include('app.pdf.locale.th')
@endif
</head>
<body>

View File

@ -346,10 +346,6 @@
}
</style>
@if (App::isLocale('th'))
@include('app.pdf.locale.th')
@endif
</head>
<body>

View File

@ -327,10 +327,6 @@
}
</style>
@if (App::isLocale('th'))
@include('app.pdf.locale.th')
@endif
</head>
<body>

View File

@ -377,10 +377,6 @@
}
</style>
@if (App::isLocale('th'))
@include('app.pdf.locale.th')
@endif
</head>
<body>

Some files were not shown because too many files have changed in this diff Show More