mirror of
https://github.com/crater-invoice/crater.git
synced 2025-10-28 12:11:08 -04:00
Merge branch 'master' into master
This commit is contained in:
@ -1,6 +1,6 @@
|
|||||||
APP_ENV=production
|
APP_ENV=production
|
||||||
APP_KEY=base64:kgk/4DW1vEVy7aEvet5FPp5un6PIGe/so8H0mvoUtW0=
|
APP_KEY=base64:kgk/4DW1vEVy7aEvet5FPp5un6PIGe/so8H0mvoUtW0=
|
||||||
APP_DEBUG=false
|
APP_DEBUG=true
|
||||||
APP_LOG_LEVEL=debug
|
APP_LOG_LEVEL=debug
|
||||||
APP_URL=http://crater.test
|
APP_URL=http://crater.test
|
||||||
|
|
||||||
|
|||||||
26
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
26
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**Expected behavior**
|
||||||
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
|
**Screenshots**
|
||||||
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
|
**Please complete the following information:**
|
||||||
|
- Crater version:
|
||||||
|
- PHP version:
|
||||||
|
- Database type and version:
|
||||||
|
|
||||||
|
**Optional info**
|
||||||
|
- OS: [e.g. Ubuntu]
|
||||||
|
- Browser: [e.g. chrome, safari]
|
||||||
17
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
17
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Is your feature request related to a problem? Please describe.**
|
||||||
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
|
**Describe alternatives you've considered**
|
||||||
|
A clear and concise description of any alternative solutions or features you've considered.
|
||||||
@ -23,8 +23,8 @@ FROM php:7.3.12-fpm-alpine
|
|||||||
# Use the default production configuration
|
# Use the default production configuration
|
||||||
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
|
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
|
||||||
|
|
||||||
RUN apk add --no-cache libpng-dev libxml2-dev oniguruma-dev && \
|
RUN apk add --no-cache libpng-dev libxml2-dev oniguruma-dev libzip-dev && \
|
||||||
docker-php-ext-install bcmath ctype json gd mbstring pdo pdo_mysql tokenizer xml
|
docker-php-ext-install bcmath ctype json gd mbstring pdo pdo_mysql tokenizer xml zip
|
||||||
|
|
||||||
# Set container's working dir
|
# Set container's working dir
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|||||||
@ -49,15 +49,20 @@ class Estimate extends Model
|
|||||||
];
|
];
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'total' => 'float',
|
'total' => 'integer',
|
||||||
'tax' => 'float',
|
'tax' => 'integer',
|
||||||
'sub_total' => 'float'
|
'sub_total' => 'integer',
|
||||||
|
'discount' => 'float',
|
||||||
|
'discount_val' => 'integer',
|
||||||
];
|
];
|
||||||
|
|
||||||
public static function getNextEstimateNumber()
|
public static function getNextEstimateNumber($value)
|
||||||
{
|
{
|
||||||
// Get the last created order
|
// Get the last created order
|
||||||
$lastOrder = Estimate::orderBy('created_at', 'desc')->first();
|
$lastOrder = Estimate::where('estimate_number', 'LIKE', $value . '-%')
|
||||||
|
->orderBy('created_at', 'desc')
|
||||||
|
->first();
|
||||||
|
|
||||||
if (!$lastOrder) {
|
if (!$lastOrder) {
|
||||||
// We get here if there is no order at all
|
// We get here if there is no order at all
|
||||||
// If there is no number set it to 0, which will be 1 at the end.
|
// If there is no number set it to 0, which will be 1 at the end.
|
||||||
@ -99,10 +104,16 @@ class Estimate extends Model
|
|||||||
|
|
||||||
public function getEstimateNumAttribute()
|
public function getEstimateNumAttribute()
|
||||||
{
|
{
|
||||||
$position = $this->strposX($this->estimate_number, "-", 2) + 1;
|
$position = $this->strposX($this->estimate_number, "-", 1) + 1;
|
||||||
return substr($this->estimate_number, $position);
|
return substr($this->estimate_number, $position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getEstimatePrefixAttribute()
|
||||||
|
{
|
||||||
|
$prefix = explode("-",$this->estimate_number)[0];
|
||||||
|
return $prefix;
|
||||||
|
}
|
||||||
|
|
||||||
private function strposX($haystack, $needle, $number)
|
private function strposX($haystack, $needle, $number)
|
||||||
{
|
{
|
||||||
if ($number == '1') {
|
if ($number == '1') {
|
||||||
|
|||||||
@ -146,7 +146,8 @@ class CompanyController extends Controller
|
|||||||
$languages = [
|
$languages = [
|
||||||
["code"=>"en", "name" => "English"],
|
["code"=>"en", "name" => "English"],
|
||||||
["code"=>"fr", "name" => "French"],
|
["code"=>"fr", "name" => "French"],
|
||||||
["code"=>"es", "name" => "Spanish"]
|
["code"=>"es", "name" => "Spanish"],
|
||||||
|
["code"=>"ar", "name" => "العربية"],
|
||||||
];
|
];
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
@ -191,6 +192,58 @@ class CompanyController extends Controller
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getCustomizeSetting (Request $request)
|
||||||
|
{
|
||||||
|
$invoice_prefix = CompanySetting::getSetting('invoice_prefix', $request->header('company'));
|
||||||
|
$invoice_auto_generate = CompanySetting::getSetting('invoice_auto_generate', $request->header('company'));
|
||||||
|
|
||||||
|
$estimate_prefix = CompanySetting::getSetting('estimate_prefix', $request->header('company'));
|
||||||
|
$estimate_auto_generate = CompanySetting::getSetting('estimate_auto_generate', $request->header('company'));
|
||||||
|
|
||||||
|
$payment_prefix = CompanySetting::getSetting('payment_prefix', $request->header('company'));
|
||||||
|
$payment_auto_generate = CompanySetting::getSetting('payment_auto_generate', $request->header('company'));
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'invoice_prefix' => $invoice_prefix,
|
||||||
|
'invoice_auto_generate' => $invoice_auto_generate,
|
||||||
|
'estimate_prefix' => $estimate_prefix,
|
||||||
|
'estimate_auto_generate' => $estimate_auto_generate,
|
||||||
|
'payment_prefix' => $payment_prefix,
|
||||||
|
'payment_auto_generate' => $payment_auto_generate,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateCustomizeSetting (Request $request)
|
||||||
|
{
|
||||||
|
$sets = [];
|
||||||
|
|
||||||
|
if ($request->type == "PAYMENTS") {
|
||||||
|
$sets = [
|
||||||
|
'payment_prefix'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->type == "INVOICES") {
|
||||||
|
$sets = [
|
||||||
|
'invoice_prefix',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->type == "ESTIMATES") {
|
||||||
|
$sets = [
|
||||||
|
'estimate_prefix',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($sets as $key) {
|
||||||
|
CompanySetting::setSetting($key, $request->$key, $request->header('company'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => true
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update a specific Company Setting
|
* Update a specific Company Setting
|
||||||
* @param \Crater\Http\Requests\SettingRequest $request
|
* @param \Crater\Http\Requests\SettingRequest $request
|
||||||
|
|||||||
@ -177,6 +177,7 @@ class CustomersController extends Controller
|
|||||||
$customer->enable_portal = $request->enable_portal;
|
$customer->enable_portal = $request->enable_portal;
|
||||||
$customer->save();
|
$customer->save();
|
||||||
|
|
||||||
|
$customer->addresses()->delete();
|
||||||
if ($request->addresses) {
|
if ($request->addresses) {
|
||||||
foreach ($request->addresses as $address) {
|
foreach ($request->addresses as $address) {
|
||||||
$newAddress = $customer->addresses()->firstOrNew(['type' => $address["type"]]);
|
$newAddress = $customer->addresses()->firstOrNew(['type' => $address["type"]]);
|
||||||
|
|||||||
@ -56,25 +56,43 @@ class EstimatesController extends Controller
|
|||||||
|
|
||||||
public function create(Request $request)
|
public function create(Request $request)
|
||||||
{
|
{
|
||||||
$nextEstimateNumber = 'EST-'.Estimate::getNextEstimateNumber();
|
$estimate_prefix = CompanySetting::getSetting('estimate_prefix', $request->header('company'));
|
||||||
|
$estimate_num_auto_generate = CompanySetting::getSetting('estimate_auto_generate', $request->header('company'));
|
||||||
|
|
||||||
|
$nextEstimateNumberAttribute = null;
|
||||||
|
$nextEstimateNumber = Estimate::getNextEstimateNumber($estimate_prefix);
|
||||||
|
|
||||||
|
if ($estimate_num_auto_generate == "YES") {
|
||||||
|
$nextEstimateNumberAttribute = $nextEstimateNumber;
|
||||||
|
}
|
||||||
|
|
||||||
$tax_per_item = CompanySetting::getSetting('tax_per_item', $request->header('company'));
|
$tax_per_item = CompanySetting::getSetting('tax_per_item', $request->header('company'));
|
||||||
$discount_per_item = CompanySetting::getSetting('discount_per_item', $request->header('company'));
|
$discount_per_item = CompanySetting::getSetting('discount_per_item', $request->header('company'));
|
||||||
$customers = User::where('role', 'customer')->get();
|
$customers = User::where('role', 'customer')->get();
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'customers' => $customers,
|
'customers' => $customers,
|
||||||
'nextEstimateNumber' => $nextEstimateNumber,
|
'nextEstimateNumberAttribute' => $nextEstimateNumberAttribute,
|
||||||
|
'nextEstimateNumber' => $estimate_prefix.'-'.$nextEstimateNumber,
|
||||||
'taxes' => Tax::whereCompany($request->header('company'))->latest()->get(),
|
'taxes' => Tax::whereCompany($request->header('company'))->latest()->get(),
|
||||||
'items' => Item::whereCompany($request->header('company'))->get(),
|
'items' => Item::whereCompany($request->header('company'))->get(),
|
||||||
'tax_per_item' => $tax_per_item,
|
'tax_per_item' => $tax_per_item,
|
||||||
'discount_per_item' => $discount_per_item,
|
'discount_per_item' => $discount_per_item,
|
||||||
'estimateTemplates' => EstimateTemplate::all(),
|
'estimateTemplates' => EstimateTemplate::all(),
|
||||||
'shareable_link' => ''
|
'shareable_link' => '',
|
||||||
|
'estimate_prefix' => $estimate_prefix
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function store(EstimatesRequest $request)
|
public function store(EstimatesRequest $request)
|
||||||
{
|
{
|
||||||
|
$estimate_number = explode("-",$request->estimate_number);
|
||||||
|
$number_attributes['estimate_number'] = $estimate_number[0].'-'.sprintf('%06d', intval($estimate_number[1]));
|
||||||
|
|
||||||
|
Validator::make($number_attributes, [
|
||||||
|
'estimate_number' => 'required|unique:estimates,estimate_number'
|
||||||
|
])->validate();
|
||||||
|
|
||||||
$estimate_date = Carbon::createFromFormat('d/m/Y', $request->estimate_date);
|
$estimate_date = Carbon::createFromFormat('d/m/Y', $request->estimate_date);
|
||||||
$expiry_date = Carbon::createFromFormat('d/m/Y', $request->expiry_date);
|
$expiry_date = Carbon::createFromFormat('d/m/Y', $request->expiry_date);
|
||||||
$status = Estimate::STATUS_DRAFT;
|
$status = Estimate::STATUS_DRAFT;
|
||||||
@ -101,7 +119,7 @@ class EstimatesController extends Controller
|
|||||||
$estimate = Estimate::create([
|
$estimate = Estimate::create([
|
||||||
'estimate_date' => $estimate_date,
|
'estimate_date' => $estimate_date,
|
||||||
'expiry_date' => $expiry_date,
|
'expiry_date' => $expiry_date,
|
||||||
'estimate_number' => $request->estimate_number,
|
'estimate_number' => $number_attributes['estimate_number'],
|
||||||
'reference_number' => $request->reference_number,
|
'reference_number' => $request->reference_number,
|
||||||
'user_id' => $request->user_id,
|
'user_id' => $request->user_id,
|
||||||
'company_id' => $request->header('company'),
|
'company_id' => $request->header('company'),
|
||||||
@ -127,7 +145,7 @@ class EstimatesController extends Controller
|
|||||||
|
|
||||||
if (array_key_exists('taxes', $estimateItem) && $estimateItem['taxes']) {
|
if (array_key_exists('taxes', $estimateItem) && $estimateItem['taxes']) {
|
||||||
foreach ($estimateItem['taxes'] as $tax) {
|
foreach ($estimateItem['taxes'] as $tax) {
|
||||||
if ($tax['amount']) {
|
if (gettype($tax['amount']) !== "NULL") {
|
||||||
$tax['company_id'] = $request->header('company');
|
$tax['company_id'] = $request->header('company');
|
||||||
$item->taxes()->create($tax);
|
$item->taxes()->create($tax);
|
||||||
}
|
}
|
||||||
@ -137,7 +155,7 @@ class EstimatesController extends Controller
|
|||||||
|
|
||||||
if ($request->has('taxes')) {
|
if ($request->has('taxes')) {
|
||||||
foreach ($request->taxes as $tax) {
|
foreach ($request->taxes as $tax) {
|
||||||
if ($tax['amount']) {
|
if (gettype($tax['amount']) !== "NULL") {
|
||||||
$tax['company_id'] = $request->header('company');
|
$tax['company_id'] = $request->header('company');
|
||||||
$estimate->taxes()->create($tax);
|
$estimate->taxes()->create($tax);
|
||||||
}
|
}
|
||||||
@ -216,26 +234,33 @@ class EstimatesController extends Controller
|
|||||||
|
|
||||||
return response()->json( [
|
return response()->json( [
|
||||||
'customers' => $customers,
|
'customers' => $customers,
|
||||||
'nextEstimateNumber' => $estimate->estimate_number,
|
'nextEstimateNumber' => $estimate->getEstimateNumAttribute(),
|
||||||
'taxes' => Tax::latest()->whereCompany($request->header('company'))->get(),
|
'taxes' => Tax::latest()->whereCompany($request->header('company'))->get(),
|
||||||
'estimate' => $estimate,
|
'estimate' => $estimate,
|
||||||
'items' => Item::whereCompany($request->header('company'))->latest()->get(),
|
'items' => Item::whereCompany($request->header('company'))->latest()->get(),
|
||||||
'estimateTemplates' => EstimateTemplate::all(),
|
'estimateTemplates' => EstimateTemplate::all(),
|
||||||
'tax_per_item' => $estimate->tax_per_item,
|
'tax_per_item' => $estimate->tax_per_item,
|
||||||
'discount_per_item' => $estimate->discount_per_item,
|
'discount_per_item' => $estimate->discount_per_item,
|
||||||
'shareable_link' => url('/estimates/pdf/'.$estimate->unique_hash)
|
'shareable_link' => url('/estimates/pdf/'.$estimate->unique_hash),
|
||||||
|
'estimate_prefix' => $estimate->getEstimatePrefixAttribute()
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function update(EstimatesRequest $request, $id)
|
public function update(EstimatesRequest $request, $id)
|
||||||
{
|
{
|
||||||
|
$estimate_number = explode("-",$request->estimate_number);
|
||||||
|
$number_attributes['estimate_number'] = $estimate_number[0].'-'.sprintf('%06d', intval($estimate_number[1]));
|
||||||
|
Validator::make($number_attributes, [
|
||||||
|
'estimate_number' => 'required|unique:estimates,estimate_number'.','.$id
|
||||||
|
])->validate();
|
||||||
|
|
||||||
$estimate_date = Carbon::createFromFormat('d/m/Y', $request->estimate_date);
|
$estimate_date = Carbon::createFromFormat('d/m/Y', $request->estimate_date);
|
||||||
$expiry_date = Carbon::createFromFormat('d/m/Y', $request->expiry_date);
|
$expiry_date = Carbon::createFromFormat('d/m/Y', $request->expiry_date);
|
||||||
|
|
||||||
$estimate = Estimate::find($id);
|
$estimate = Estimate::find($id);
|
||||||
$estimate->estimate_date = $estimate_date;
|
$estimate->estimate_date = $estimate_date;
|
||||||
$estimate->expiry_date = $expiry_date;
|
$estimate->expiry_date = $expiry_date;
|
||||||
$estimate->estimate_number = $request->estimate_number;
|
$estimate->estimate_number = $number_attributes['estimate_number'];
|
||||||
$estimate->reference_number = $request->reference_number;
|
$estimate->reference_number = $request->reference_number;
|
||||||
$estimate->user_id = $request->user_id;
|
$estimate->user_id = $request->user_id;
|
||||||
$estimate->estimate_template_id = $request->estimate_template_id;
|
$estimate->estimate_template_id = $request->estimate_template_id;
|
||||||
@ -266,7 +291,7 @@ class EstimatesController extends Controller
|
|||||||
|
|
||||||
if (array_key_exists('taxes', $estimateItem) && $estimateItem['taxes']) {
|
if (array_key_exists('taxes', $estimateItem) && $estimateItem['taxes']) {
|
||||||
foreach ($estimateItem['taxes'] as $tax) {
|
foreach ($estimateItem['taxes'] as $tax) {
|
||||||
if ($tax['amount']) {
|
if (gettype($tax['amount']) !== "NULL") {
|
||||||
$tax['company_id'] = $request->header('company');
|
$tax['company_id'] = $request->header('company');
|
||||||
$item->taxes()->create($tax);
|
$item->taxes()->create($tax);
|
||||||
}
|
}
|
||||||
@ -276,7 +301,7 @@ class EstimatesController extends Controller
|
|||||||
|
|
||||||
if ($request->has('taxes')) {
|
if ($request->has('taxes')) {
|
||||||
foreach ($request->taxes as $tax) {
|
foreach ($request->taxes as $tax) {
|
||||||
if ($tax['amount']) {
|
if (gettype($tax['amount']) !== "NULL") {
|
||||||
$tax['company_id'] = $request->header('company');
|
$tax['company_id'] = $request->header('company');
|
||||||
$estimate->taxes()->create($tax);
|
$estimate->taxes()->create($tax);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -66,14 +66,24 @@ class InvoicesController extends Controller
|
|||||||
{
|
{
|
||||||
$tax_per_item = CompanySetting::getSetting('tax_per_item', $request->header('company'));
|
$tax_per_item = CompanySetting::getSetting('tax_per_item', $request->header('company'));
|
||||||
$discount_per_item = CompanySetting::getSetting('discount_per_item', $request->header('company'));
|
$discount_per_item = CompanySetting::getSetting('discount_per_item', $request->header('company'));
|
||||||
$nextInvoiceNumber = "INV-".Invoice::getNextInvoiceNumber();
|
$invoice_prefix = CompanySetting::getSetting('invoice_prefix', $request->header('company'));
|
||||||
|
$invoice_num_auto_generate = CompanySetting::getSetting('invoice_auto_generate', $request->header('company'));
|
||||||
|
|
||||||
|
$nextInvoiceNumberAttribute = null;
|
||||||
|
$nextInvoiceNumber = Invoice::getNextInvoiceNumber($invoice_prefix);
|
||||||
|
|
||||||
|
if ($invoice_num_auto_generate == "YES") {
|
||||||
|
$nextInvoiceNumberAttribute = $nextInvoiceNumber;
|
||||||
|
}
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'nextInvoiceNumber' => $nextInvoiceNumber,
|
'nextInvoiceNumberAttribute' => $nextInvoiceNumberAttribute,
|
||||||
|
'nextInvoiceNumber' => $invoice_prefix.'-'.$nextInvoiceNumber,
|
||||||
'items' => Item::with('taxes')->whereCompany($request->header('company'))->get(),
|
'items' => Item::with('taxes')->whereCompany($request->header('company'))->get(),
|
||||||
'invoiceTemplates' => InvoiceTemplate::all(),
|
'invoiceTemplates' => InvoiceTemplate::all(),
|
||||||
'tax_per_item' => $tax_per_item,
|
'tax_per_item' => $tax_per_item,
|
||||||
'discount_per_item' => $discount_per_item
|
'discount_per_item' => $discount_per_item,
|
||||||
|
'invoice_prefix' => $invoice_prefix
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,6 +95,13 @@ class InvoicesController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function store(Requests\InvoicesRequest $request)
|
public function store(Requests\InvoicesRequest $request)
|
||||||
{
|
{
|
||||||
|
$invoice_number = explode("-",$request->invoice_number);
|
||||||
|
$number_attributes['invoice_number'] = $invoice_number[0].'-'.sprintf('%06d', intval($invoice_number[1]));
|
||||||
|
|
||||||
|
Validator::make($number_attributes, [
|
||||||
|
'invoice_number' => 'required|unique:invoices,invoice_number'
|
||||||
|
])->validate();
|
||||||
|
|
||||||
$invoice_date = Carbon::createFromFormat('d/m/Y', $request->invoice_date);
|
$invoice_date = Carbon::createFromFormat('d/m/Y', $request->invoice_date);
|
||||||
$due_date = Carbon::createFromFormat('d/m/Y', $request->due_date);
|
$due_date = Carbon::createFromFormat('d/m/Y', $request->due_date);
|
||||||
$status = Invoice::STATUS_DRAFT;
|
$status = Invoice::STATUS_DRAFT;
|
||||||
@ -99,7 +116,7 @@ class InvoicesController extends Controller
|
|||||||
$invoice = Invoice::create([
|
$invoice = Invoice::create([
|
||||||
'invoice_date' => $invoice_date,
|
'invoice_date' => $invoice_date,
|
||||||
'due_date' => $due_date,
|
'due_date' => $due_date,
|
||||||
'invoice_number' => $request->invoice_number,
|
'invoice_number' => $number_attributes['invoice_number'],
|
||||||
'reference_number' => $request->reference_number,
|
'reference_number' => $request->reference_number,
|
||||||
'user_id' => $request->user_id,
|
'user_id' => $request->user_id,
|
||||||
'company_id' => $request->header('company'),
|
'company_id' => $request->header('company'),
|
||||||
@ -128,8 +145,7 @@ class InvoicesController extends Controller
|
|||||||
if (array_key_exists('taxes', $invoiceItem) && $invoiceItem['taxes']) {
|
if (array_key_exists('taxes', $invoiceItem) && $invoiceItem['taxes']) {
|
||||||
foreach ($invoiceItem['taxes'] as $tax) {
|
foreach ($invoiceItem['taxes'] as $tax) {
|
||||||
$tax['company_id'] = $request->header('company');
|
$tax['company_id'] = $request->header('company');
|
||||||
|
if (gettype($tax['amount']) !== "NULL") {
|
||||||
if ($tax['amount']) {
|
|
||||||
$item->taxes()->create($tax);
|
$item->taxes()->create($tax);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -140,7 +156,7 @@ class InvoicesController extends Controller
|
|||||||
foreach ($request->taxes as $tax) {
|
foreach ($request->taxes as $tax) {
|
||||||
$tax['company_id'] = $request->header('company');
|
$tax['company_id'] = $request->header('company');
|
||||||
|
|
||||||
if ($tax['amount']) {
|
if (gettype($tax['amount']) !== "NULL") {
|
||||||
$invoice->taxes()->create($tax);
|
$invoice->taxes()->create($tax);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -222,12 +238,13 @@ class InvoicesController extends Controller
|
|||||||
])->find($id);
|
])->find($id);
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'nextInvoiceNumber' => $invoice->invoice_number,
|
'nextInvoiceNumber' => $invoice->getInvoiceNumAttribute(),
|
||||||
'invoice' => $invoice,
|
'invoice' => $invoice,
|
||||||
'invoiceTemplates' => InvoiceTemplate::all(),
|
'invoiceTemplates' => InvoiceTemplate::all(),
|
||||||
'tax_per_item' => $invoice->tax_per_item,
|
'tax_per_item' => $invoice->tax_per_item,
|
||||||
'discount_per_item' => $invoice->discount_per_item,
|
'discount_per_item' => $invoice->discount_per_item,
|
||||||
'shareable_link' => url('/invoices/pdf/'.$invoice->unique_hash)
|
'shareable_link' => url('/invoices/pdf/'.$invoice->unique_hash),
|
||||||
|
'invoice_prefix' => $invoice->getInvoicePrefixAttribute()
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,6 +257,13 @@ class InvoicesController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function update(Requests\InvoicesRequest $request, $id)
|
public function update(Requests\InvoicesRequest $request, $id)
|
||||||
{
|
{
|
||||||
|
$invoice_number = explode("-",$request->invoice_number);
|
||||||
|
$number_attributes['invoice_number'] = $invoice_number[0].'-'.sprintf('%06d', intval($invoice_number[1]));
|
||||||
|
|
||||||
|
Validator::make($number_attributes, [
|
||||||
|
'invoice_number' => 'required|unique:invoices,invoice_number'.','.$id
|
||||||
|
])->validate();
|
||||||
|
|
||||||
$invoice_date = Carbon::createFromFormat('d/m/Y', $request->invoice_date);
|
$invoice_date = Carbon::createFromFormat('d/m/Y', $request->invoice_date);
|
||||||
$due_date = Carbon::createFromFormat('d/m/Y', $request->due_date);
|
$due_date = Carbon::createFromFormat('d/m/Y', $request->due_date);
|
||||||
|
|
||||||
@ -268,7 +292,7 @@ class InvoicesController extends Controller
|
|||||||
|
|
||||||
$invoice->invoice_date = $invoice_date;
|
$invoice->invoice_date = $invoice_date;
|
||||||
$invoice->due_date = $due_date;
|
$invoice->due_date = $due_date;
|
||||||
$invoice->invoice_number = $request->invoice_number;
|
$invoice->invoice_number = $number_attributes['invoice_number'];
|
||||||
$invoice->reference_number = $request->reference_number;
|
$invoice->reference_number = $request->reference_number;
|
||||||
$invoice->user_id = $request->user_id;
|
$invoice->user_id = $request->user_id;
|
||||||
$invoice->invoice_template_id = $request->invoice_template_id;
|
$invoice->invoice_template_id = $request->invoice_template_id;
|
||||||
@ -292,7 +316,6 @@ class InvoicesController extends Controller
|
|||||||
foreach ($oldTaxes as $oldTax) {
|
foreach ($oldTaxes as $oldTax) {
|
||||||
Tax::destroy($oldTax['id']);
|
Tax::destroy($oldTax['id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($invoiceItems as $invoiceItem) {
|
foreach ($invoiceItems as $invoiceItem) {
|
||||||
$invoiceItem['company_id'] = $request->header('company');
|
$invoiceItem['company_id'] = $request->header('company');
|
||||||
$item = $invoice->items()->create($invoiceItem);
|
$item = $invoice->items()->create($invoiceItem);
|
||||||
@ -300,8 +323,7 @@ class InvoicesController extends Controller
|
|||||||
if (array_key_exists('taxes', $invoiceItem) && $invoiceItem['taxes']) {
|
if (array_key_exists('taxes', $invoiceItem) && $invoiceItem['taxes']) {
|
||||||
foreach ($invoiceItem['taxes'] as $tax) {
|
foreach ($invoiceItem['taxes'] as $tax) {
|
||||||
$tax['company_id'] = $request->header('company');
|
$tax['company_id'] = $request->header('company');
|
||||||
|
if (gettype($tax['amount']) !== "NULL") {
|
||||||
if ($tax['amount']) {
|
|
||||||
$item->taxes()->create($tax);
|
$item->taxes()->create($tax);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -312,7 +334,7 @@ class InvoicesController extends Controller
|
|||||||
foreach ($request->taxes as $tax) {
|
foreach ($request->taxes as $tax) {
|
||||||
$tax['company_id'] = $request->header('company');
|
$tax['company_id'] = $request->header('company');
|
||||||
|
|
||||||
if ($tax['amount']) {
|
if (gettype($tax['amount']) !== "NULL") {
|
||||||
$invoice->taxes()->create($tax);
|
$invoice->taxes()->create($tax);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -235,6 +235,45 @@ class OnboardingController extends Controller
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$invoices = [
|
||||||
|
'invoice_auto_generate' => 'YES',
|
||||||
|
'invoice_prefix' => 'INV'
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($invoices as $key => $value) {
|
||||||
|
CompanySetting::setSetting(
|
||||||
|
$key,
|
||||||
|
$value,
|
||||||
|
$user->company_id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$estimates = [
|
||||||
|
'estimate_prefix' => 'EST',
|
||||||
|
'estimate_auto_generate' => 'YES'
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($estimates as $key => $value) {
|
||||||
|
CompanySetting::setSetting(
|
||||||
|
$key,
|
||||||
|
$value,
|
||||||
|
$user->company_id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$payments = [
|
||||||
|
'payment_prefix' => 'PAY',
|
||||||
|
'payment_auto_generate' => 'YES'
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($payments as $key => $value) {
|
||||||
|
CompanySetting::setSetting(
|
||||||
|
$key,
|
||||||
|
$value,
|
||||||
|
$user->company_id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
$colors = [
|
$colors = [
|
||||||
'primary_text_color' => '#5851D8',
|
'primary_text_color' => '#5851D8',
|
||||||
'heading_text_color' => '#595959',
|
'heading_text_color' => '#595959',
|
||||||
@ -271,7 +310,14 @@ class OnboardingController extends Controller
|
|||||||
|
|
||||||
if (file_exists($path)) {
|
if (file_exists($path)) {
|
||||||
file_put_contents($path, str_replace(
|
file_put_contents($path, str_replace(
|
||||||
'PROXY_OAUTH_CLIENT_SECRET='.config('auth.proxy.client_secret'), 'PROXY_OAUTH_CLIENT_SECRET='.$client->secret, file_get_contents($path)
|
'PROXY_OAUTH_CLIENT_SECRET='.config('auth.proxy.client_secret'),
|
||||||
|
'PROXY_OAUTH_CLIENT_SECRET='.$client->secret,
|
||||||
|
file_get_contents($path)
|
||||||
|
));
|
||||||
|
file_put_contents($path, str_replace(
|
||||||
|
'APP_DEBUG=true',
|
||||||
|
'APP_DEBUG=false',
|
||||||
|
file_get_contents($path)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,7 @@ use Carbon\Carbon;
|
|||||||
use function MongoDB\BSON\toJSON;
|
use function MongoDB\BSON\toJSON;
|
||||||
use Crater\User;
|
use Crater\User;
|
||||||
use Crater\Http\Requests\PaymentRequest;
|
use Crater\Http\Requests\PaymentRequest;
|
||||||
|
use Validator;
|
||||||
|
|
||||||
class PaymentController extends Controller
|
class PaymentController extends Controller
|
||||||
{
|
{
|
||||||
@ -50,13 +51,24 @@ class PaymentController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function create(Request $request)
|
public function create(Request $request)
|
||||||
{
|
{
|
||||||
$nextPaymentNumber = 'PAY-'.Payment::getNextPaymentNumber();
|
$payment_prefix = CompanySetting::getSetting('payment_prefix', $request->header('company'));
|
||||||
|
$payment_num_auto_generate = CompanySetting::getSetting('payment_auto_generate', $request->header('company'));
|
||||||
|
|
||||||
|
|
||||||
|
$nextPaymentNumberAttribute = null;
|
||||||
|
$nextPaymentNumber = Payment::getNextPaymentNumber($payment_prefix);
|
||||||
|
|
||||||
|
if ($payment_num_auto_generate == "YES") {
|
||||||
|
$nextPaymentNumberAttribute = $nextPaymentNumber;
|
||||||
|
}
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'customers' => User::where('role', 'customer')
|
'customers' => User::where('role', 'customer')
|
||||||
->whereCompany($request->header('company'))
|
->whereCompany($request->header('company'))
|
||||||
->get(),
|
->get(),
|
||||||
'nextPaymentNumber' => $nextPaymentNumber
|
'nextPaymentNumberAttribute' => $nextPaymentNumberAttribute,
|
||||||
|
'nextPaymentNumber' => $payment_prefix.'-'.$nextPaymentNumber,
|
||||||
|
'payment_prefix' => $payment_prefix
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,6 +80,13 @@ class PaymentController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function store(PaymentRequest $request)
|
public function store(PaymentRequest $request)
|
||||||
{
|
{
|
||||||
|
$payment_number = explode("-",$request->payment_number);
|
||||||
|
$number_attributes['payment_number'] = $payment_number[0].'-'.sprintf('%06d', intval($payment_number[1]));
|
||||||
|
|
||||||
|
Validator::make($number_attributes, [
|
||||||
|
'payment_number' => 'required|unique:payments,payment_number'
|
||||||
|
])->validate();
|
||||||
|
|
||||||
$payment_date = Carbon::createFromFormat('d/m/Y', $request->payment_date);
|
$payment_date = Carbon::createFromFormat('d/m/Y', $request->payment_date);
|
||||||
|
|
||||||
if ($request->has('invoice_id') && $request->invoice_id != null) {
|
if ($request->has('invoice_id') && $request->invoice_id != null) {
|
||||||
@ -90,7 +109,7 @@ class PaymentController extends Controller
|
|||||||
|
|
||||||
$payment = Payment::create([
|
$payment = Payment::create([
|
||||||
'payment_date' => $payment_date,
|
'payment_date' => $payment_date,
|
||||||
'payment_number' => $request->payment_number,
|
'payment_number' => $number_attributes['payment_number'],
|
||||||
'user_id' => $request->user_id,
|
'user_id' => $request->user_id,
|
||||||
'company_id' => $request->header('company'),
|
'company_id' => $request->header('company'),
|
||||||
'invoice_id' => $request->invoice_id,
|
'invoice_id' => $request->invoice_id,
|
||||||
@ -135,7 +154,8 @@ class PaymentController extends Controller
|
|||||||
'customers' => User::where('role', 'customer')
|
'customers' => User::where('role', 'customer')
|
||||||
->whereCompany($request->header('company'))
|
->whereCompany($request->header('company'))
|
||||||
->get(),
|
->get(),
|
||||||
'nextPaymentNumber' => $payment->payment_number,
|
'nextPaymentNumber' => $payment->getPaymentNumAttribute(),
|
||||||
|
'payment_prefix' => $payment->getPaymentPrefixAttribute(),
|
||||||
'payment' => $payment,
|
'payment' => $payment,
|
||||||
'invoices' => $invoices
|
'invoices' => $invoices
|
||||||
]);
|
]);
|
||||||
@ -150,6 +170,13 @@ class PaymentController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function update(PaymentRequest $request, $id)
|
public function update(PaymentRequest $request, $id)
|
||||||
{
|
{
|
||||||
|
$payment_number = explode("-",$request->payment_number);
|
||||||
|
$number_attributes['payment_number'] = $payment_number[0].'-'.sprintf('%06d', intval($payment_number[1]));
|
||||||
|
|
||||||
|
Validator::make($number_attributes, [
|
||||||
|
'payment_number' => 'required|unique:payments,payment_number'.','.$id
|
||||||
|
])->validate();
|
||||||
|
|
||||||
$payment_date = Carbon::createFromFormat('d/m/Y', $request->payment_date);
|
$payment_date = Carbon::createFromFormat('d/m/Y', $request->payment_date);
|
||||||
|
|
||||||
$payment = Payment::find($id);
|
$payment = Payment::find($id);
|
||||||
@ -178,7 +205,7 @@ class PaymentController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
$payment->payment_date = $payment_date;
|
$payment->payment_date = $payment_date;
|
||||||
$payment->payment_number = $request->payment_number;
|
$payment->payment_number = $number_attributes['payment_number'];
|
||||||
$payment->user_id = $request->user_id;
|
$payment->user_id = $request->user_id;
|
||||||
$payment->invoice_id = $request->invoice_id;
|
$payment->invoice_id = $request->invoice_id;
|
||||||
$payment->payment_mode = $request->payment_mode;
|
$payment->payment_mode = $request->payment_mode;
|
||||||
|
|||||||
@ -25,7 +25,6 @@ class EstimatesRequest extends FormRequest
|
|||||||
$rules = [
|
$rules = [
|
||||||
'estimate_date' => 'required',
|
'estimate_date' => 'required',
|
||||||
'expiry_date' => 'required',
|
'expiry_date' => 'required',
|
||||||
'estimate_number' => 'required|unique:estimates,estimate_number',
|
|
||||||
'user_id' => 'required',
|
'user_id' => 'required',
|
||||||
'discount' => 'required',
|
'discount' => 'required',
|
||||||
'discount_val' => 'required',
|
'discount_val' => 'required',
|
||||||
@ -41,10 +40,6 @@ class EstimatesRequest extends FormRequest
|
|||||||
'items.*.price' => 'required'
|
'items.*.price' => 'required'
|
||||||
];
|
];
|
||||||
|
|
||||||
if ($this->getMethod() == 'PUT') {
|
|
||||||
$rules['estimate_number'] = $rules['estimate_number'].','.$this->get('id');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $rules;
|
return $rules;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,7 +25,6 @@ class InvoicesRequest extends FormRequest
|
|||||||
$rules = [
|
$rules = [
|
||||||
'invoice_date' => 'required',
|
'invoice_date' => 'required',
|
||||||
'due_date' => 'required',
|
'due_date' => 'required',
|
||||||
'invoice_number' => 'required|unique:invoices,invoice_number',
|
|
||||||
'user_id' => 'required',
|
'user_id' => 'required',
|
||||||
'discount' => 'required',
|
'discount' => 'required',
|
||||||
'discount_val' => 'required',
|
'discount_val' => 'required',
|
||||||
@ -41,10 +40,6 @@ class InvoicesRequest extends FormRequest
|
|||||||
'items.*.price' => 'required'
|
'items.*.price' => 'required'
|
||||||
];
|
];
|
||||||
|
|
||||||
if ($this->getMethod() == 'PUT') {
|
|
||||||
$rules['invoice_number'] = $rules['invoice_number'].','.$this->get('id');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $rules;
|
return $rules;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,15 +24,10 @@ class PaymentRequest extends FormRequest
|
|||||||
{
|
{
|
||||||
$rules = [
|
$rules = [
|
||||||
'payment_date' => 'required',
|
'payment_date' => 'required',
|
||||||
'payment_number' => 'required|unique:payments,payment_number',
|
|
||||||
'user_id' => 'required',
|
'user_id' => 'required',
|
||||||
'amount' => 'required',
|
'amount' => 'required',
|
||||||
];
|
];
|
||||||
|
|
||||||
if ($this->getMethod() == 'PUT') {
|
|
||||||
$rules['payment_number'] = $rules['payment_number'].','.$this->route('payment');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $rules;
|
return $rules;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,7 +30,7 @@ class ProfileRequest extends FormRequest
|
|||||||
case 'POST':
|
case 'POST':
|
||||||
return [
|
return [
|
||||||
'name' => 'required',
|
'name' => 'required',
|
||||||
'password' => 'required',
|
'password' => 'required|min:8',
|
||||||
'address_street_1' => 'max:255',
|
'address_street_1' => 'max:255',
|
||||||
'address_street_2' => 'max:255',
|
'address_street_2' => 'max:255',
|
||||||
'email' => [
|
'email' => [
|
||||||
|
|||||||
@ -66,10 +66,14 @@ class Invoice extends Model
|
|||||||
'formattedDueDate'
|
'formattedDueDate'
|
||||||
];
|
];
|
||||||
|
|
||||||
public static function getNextInvoiceNumber()
|
public static function getNextInvoiceNumber($value)
|
||||||
{
|
{
|
||||||
// Get the last created order
|
// Get the last created order
|
||||||
$lastOrder = Invoice::orderBy('created_at', 'desc')->first();
|
$lastOrder = Invoice::where('invoice_number', 'LIKE', $value . '-%')
|
||||||
|
->orderBy('created_at', 'desc')
|
||||||
|
->first();
|
||||||
|
|
||||||
|
|
||||||
if (!$lastOrder) {
|
if (!$lastOrder) {
|
||||||
// We get here if there is no order at all
|
// We get here if there is no order at all
|
||||||
// If there is no number set it to 0, which will be 1 at the end.
|
// If there is no number set it to 0, which will be 1 at the end.
|
||||||
@ -143,10 +147,15 @@ class Invoice extends Model
|
|||||||
|
|
||||||
public function getInvoiceNumAttribute()
|
public function getInvoiceNumAttribute()
|
||||||
{
|
{
|
||||||
$position = $this->strposX($this->invoice_number, "-", 2) + 1;
|
$position = $this->strposX($this->invoice_number, "-", 1) + 1;
|
||||||
return substr($this->invoice_number, $position);
|
return substr($this->invoice_number, $position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getInvoicePrefixAttribute () {
|
||||||
|
$prefix = explode("-", $this->invoice_number)[0];
|
||||||
|
return $prefix;
|
||||||
|
}
|
||||||
|
|
||||||
public function getFormattedCreatedAtAttribute($value)
|
public function getFormattedCreatedAtAttribute($value)
|
||||||
{
|
{
|
||||||
$dateFormat = CompanySetting::getSetting('carbon_date_format', $this->company_id);
|
$dateFormat = CompanySetting::getSetting('carbon_date_format', $this->company_id);
|
||||||
|
|||||||
@ -6,7 +6,6 @@ use Illuminate\Contracts\Queue\ShouldQueue;
|
|||||||
use Illuminate\Queue\InteractsWithQueue;
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
use Crater\Listeners\Updates\Listener;
|
use Crater\Listeners\Updates\Listener;
|
||||||
use Crater\Listeners\Updates\v2\Version200;
|
|
||||||
use Crater\Events\UpdateFinished;
|
use Crater\Events\UpdateFinished;
|
||||||
use Crater\Setting;
|
use Crater\Setting;
|
||||||
use Crater\Address;
|
use Crater\Address;
|
||||||
|
|||||||
64
app/Listeners/Updates/v2/Version210.php
Normal file
64
app/Listeners/Updates/v2/Version210.php
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Crater\Listeners\Updates\v2;
|
||||||
|
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
|
use Crater\Events\UpdateFinished;
|
||||||
|
use Crater\Listeners\Updates\Listener;
|
||||||
|
use Crater\Setting;
|
||||||
|
use Crater\CompanySetting;
|
||||||
|
|
||||||
|
class Version210 extends Listener
|
||||||
|
{
|
||||||
|
const VERSION = '2.1.0';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the event listener.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the event.
|
||||||
|
*
|
||||||
|
* @param object $event
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function handle(UpdateFinished $event)
|
||||||
|
{
|
||||||
|
if ($this->isListenerFired($event)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add initial auto generate value
|
||||||
|
$this->addAutoGenerateSettings();
|
||||||
|
|
||||||
|
// Update Crater app version
|
||||||
|
Setting::setSetting('version', static::VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function addAutoGenerateSettings()
|
||||||
|
{
|
||||||
|
$settings = [
|
||||||
|
'invoice_auto_generate' => 'YES',
|
||||||
|
'invoice_prefix' => 'INV',
|
||||||
|
'estimate_prefix' => 'EST',
|
||||||
|
'estimate_auto_generate' => 'YES',
|
||||||
|
'payment_prefix' => 'PAY',
|
||||||
|
'payment_auto_generate' => 'YES'
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($settings as $key => $value) {
|
||||||
|
CompanySetting::setSetting(
|
||||||
|
$key,
|
||||||
|
$value,
|
||||||
|
auth()->user()->company->id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -32,10 +32,34 @@ class Payment extends Model
|
|||||||
'formattedPaymentDate'
|
'formattedPaymentDate'
|
||||||
];
|
];
|
||||||
|
|
||||||
public static function getNextPaymentNumber()
|
|
||||||
|
private function strposX($haystack, $needle, $number)
|
||||||
|
{
|
||||||
|
if ($number == '1') {
|
||||||
|
return strpos($haystack, $needle);
|
||||||
|
} elseif ($number > '1') {
|
||||||
|
return strpos(
|
||||||
|
$haystack,
|
||||||
|
$needle,
|
||||||
|
$this->strposX($haystack, $needle, $number - 1) + strlen($needle)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return error_log('Error: Value for parameter $number is out of range');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPaymentNumAttribute()
|
||||||
|
{
|
||||||
|
$position = $this->strposX($this->payment_number, "-", 1) + 1;
|
||||||
|
return substr($this->payment_number, $position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getNextPaymentNumber($value)
|
||||||
{
|
{
|
||||||
// Get the last created order
|
// Get the last created order
|
||||||
$payment = Payment::orderBy('created_at', 'desc')->first();
|
$payment = Payment::where('payment_number', 'LIKE', $value . '-%')
|
||||||
|
->orderBy('created_at', 'desc')
|
||||||
|
->first();
|
||||||
if (!$payment) {
|
if (!$payment) {
|
||||||
// We get here if there is no order at all
|
// We get here if there is no order at all
|
||||||
// If there is no number set it to 0, which will be 1 at the end.
|
// If there is no number set it to 0, which will be 1 at the end.
|
||||||
@ -54,6 +78,13 @@ class Payment extends Model
|
|||||||
return sprintf('%06d', intval($number) + 1);
|
return sprintf('%06d', intval($number) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getPaymentPrefixAttribute ()
|
||||||
|
{
|
||||||
|
$prefix= explode("-",$this->payment_number)[0];
|
||||||
|
return $prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function invoice()
|
public function invoice()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Invoice::class);
|
return $this->belongsTo(Invoice::class);
|
||||||
|
|||||||
@ -9,6 +9,7 @@ use Crater\Listeners\Updates\v1\Version110;
|
|||||||
use Crater\Listeners\Updates\v2\Version200;
|
use Crater\Listeners\Updates\v2\Version200;
|
||||||
use Crater\Listeners\Updates\v2\Version201;
|
use Crater\Listeners\Updates\v2\Version201;
|
||||||
use Crater\Listeners\Updates\v2\Version202;
|
use Crater\Listeners\Updates\v2\Version202;
|
||||||
|
use Crater\Listeners\Updates\v2\Version210;
|
||||||
|
|
||||||
class EventServiceProvider extends ServiceProvider
|
class EventServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
@ -23,6 +24,7 @@ class EventServiceProvider extends ServiceProvider
|
|||||||
Version200::class,
|
Version200::class,
|
||||||
Version201::class,
|
Version201::class,
|
||||||
Version202::class,
|
Version202::class,
|
||||||
|
Version210::class,
|
||||||
],
|
],
|
||||||
Registered::class => [
|
Registered::class => [
|
||||||
SendEmailVerificationNotification::class,
|
SendEmailVerificationNotification::class,
|
||||||
|
|||||||
@ -61,7 +61,7 @@ class EnvironmentManager
|
|||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'error' => $e->getMessage()
|
'error_message' => $e->getMessage()
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -41,10 +41,14 @@ function clean_slug($string)
|
|||||||
* @param $money
|
* @param $money
|
||||||
* @return formated_money
|
* @return formated_money
|
||||||
*/
|
*/
|
||||||
function format_money_pdf($money)
|
function format_money_pdf($money, $currency = null)
|
||||||
{
|
{
|
||||||
$money = $money / 100;
|
$money = $money / 100;
|
||||||
|
|
||||||
|
if (!$currency) {
|
||||||
$currency = Currency::findOrFail(CompanySetting::getSetting('currency', 1));
|
$currency = Currency::findOrFail(CompanySetting::getSetting('currency', 1));
|
||||||
|
}
|
||||||
|
|
||||||
$format_money = number_format(
|
$format_money = number_format(
|
||||||
$money,
|
$money,
|
||||||
$currency->precision,
|
$currency->precision,
|
||||||
|
|||||||
@ -9,6 +9,6 @@ return [
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'version' => '2.0.2',
|
'version' => '2.1.0',
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|||||||
244
config/dompdf.php
Normal file
244
config/dompdf.php
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Settings
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Set some default values. It is possible to add all defines that can be set
|
||||||
|
| in dompdf_config.inc.php. You can also override the entire config file.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
'show_warnings' => false, // Throw an Exception on warnings from dompdf
|
||||||
|
'orientation' => 'portrait',
|
||||||
|
'defines' => array(
|
||||||
|
/**
|
||||||
|
* The location of the DOMPDF font directory
|
||||||
|
*
|
||||||
|
* The location of the directory where DOMPDF will store fonts and font metrics
|
||||||
|
* Note: This directory must exist and be writable by the webserver process.
|
||||||
|
* *Please note the trailing slash.*
|
||||||
|
*
|
||||||
|
* Notes regarding fonts:
|
||||||
|
* Additional .afm font metrics can be added by executing load_font.php from command line.
|
||||||
|
*
|
||||||
|
* Only the original "Base 14 fonts" are present on all pdf viewers. Additional fonts must
|
||||||
|
* be embedded in the pdf file or the PDF may not display correctly. This can significantly
|
||||||
|
* increase file size unless font subsetting is enabled. Before embedding a font please
|
||||||
|
* review your rights under the font license.
|
||||||
|
*
|
||||||
|
* Any font specification in the source HTML is translated to the closest font available
|
||||||
|
* in the font directory.
|
||||||
|
*
|
||||||
|
* The pdf standard "Base 14 fonts" are:
|
||||||
|
* Courier, Courier-Bold, Courier-BoldOblique, Courier-Oblique,
|
||||||
|
* Helvetica, Helvetica-Bold, Helvetica-BoldOblique, Helvetica-Oblique,
|
||||||
|
* Times-Roman, Times-Bold, Times-BoldItalic, Times-Italic,
|
||||||
|
* Symbol, ZapfDingbats.
|
||||||
|
*/
|
||||||
|
"font_dir" => storage_path('fonts/'), // advised by dompdf (https://github.com/dompdf/dompdf/pull/782)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The location of the DOMPDF font cache directory
|
||||||
|
*
|
||||||
|
* This directory contains the cached font metrics for the fonts used by DOMPDF.
|
||||||
|
* This directory can be the same as DOMPDF_FONT_DIR
|
||||||
|
*
|
||||||
|
* Note: This directory must exist and be writable by the webserver process.
|
||||||
|
*/
|
||||||
|
"font_cache" => storage_path('fonts/'),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The location of a temporary directory.
|
||||||
|
*
|
||||||
|
* The directory specified must be writeable by the webserver process.
|
||||||
|
* The temporary directory is required to download remote images and when
|
||||||
|
* using the PFDLib back end.
|
||||||
|
*/
|
||||||
|
"temp_dir" => sys_get_temp_dir(),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ==== IMPORTANT ====
|
||||||
|
*
|
||||||
|
* dompdf's "chroot": Prevents dompdf from accessing system files or other
|
||||||
|
* files on the webserver. All local files opened by dompdf must be in a
|
||||||
|
* subdirectory of this directory. DO NOT set it to '/' since this could
|
||||||
|
* allow an attacker to use dompdf to read any files on the server. This
|
||||||
|
* should be an absolute path.
|
||||||
|
* This is only checked on command line call by dompdf.php, but not by
|
||||||
|
* direct class use like:
|
||||||
|
* $dompdf = new DOMPDF(); $dompdf->load_html($htmldata); $dompdf->render(); $pdfdata = $dompdf->output();
|
||||||
|
*/
|
||||||
|
"chroot" => realpath(base_path()),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to enable font subsetting or not.
|
||||||
|
*/
|
||||||
|
"enable_font_subsetting" => false,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The PDF rendering backend to use
|
||||||
|
*
|
||||||
|
* Valid settings are 'PDFLib', 'CPDF' (the bundled R&OS PDF class), 'GD' and
|
||||||
|
* 'auto'. 'auto' will look for PDFLib and use it if found, or if not it will
|
||||||
|
* fall back on CPDF. 'GD' renders PDFs to graphic files. {@link
|
||||||
|
* Canvas_Factory} ultimately determines which rendering class to instantiate
|
||||||
|
* based on this setting.
|
||||||
|
*
|
||||||
|
* Both PDFLib & CPDF rendering backends provide sufficient rendering
|
||||||
|
* capabilities for dompdf, however additional features (e.g. object,
|
||||||
|
* image and font support, etc.) differ between backends. Please see
|
||||||
|
* {@link PDFLib_Adapter} for more information on the PDFLib backend
|
||||||
|
* and {@link CPDF_Adapter} and lib/class.pdf.php for more information
|
||||||
|
* on CPDF. Also see the documentation for each backend at the links
|
||||||
|
* below.
|
||||||
|
*
|
||||||
|
* The GD rendering backend is a little different than PDFLib and
|
||||||
|
* CPDF. Several features of CPDF and PDFLib are not supported or do
|
||||||
|
* not make any sense when creating image files. For example,
|
||||||
|
* multiple pages are not supported, nor are PDF 'objects'. Have a
|
||||||
|
* look at {@link GD_Adapter} for more information. GD support is
|
||||||
|
* experimental, so use it at your own risk.
|
||||||
|
*
|
||||||
|
* @link http://www.pdflib.com
|
||||||
|
* @link http://www.ros.co.nz/pdf
|
||||||
|
* @link http://www.php.net/image
|
||||||
|
*/
|
||||||
|
"pdf_backend" => "CPDF",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PDFlib license key
|
||||||
|
*
|
||||||
|
* If you are using a licensed, commercial version of PDFlib, specify
|
||||||
|
* your license key here. If you are using PDFlib-Lite or are evaluating
|
||||||
|
* the commercial version of PDFlib, comment out this setting.
|
||||||
|
*
|
||||||
|
* @link http://www.pdflib.com
|
||||||
|
*
|
||||||
|
* If pdflib present in web server and auto or selected explicitely above,
|
||||||
|
* a real license code must exist!
|
||||||
|
*/
|
||||||
|
//"DOMPDF_PDFLIB_LICENSE" => "your license key here",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* html target media view which should be rendered into pdf.
|
||||||
|
* List of types and parsing rules for future extensions:
|
||||||
|
* http://www.w3.org/TR/REC-html40/types.html
|
||||||
|
* screen, tty, tv, projection, handheld, print, braille, aural, all
|
||||||
|
* Note: aural is deprecated in CSS 2.1 because it is replaced by speech in CSS 3.
|
||||||
|
* Note, even though the generated pdf file is intended for print output,
|
||||||
|
* the desired content might be different (e.g. screen or projection view of html file).
|
||||||
|
* Therefore allow specification of content here.
|
||||||
|
*/
|
||||||
|
"default_media_type" => "screen",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default paper size.
|
||||||
|
*
|
||||||
|
* North America standard is "letter"; other countries generally "a4"
|
||||||
|
*
|
||||||
|
* @see CPDF_Adapter::PAPER_SIZES for valid sizes ('letter', 'legal', 'A4', etc.)
|
||||||
|
*/
|
||||||
|
"default_paper_size" => "a4",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default font family
|
||||||
|
*
|
||||||
|
* Used if no suitable fonts can be found. This must exist in the font folder.
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
"default_font" => "DejaVu Sans",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Image DPI setting
|
||||||
|
*
|
||||||
|
* This setting determines the default DPI setting for images and fonts. The
|
||||||
|
* DPI may be overridden for inline images by explictly setting the
|
||||||
|
* image's width & height style attributes (i.e. if the image's native
|
||||||
|
* width is 600 pixels and you specify the image's width as 72 points,
|
||||||
|
* the image will have a DPI of 600 in the rendered PDF. The DPI of
|
||||||
|
* background images can not be overridden and is controlled entirely
|
||||||
|
* via this parameter.
|
||||||
|
*
|
||||||
|
* For the purposes of DOMPDF, pixels per inch (PPI) = dots per inch (DPI).
|
||||||
|
* If a size in html is given as px (or without unit as image size),
|
||||||
|
* this tells the corresponding size in pt.
|
||||||
|
* This adjusts the relative sizes to be similar to the rendering of the
|
||||||
|
* html page in a reference browser.
|
||||||
|
*
|
||||||
|
* In pdf, always 1 pt = 1/72 inch
|
||||||
|
*
|
||||||
|
* Rendering resolution of various browsers in px per inch:
|
||||||
|
* Windows Firefox and Internet Explorer:
|
||||||
|
* SystemControl->Display properties->FontResolution: Default:96, largefonts:120, custom:?
|
||||||
|
* Linux Firefox:
|
||||||
|
* about:config *resolution: Default:96
|
||||||
|
* (xorg screen dimension in mm and Desktop font dpi settings are ignored)
|
||||||
|
*
|
||||||
|
* Take care about extra font/image zoom factor of browser.
|
||||||
|
*
|
||||||
|
* In images, <img> size in pixel attribute, img css style, are overriding
|
||||||
|
* the real image dimension in px for rendering.
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
"dpi" => 96,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable inline PHP
|
||||||
|
*
|
||||||
|
* If this setting is set to true then DOMPDF will automatically evaluate
|
||||||
|
* inline PHP contained within <script type="text/php"> ... </script> tags.
|
||||||
|
*
|
||||||
|
* Enabling this for documents you do not trust (e.g. arbitrary remote html
|
||||||
|
* pages) is a security risk. Set this option to false if you wish to process
|
||||||
|
* untrusted documents.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
"enable_php" => false,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable inline Javascript
|
||||||
|
*
|
||||||
|
* If this setting is set to true then DOMPDF will automatically insert
|
||||||
|
* JavaScript code contained within <script type="text/javascript"> ... </script> tags.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
"enable_javascript" => true,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable remote file access
|
||||||
|
*
|
||||||
|
* If this setting is set to true, DOMPDF will access remote sites for
|
||||||
|
* images and CSS files as required.
|
||||||
|
* This is required for part of test case www/test/image_variants.html through www/examples.php
|
||||||
|
*
|
||||||
|
* Attention!
|
||||||
|
* This can be a security risk, in particular in combination with DOMPDF_ENABLE_PHP and
|
||||||
|
* allowing remote access to dompdf.php or on allowing remote html code to be passed to
|
||||||
|
* $dompdf = new DOMPDF(, $dompdf->load_html(...,
|
||||||
|
* This allows anonymous users to download legally doubtful internet content which on
|
||||||
|
* tracing back appears to being downloaded by your server, or allows malicious php code
|
||||||
|
* in remote html pages to be executed by your server with your account privileges.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
"enable_remote" => true,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A ratio applied to the fonts height to be more like browsers' line height
|
||||||
|
*/
|
||||||
|
"font_height_ratio" => 1.1,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use the more-than-experimental HTML5 Lib parser
|
||||||
|
*/
|
||||||
|
"enable_html5_parser" => true,
|
||||||
|
),
|
||||||
|
|
||||||
|
|
||||||
|
);
|
||||||
@ -20,9 +20,9 @@ class CreateMediaTable extends Migration
|
|||||||
$table->string('mime_type')->nullable();
|
$table->string('mime_type')->nullable();
|
||||||
$table->string('disk');
|
$table->string('disk');
|
||||||
$table->unsignedInteger('size');
|
$table->unsignedInteger('size');
|
||||||
$table->json('manipulations');
|
$table->text('manipulations');
|
||||||
$table->json('custom_properties');
|
$table->text('custom_properties');
|
||||||
$table->json('responsive_images');
|
$table->text('responsive_images');
|
||||||
$table->unsignedInteger('order_column')->nullable();
|
$table->unsignedInteger('order_column')->nullable();
|
||||||
$table->nullableTimestamps();
|
$table->nullableTimestamps();
|
||||||
});
|
});
|
||||||
|
|||||||
2
public/assets/css/crater.css
vendored
2
public/assets/css/crater.css
vendored
File diff suppressed because one or more lines are too long
1
public/assets/css/crater.css.map
Normal file
1
public/assets/css/crater.css.map
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,4 +1,4 @@
|
|||||||
{
|
{
|
||||||
"/assets/js/app.js": "/assets/js/app.js?id=36ab3529ebffd4f0624b",
|
"/assets/js/app.js": "/assets/js/app.js?id=a9f802b3fe774e87bf0c",
|
||||||
"/assets/css/crater.css": "/assets/css/crater.css?id=108e3a8d009e7d38018c"
|
"/assets/css/crater.css": "/assets/css/crater.css?id=193e5770a0e7a8604f35"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,7 +29,7 @@ Web Application is made using Laravel & VueJS while the Mobile Apps are built us
|
|||||||
|
|
||||||
## Mobile Apps
|
## Mobile Apps
|
||||||
- [Android](https://play.google.com/store/apps/details?id=com.craterapp.app)
|
- [Android](https://play.google.com/store/apps/details?id=com.craterapp.app)
|
||||||
- IOS - Coming Soon
|
- [IOS](https://apps.apple.com/app/id1489169767)
|
||||||
- [Source](https://github.com/bytefury/crater-mobile)
|
- [Source](https://github.com/bytefury/crater-mobile)
|
||||||
|
|
||||||
## Discord
|
## Discord
|
||||||
@ -62,7 +62,7 @@ Crater is a product of [Bytefury](https://bytefury.com)
|
|||||||
|
|
||||||
**Special thanks to:**
|
**Special thanks to:**
|
||||||
* [Birkhoff Lee](https://github.com/BirkhoffLee)
|
* [Birkhoff Lee](https://github.com/BirkhoffLee)
|
||||||
|
* [Hassan A. Ba Abdullah](https://github.com/hsnapps)
|
||||||
|
|
||||||
## Translate
|
## Translate
|
||||||
Help us translate on [Transifex](https://www.transifex.com/bytefury/crater-invoice)
|
Help us translate on [Transifex](https://www.transifex.com/bytefury/crater-invoice)
|
||||||
|
|||||||
71
resources/assets/js/components/base/BasePrefixInput.vue
Normal file
71
resources/assets/js/components/base/BasePrefixInput.vue
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<template>
|
||||||
|
<div class="base-prefix-input" @click="focusInput">
|
||||||
|
<font-awesome-icon v-if="icon" :icon="icon" class="icon" />
|
||||||
|
<p class="prefix-label"><span class="mr-1">{{ prefix }}</span>-</p>
|
||||||
|
<input
|
||||||
|
ref="basePrefixInput"
|
||||||
|
v-model="inputValue"
|
||||||
|
:type="type"
|
||||||
|
class="prefix-input-field"
|
||||||
|
@input="handleInput"
|
||||||
|
@change="handleChange"
|
||||||
|
@keyup="handleKeyupEnter"
|
||||||
|
@keydown="handleKeyDownEnter"
|
||||||
|
@blur="handleFocusOut"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
prefix: {
|
||||||
|
type: String,
|
||||||
|
default: null,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: [String, Number, File],
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'text'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
inputValue: this.value
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'value' () {
|
||||||
|
this.inputValue = this.value
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
focusInput () {
|
||||||
|
this.$refs.basePrefixInput.focus()
|
||||||
|
},
|
||||||
|
handleInput (e) {
|
||||||
|
this.$emit('input', this.inputValue)
|
||||||
|
},
|
||||||
|
handleChange (e) {
|
||||||
|
this.$emit('change', this.inputValue)
|
||||||
|
},
|
||||||
|
handleKeyupEnter (e) {
|
||||||
|
this.$emit('keyup', this.inputValue)
|
||||||
|
},
|
||||||
|
handleKeyDownEnter (e) {
|
||||||
|
this.$emit('keydown', e, this.inputValue)
|
||||||
|
},
|
||||||
|
handleFocusOut (e) {
|
||||||
|
this.$emit('blur', this.inputValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@ -8,6 +8,7 @@ import BaseTextArea from './BaseTextArea.vue'
|
|||||||
import BaseSelect from './base-select/BaseSelect.vue'
|
import BaseSelect from './base-select/BaseSelect.vue'
|
||||||
import BaseLoader from './BaseLoader.vue'
|
import BaseLoader from './BaseLoader.vue'
|
||||||
import BaseCustomerSelect from './BaseCustomerSelect.vue'
|
import BaseCustomerSelect from './BaseCustomerSelect.vue'
|
||||||
|
import BasePrefixInput from './BasePrefixInput.vue'
|
||||||
|
|
||||||
import BasePopup from './popup/BasePopup.vue'
|
import BasePopup from './popup/BasePopup.vue'
|
||||||
import CustomerSelectPopup from './popup/CustomerSelectPopup.vue'
|
import CustomerSelectPopup from './popup/CustomerSelectPopup.vue'
|
||||||
@ -23,6 +24,7 @@ Vue.component('base-input', BaseInput)
|
|||||||
Vue.component('base-switch', BaseSwitch)
|
Vue.component('base-switch', BaseSwitch)
|
||||||
Vue.component('base-text-area', BaseTextArea)
|
Vue.component('base-text-area', BaseTextArea)
|
||||||
Vue.component('base-loader', BaseLoader)
|
Vue.component('base-loader', BaseLoader)
|
||||||
|
Vue.component('base-prefix-input', BasePrefixInput)
|
||||||
|
|
||||||
Vue.component('table-component', TableComponent)
|
Vue.component('table-component', TableComponent)
|
||||||
Vue.component('table-column', TableColumn)
|
Vue.component('table-column', TableColumn)
|
||||||
|
|||||||
@ -55,6 +55,7 @@
|
|||||||
v-model="currency"
|
v-model="currency"
|
||||||
:options="currencies"
|
:options="currencies"
|
||||||
:searchable="true"
|
:searchable="true"
|
||||||
|
:allow-empty="false"
|
||||||
:show-labels="false"
|
:show-labels="false"
|
||||||
:placeholder="$t('customers.select_currency')"
|
:placeholder="$t('customers.select_currency')"
|
||||||
label="name"
|
label="name"
|
||||||
|
|||||||
@ -124,7 +124,7 @@ export default {
|
|||||||
},
|
},
|
||||||
percent: {
|
percent: {
|
||||||
required,
|
required,
|
||||||
between: between(0.10, 100)
|
between: between(0, 100)
|
||||||
},
|
},
|
||||||
description: {
|
description: {
|
||||||
maxLength: maxLength(255)
|
maxLength: maxLength(255)
|
||||||
|
|||||||
880
resources/assets/js/plugins/ar.js
Normal file
880
resources/assets/js/plugins/ar.js
Normal file
@ -0,0 +1,880 @@
|
|||||||
|
{
|
||||||
|
"navigation": {
|
||||||
|
"dashboard": "الرئيسية",
|
||||||
|
"customers": "العملاء",
|
||||||
|
"items": "الأصناف",
|
||||||
|
"invoices": "الفواتير",
|
||||||
|
"expenses": "النفقات",
|
||||||
|
"estimates": "التقديرات",
|
||||||
|
"payments": "المدفوعات",
|
||||||
|
"reports": "التقارير",
|
||||||
|
"settings": "الإعدادات",
|
||||||
|
"logout": "خروج"
|
||||||
|
},
|
||||||
|
"general": {
|
||||||
|
"view_pdf": "عرض PDF",
|
||||||
|
"download_pdf": "تنزيل PDF",
|
||||||
|
"save": "حفظ",
|
||||||
|
"cancel": "إلغاء الأمر",
|
||||||
|
"update": "تحديث",
|
||||||
|
"download": "تنزيل",
|
||||||
|
"from_date": "من تاريخ",
|
||||||
|
"to_date": "إلى تاريخ",
|
||||||
|
"from": "من",
|
||||||
|
"to": "إلى",
|
||||||
|
"go_back": "إلى الخلف",
|
||||||
|
"back_to_login": "العودة إلى تسجيل الدخول؟",
|
||||||
|
"home": "الرئيسية",
|
||||||
|
"filter": "تصفية",
|
||||||
|
"delete": "حذف",
|
||||||
|
"edit": "تعديل",
|
||||||
|
"view": "عرض",
|
||||||
|
"add_new_item": "إضافة صنف جديد",
|
||||||
|
"clear_all": "مسح الكل",
|
||||||
|
"showing": "عرض",
|
||||||
|
"of": "من",
|
||||||
|
"actions": "العمليات",
|
||||||
|
"subtotal": "المجموع الفرعي",
|
||||||
|
"discount": "خصم",
|
||||||
|
"fixed": "ثابت",
|
||||||
|
"percentage": "نسبة",
|
||||||
|
"tax": "ضريبة",
|
||||||
|
"total_amount": "المبلغ الإجمالي",
|
||||||
|
"bill_to": "مطلوب من",
|
||||||
|
"ship_to": "يشحن إلى",
|
||||||
|
"due": "واجبة السداد",
|
||||||
|
"draft": "مسودة",
|
||||||
|
"sent": "مرسلة",
|
||||||
|
"all": "الكل",
|
||||||
|
"select_all": "تحديد الل",
|
||||||
|
"choose_file": "اضغط هنا لاختيار ملف",
|
||||||
|
"choose_template": "اختيار القالب",
|
||||||
|
"choose": "اختر",
|
||||||
|
"remove": "إزالة",
|
||||||
|
"powered_by": "تصميم",
|
||||||
|
"bytefury": "باترفوري",
|
||||||
|
"select_a_status": "اختر الحالة",
|
||||||
|
"select_a_tax": "اختر الضريبة",
|
||||||
|
"search": "بحث",
|
||||||
|
"are_you_sure": "هل أنت متأكد?",
|
||||||
|
"list_is_empty": "القائمة فارغة.",
|
||||||
|
"no_tax_found": "لا يوجد ضريبة!",
|
||||||
|
"four_zero_four": "404",
|
||||||
|
"you_got_lost": "عفواً! يبدو أنك قد تهت!",
|
||||||
|
"go_home": "عودة إلى الرئيسية",
|
||||||
|
|
||||||
|
"setting_updated": "تم تحديث الإعدادات بنجاح",
|
||||||
|
"select_state": "اختر الولاية/المنطقة",
|
||||||
|
"select_country": "اختر الدولة",
|
||||||
|
"select_city": "اختر المدينة",
|
||||||
|
"street_1": "عنوان الشارع 1",
|
||||||
|
"street_2": "عنوان الشارع 2",
|
||||||
|
"action_failed": "فشلت العملية"
|
||||||
|
},
|
||||||
|
"dashboard": {
|
||||||
|
"select_year": "اختر السنة",
|
||||||
|
"cards": {
|
||||||
|
"due_amount": "المبلغ المطلوب",
|
||||||
|
"customers": "العملاء",
|
||||||
|
"invoices": "الفواتير",
|
||||||
|
"estimates": "التقديرات"
|
||||||
|
},
|
||||||
|
"chart_info": {
|
||||||
|
"total_sales": "المبيعات",
|
||||||
|
"total_receipts": "إجمالي الدخل",
|
||||||
|
"total_expense": "النفقات",
|
||||||
|
"net_income": "صافي الدخل",
|
||||||
|
"year": "اختر السنة"
|
||||||
|
},
|
||||||
|
"weekly_invoices": {
|
||||||
|
"title": "الفواتير الأسبوعية"
|
||||||
|
},
|
||||||
|
"monthly_chart": {
|
||||||
|
"title": "المبيعات والنفقات"
|
||||||
|
},
|
||||||
|
"recent_invoices_card": {
|
||||||
|
"title": "فواتير مستحقة",
|
||||||
|
"due_on": "مستحقة في",
|
||||||
|
"customer": "العميل",
|
||||||
|
"amount_due": "المبلغ المطلوب",
|
||||||
|
"actions": "العمليات",
|
||||||
|
"view_all": "عرض الكل"
|
||||||
|
},
|
||||||
|
"recent_estimate_card": {
|
||||||
|
"title": "أحدث التقديرات",
|
||||||
|
"date": "التاريخ",
|
||||||
|
"customer": "العميل",
|
||||||
|
"amount_due": "المبلغ المطلوب",
|
||||||
|
"actions": "العمليات",
|
||||||
|
"view_all": "عرض الكل"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tax_types": {
|
||||||
|
"name": "الاسم",
|
||||||
|
"description": "الوصف",
|
||||||
|
"percent": "Percent",
|
||||||
|
"compound_tax": "Compound Tax"
|
||||||
|
},
|
||||||
|
"customers": {
|
||||||
|
"title": "العملاء",
|
||||||
|
"add_customer": "إضافة عميل",
|
||||||
|
"contacts_list": "قائمة العملاء",
|
||||||
|
"name": "الاسم",
|
||||||
|
"display_name": "اسم العرض",
|
||||||
|
"primary_contact_name": "اسم التواصل الرئيسي",
|
||||||
|
"contact_name": "اسم تواصل آخر",
|
||||||
|
"amount_due": "المبلغ المطلوب",
|
||||||
|
"email": "البريد الإلكتروني",
|
||||||
|
"address": "العنوان",
|
||||||
|
"phone": "الهاتف",
|
||||||
|
"website": "موقع الإنترنت",
|
||||||
|
"country": "الدولة",
|
||||||
|
"state": "الولاية/المنطقة",
|
||||||
|
"city": "المدينة",
|
||||||
|
"zip_code": "الرمز البريدي",
|
||||||
|
"added_on": "أضيف في",
|
||||||
|
"action": "إجراء",
|
||||||
|
"password": "كلمة المرور",
|
||||||
|
"street_number": "رقم الشارع",
|
||||||
|
"primary_currency": "العملة الرئيسية",
|
||||||
|
"add_new_customer": "إضافة عميل جديد",
|
||||||
|
"save_customer": "حفظ العميل",
|
||||||
|
"update_customer": "تحديث بيانات العميل",
|
||||||
|
"customer": "عميل | عملاء",
|
||||||
|
"new_customer": "عميل جديد",
|
||||||
|
"edit_customer": "تعديل عميل",
|
||||||
|
"basic_info": "معلوات أساسية",
|
||||||
|
"billing_address": "عنوان الفوترة",
|
||||||
|
"shipping_address": "عنوان الشحن",
|
||||||
|
"copy_billing_address": "نسخ من عنوان الفوترة",
|
||||||
|
"no_customers": "لا يوجد عملاء حتى الآن!",
|
||||||
|
"no_customers_found": "لم يتم الحصول على عملاء!",
|
||||||
|
"list_of_customers": "سوف يحتوي هذا القسم على قائمة العملاء.",
|
||||||
|
"primary_display_name": "اسم العرض الرئيسي",
|
||||||
|
"select_currency": "اختر العملة",
|
||||||
|
"select_a_customer": "اختر العميل",
|
||||||
|
"type_or_click": "اكتب أو اضغط للاختيار",
|
||||||
|
|
||||||
|
"confirm_delete": "لن تكون قادراً على استرجاع هذا العميل | لن تكون قادراً على استرجاع هؤلاء العملاء",
|
||||||
|
"created_message": "تم إنشاء العملاء بنجاح",
|
||||||
|
"updated_message": "تم تحديث العملاء بنجاح",
|
||||||
|
"deleted_message": "تم حذف العملاء بنجاح | تم حذف العميل بنجاح"
|
||||||
|
},
|
||||||
|
"items": {
|
||||||
|
"title": "الأصناف",
|
||||||
|
"items_list": "قائمة الأصناف",
|
||||||
|
"name": "الاسم",
|
||||||
|
"unit": "الوحدة",
|
||||||
|
"description": "الوصف",
|
||||||
|
"added_on": "أضيف في",
|
||||||
|
"price": "السعر",
|
||||||
|
"date_of_creation": "تاريخ الإنشاء",
|
||||||
|
"action": "إجراء",
|
||||||
|
"add_item": "إضافة صنف",
|
||||||
|
"save_item": "حفظ الصنف",
|
||||||
|
"update_item": "تحديث الصنف",
|
||||||
|
"item": "صنف | أصناف",
|
||||||
|
"add_new_item": "إضافة صنف جديد",
|
||||||
|
"new_item": "جديد صنف",
|
||||||
|
"edit_item": "تحديث صنف",
|
||||||
|
"no_items": "لا يوجد أصناف حتى الآن!",
|
||||||
|
"list_of_items": "هذا القسم سوف يحتوي على قائمة الأصناف.",
|
||||||
|
"select_a_unit": "اختر الوحدة",
|
||||||
|
|
||||||
|
"item_attached_message": "لا يمكن حذف الصنف قيد الاستخدام",
|
||||||
|
"confirm_delete": "لن تتمكن من استرجاع هذا الصنف | لن تتمكن من استرجاع هذه الأصناف",
|
||||||
|
"created_message": "تم إنشاء الصنف بنجاح",
|
||||||
|
"updated_message": "تم تحديث الصنف بنجاح",
|
||||||
|
"deleted_message": "تم حذف الصنف بنجاح | تم حذف الأصناف بنجاح"
|
||||||
|
},
|
||||||
|
"estimates": {
|
||||||
|
"title": "التقديرات",
|
||||||
|
"estimate": "تقدير | تقديرات",
|
||||||
|
"estimates_list": "قائمة التقديرات",
|
||||||
|
"days": "{days} أيام",
|
||||||
|
"months": "{months} أشهر",
|
||||||
|
"years": "{years} سنوات",
|
||||||
|
"all": "الكل",
|
||||||
|
"paid": "مدفوع",
|
||||||
|
"unpaid": "غير مدفوع",
|
||||||
|
"customer": "العميل",
|
||||||
|
"ref_no": "رقم المرجع.",
|
||||||
|
"number": "الرقم",
|
||||||
|
"amount_due": "المبلغ المطلوب",
|
||||||
|
"partially_paid": "مدفوع جزئيا",
|
||||||
|
"total": "الإجمالي",
|
||||||
|
"discount": "الخصم",
|
||||||
|
"sub_total": "حاصل الجمع",
|
||||||
|
"estimate_number": "رقم تقدير",
|
||||||
|
"ref_number": "رقم المرجع",
|
||||||
|
"contact": "تواصل",
|
||||||
|
"add_item": "إضافة صنف",
|
||||||
|
"date": "تاريخ",
|
||||||
|
"due_date": "تاريخ الاستحقاق",
|
||||||
|
"expiry_date": "تاريخ الصلاحية",
|
||||||
|
"status": "الحالة",
|
||||||
|
"add_tax": "إضافة ضرية",
|
||||||
|
"amount": "المبلغ المطلوب",
|
||||||
|
"action": "إجراء",
|
||||||
|
"notes": "ملاحظات",
|
||||||
|
"tax": "ضريبة",
|
||||||
|
"estimate_template": "قالب",
|
||||||
|
"convert_to_invoice": "تحويل إلى فاتورة",
|
||||||
|
"mark_as_sent": "تحديد كمرسل",
|
||||||
|
"send_estimate": "إرسال التقدير",
|
||||||
|
"record_payment": "تسجيل مدفوات",
|
||||||
|
"add_estimate": "إضافة تقدير",
|
||||||
|
"save_estimate": "حفظ التقدير",
|
||||||
|
"confirm_conversion": "هل تريد تحويل هذا التقدير إلى فاتورة؟",
|
||||||
|
"conversion_message": "تم إنشاء الفاتورة بنجاح",
|
||||||
|
"confirm_send_estimate": "سيتم إرسال هذا التقدير بالبريد الإلكتروني إلى العميل",
|
||||||
|
"confirm_mark_as_sent": "سيتم التحديد كمرسل على هذا التقدير",
|
||||||
|
"confirm_mark_as_accepted": "سيتم التحديد كمقبول على هذا التقدير",
|
||||||
|
"confirm_mark_as_rejected": "سيتم التحديد كمرفوض على هذا التقدير",
|
||||||
|
"no_matching_estimates": "لا يوجد تقديرات مطابقة!",
|
||||||
|
"mark_as_sent_successfully": "تم التحديد كمرسل بنجاح",
|
||||||
|
"send_estimate_successfully": "تم إرسال التقدير بنجاح",
|
||||||
|
"errors": {
|
||||||
|
"required": "حقل مطلوب"
|
||||||
|
},
|
||||||
|
"accepted": "مقبول",
|
||||||
|
"sent": "مرسل",
|
||||||
|
"draft": "مسودة",
|
||||||
|
"declined": "مرفوض",
|
||||||
|
"new_estimate": "تقدير جديد",
|
||||||
|
"add_new_estimate": "إضافة تقدير جديد",
|
||||||
|
"update_Estimate": "تحديث تقدير",
|
||||||
|
"edit_estimate": "تعديل التقدير",
|
||||||
|
"items": "الأصناف",
|
||||||
|
"Estimate": "تقدير | تقديرات",
|
||||||
|
"add_new_tax": "إضافة ضريبة جديدة",
|
||||||
|
"no_estimates": "لا يوجد تقديرات حالياً!",
|
||||||
|
"list_of_estimates": "هذا القسم سوف يحتوي على التقديرات.",
|
||||||
|
"mark_as_rejected": "تحديد كمرفوض",
|
||||||
|
"mark_as_accepted": "تحديد كمقروء",
|
||||||
|
|
||||||
|
"marked_as_accepted_message": "تحديد التقدير كمقبول",
|
||||||
|
"marked_as_rejected_message": "تحديد التقدير كمرفوض",
|
||||||
|
"confirm_delete": "لن تستطيع استرجاع هذا التقدير | لن تستطيع إستعادة هذه التقديرات",
|
||||||
|
"created_message": "تم إنشاء التقدير بنجاح",
|
||||||
|
"updated_message": "تم تحديث التقدير بنجاح",
|
||||||
|
"deleted_message": "تم حذف التقدير بنجاح | تم حذف التقديرات بنجاح",
|
||||||
|
"user_email_does_not_exist": "البريد الالكتروني للمستخدم غير موجود",
|
||||||
|
"something_went_wrong": "خطأ غير معروف!",
|
||||||
|
"item": {
|
||||||
|
"title": "اسم الصنف",
|
||||||
|
"description": "الوصف",
|
||||||
|
"quantity": "الكمية",
|
||||||
|
"price": "السعر",
|
||||||
|
"discount": "الخصم",
|
||||||
|
"total": "الإجمالي",
|
||||||
|
"total_discount": "مجموع الخصم",
|
||||||
|
"sub_total": "حاصل الجمع",
|
||||||
|
"tax": "الضرية",
|
||||||
|
"amount": "المبلغ المطلوب",
|
||||||
|
"select_an_item": "اكتب أو اختر الصنف",
|
||||||
|
"type_item_description": "اكتب وصف الصنف (اختياري)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"invoices": {
|
||||||
|
"title": "الفواتير",
|
||||||
|
"invoices_list": "قائمة الفواتير",
|
||||||
|
"days": "{days} أيام",
|
||||||
|
"months": "{months} أشهر",
|
||||||
|
"years": "{years} سنوات",
|
||||||
|
"all": "الكل",
|
||||||
|
"paid": "مدفوع",
|
||||||
|
"unpaid": "غير مدفوع",
|
||||||
|
"customer": "العميل",
|
||||||
|
"paid_status": "حالة الدفع",
|
||||||
|
"ref_no": "رقم المرجع.",
|
||||||
|
"number": "الرقم",
|
||||||
|
"amount_due": "المبلغ المطلوب",
|
||||||
|
"partially_paid": "مدفوع جزئياً",
|
||||||
|
"total": "الإجمالي",
|
||||||
|
"discount": "الخصم",
|
||||||
|
"sub_total": "حاصل الجمع",
|
||||||
|
"invoice": "فاتورة | فواتير",
|
||||||
|
"invoice_number": "رقم الفاتورة",
|
||||||
|
"ref_number": "رقم المرجع",
|
||||||
|
"contact": "تواصل",
|
||||||
|
"add_item": "إضافة صنف",
|
||||||
|
"date": "التاريخ",
|
||||||
|
"due_date": "تاريخ الاستحقاق",
|
||||||
|
"status": "الحالة",
|
||||||
|
"add_tax": "إضافة ضريبة",
|
||||||
|
"amount": "المبلغ المطلوب",
|
||||||
|
"action": "إجراء",
|
||||||
|
"notes": "ملاحظات",
|
||||||
|
"view": "عرض",
|
||||||
|
"send_invoice": "إرسال الفاتورة",
|
||||||
|
"invoice_template": "قالب الفاتورة",
|
||||||
|
"template": "قالب",
|
||||||
|
"mark_as_sent": "تحديد كمرسل",
|
||||||
|
"confirm_send_invoice": "سيتم إرسال هذه الفاتورة بالبريد الألكتروني إلى العميل",
|
||||||
|
"invoice_mark_as_sent": "سيتم تحديد هذه الفاتورة كمرسلة",
|
||||||
|
"confirm_send": "سيتم إرسال هذه الفاتورة بالبريد الألكتروني إلى العميل",
|
||||||
|
"invoice_date": "تاريخ الفاتورة",
|
||||||
|
"record_payment": "تسجيل مدفوعات",
|
||||||
|
"add_new_invoice": "إضافة فاتورة جديدة",
|
||||||
|
"update_expense": "تحديث المصروفات",
|
||||||
|
"edit_invoice": "تعديل الفاتورة",
|
||||||
|
"new_invoice": "فاتورة جديدة",
|
||||||
|
"save_invoice": "حفظ الفاتورة",
|
||||||
|
"update_invoice": "تحديث الفاتورة",
|
||||||
|
"add_new_tax": "إضافة ضريبة جديدة",
|
||||||
|
"no_invoices": "لا يوجد فواتير حتى الآن!",
|
||||||
|
"list_of_invoices": "قائمة الفواتير .",
|
||||||
|
"select_invoice": "اختر الفاتورة",
|
||||||
|
"no_matching_invoices": "لا يوجد فواتير مطابقة!",
|
||||||
|
"mark_as_sent_successfully": "تم تحديد الفاتورة كمرسلة بنجاح",
|
||||||
|
"send_invoice_successfully": "تم إرسال الفاتورة بنجاح",
|
||||||
|
"item": {
|
||||||
|
"title": "اسم الصنف",
|
||||||
|
"description": "الوصف",
|
||||||
|
"quantity": "الكمية",
|
||||||
|
"price": "السعر",
|
||||||
|
"discount": "الخصم",
|
||||||
|
"total": "الإجمالي",
|
||||||
|
"total_discount": "إجمالي الخصم",
|
||||||
|
"sub_total": "حاصل الجمع",
|
||||||
|
"tax": "الضريبة",
|
||||||
|
"amount": "المبلغ المطلوب",
|
||||||
|
"select_an_item": "اكتب أو انقر لاختيار صنف",
|
||||||
|
"type_item_description": "وصف الصنف (اختياري)"
|
||||||
|
},
|
||||||
|
|
||||||
|
"payment_attached_message": "هناك مدفوعات مرتبطة بالفعل بإحدى الفواتير المحددة. تأكد من حذف المدفوعات المرتبطة أولاً قبل حذف الفاتورة.",
|
||||||
|
"confirm_delete": "لن تتمكن من استرجاع الفاتورة بعد هذه الإجراء | لن تتمكن من استرجاع الفواتير بعد هذا الإجراء",
|
||||||
|
"created_message": "تم إنشاء الفاتورة بنجاح",
|
||||||
|
"updated_message": "تم تحديث الفاتورة بنجاح",
|
||||||
|
"deleted_message": "تم حذف الفاتورة بنجاح | تم حذف الفواتير بنجاح",
|
||||||
|
"marked_as_sent_message": "تم إرسال الفاتورة بنجاح",
|
||||||
|
"user_email_does_not_exist": "البريد الإلكتروني للمستخدم غير موجود!",
|
||||||
|
"something_went_wrong": "خطأ غير معروف!",
|
||||||
|
"invalid_due_amount_message": "المبلغ النهائي للفاتورة لا يمكن أن يكون أقل من المبلغ المطلوب لها. رجاءاً حدث الفاتورة أو قم بحذف المدفوعات المرتبطة بها للاستمرار."
|
||||||
|
},
|
||||||
|
"credit_notes": {
|
||||||
|
"title": "ملاحظات إئتمانية",
|
||||||
|
"credit_notes_list": "قائمة الملاحظات الإئتمانية",
|
||||||
|
"credit_notes": "ملاحظات إئتمانية",
|
||||||
|
"contact": "تواصل",
|
||||||
|
"date": "التاريخ",
|
||||||
|
"amount": "المبلغ المطلوب",
|
||||||
|
"action": "إجراء",
|
||||||
|
"credit_number": "الرقم الإئتماني",
|
||||||
|
"notes": "ملاحظات",
|
||||||
|
"confirm_delete": "هل تريد حفذف هذه الملاحظة الإئتمانية؟",
|
||||||
|
"item": {
|
||||||
|
"title": "اسم الصنف",
|
||||||
|
"description": "الوصف",
|
||||||
|
"quantity": "الكمية",
|
||||||
|
"price": "السعر",
|
||||||
|
"discount": "الخصم",
|
||||||
|
"total": "الإجمالي",
|
||||||
|
"total_discount": "إجمالي الخصم",
|
||||||
|
"sub_total": "حاصل الجمع",
|
||||||
|
"tax": "الضريبة"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"payments": {
|
||||||
|
"title": "المدفوعات",
|
||||||
|
"payments_list": "قائمة المدفوعات",
|
||||||
|
"record_payment": "تسجيل دفعة",
|
||||||
|
"customer": "العميل",
|
||||||
|
"date": "التاريخ",
|
||||||
|
"amount": "المبلغ المطلوب",
|
||||||
|
"action": "إجراء",
|
||||||
|
"payment_number": "رقم الدفعة",
|
||||||
|
"payment_mode": "نوع الدفعة",
|
||||||
|
"invoice": "الفاتورة",
|
||||||
|
"note": "ملاحظة",
|
||||||
|
"add_payment": "إضافة دفعة",
|
||||||
|
"new_payment": "دفعة جديدة",
|
||||||
|
"edit_payment": "تعديل الدفعة",
|
||||||
|
"view_payment": "عرض الدفعة",
|
||||||
|
"add_new_payment": "إضافة دفعة جديدة",
|
||||||
|
"save_payment": "حفظ الدفعة",
|
||||||
|
"update_payment": "تحديث الدفعة",
|
||||||
|
"payment": "دفعة | مدفوعات",
|
||||||
|
"no_payments": "لا يوجد مدفوعات حتى الآن!",
|
||||||
|
"list_of_payments": "سوف تحتوي هذه القائمة على مدفوعات الفواتير.",
|
||||||
|
"select_payment_mode": "اختر طريقة الدفع",
|
||||||
|
|
||||||
|
"confirm_delete": "لن تكون قادر على استرجاع هذه الدفعة | لن تكون قادراً على استرجاع هذه المدفوعات",
|
||||||
|
"created_message": "تم إنشاء الدفعة بنجاح",
|
||||||
|
"updated_message": "تم تحديث الدفعة بنجاح",
|
||||||
|
"deleted_message": "تم حذف الدفعة بنجاح | تم حذف المدفوعات بنجاح",
|
||||||
|
"invalid_amount_message": "قيمة الدفعة غير صحيحة!"
|
||||||
|
},
|
||||||
|
"expenses": {
|
||||||
|
"title": "النفقات",
|
||||||
|
"expenses_list": "قائمة النفقات",
|
||||||
|
"expense_title": "Title",
|
||||||
|
"contact": "تواصل",
|
||||||
|
"category": "الفئة",
|
||||||
|
"from_date": "من تاريخ",
|
||||||
|
"to_date": "حتى تاريخ",
|
||||||
|
"expense_date": "التاريخ",
|
||||||
|
"description": "الوصف",
|
||||||
|
"receipt": "سند القبض",
|
||||||
|
"amount": "المبلغ المطلوب",
|
||||||
|
"action": "إجراء",
|
||||||
|
"note": "ملاحظة",
|
||||||
|
"category_id": "رمز الفئة",
|
||||||
|
"date": "تاريخ النفقات",
|
||||||
|
"add_expense": "أضف نفقات",
|
||||||
|
"add_new_expense": "أضف نفقات جديدة",
|
||||||
|
"save_expense": "حفظ النفقات",
|
||||||
|
"update_expense": "تحديث النفقات",
|
||||||
|
"download_receipt": "تنزيل السند",
|
||||||
|
"edit_expense": "تعديل النفقات",
|
||||||
|
"new_expense": "نفقات جديدة",
|
||||||
|
"expense": "إنفاق | نفقات",
|
||||||
|
"no_expenses": "لا يوجد نفقات حتى الآن!",
|
||||||
|
"list_of_expenses": "هذه القائمة ستحتوي النفقات الخاصة بك",
|
||||||
|
|
||||||
|
"confirm_delete": "لن تتمكن من استرجاع هذا الإنفاق | لن تتمكن من استرجاع هذه النفقات",
|
||||||
|
"created_message": "تم إنشاء النفقات بنجاح",
|
||||||
|
"updated_message": "تم تحديث النفقات بنجاح",
|
||||||
|
"deleted_message": "تم حذف النفقات بنجاح",
|
||||||
|
"categories": {
|
||||||
|
"categories_list": "قائمة الفئات",
|
||||||
|
"title": "العنوان",
|
||||||
|
"name": "الاسم",
|
||||||
|
"description": "الوصف",
|
||||||
|
"amount": "المبلغ المطلوب",
|
||||||
|
"actions": "العمليات",
|
||||||
|
"add_category": "إضافة فئمة",
|
||||||
|
"new_category": "فئة جديدة",
|
||||||
|
"category": "فئة | فئات",
|
||||||
|
"select_a_category": "اختر الفئة"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"login": {
|
||||||
|
"email": "البريد الإلكتروني",
|
||||||
|
"password": "كلمة المرور",
|
||||||
|
"forgot_password": "نسيت كلمة المرور؟",
|
||||||
|
"or_signIn_with": "أو سجل الدخول بواسطة",
|
||||||
|
"login": "دخول",
|
||||||
|
"register": "تسجيل",
|
||||||
|
"reset_password": "إعادة تعيين كلمة المرور",
|
||||||
|
"password_reset_successfully": "تم إعادة تعيين كلمة المرور بنجاح",
|
||||||
|
"enter_email": "أدخل البريد الالكتروني",
|
||||||
|
"enter_password": "أكتب كلمة المرور",
|
||||||
|
"retype_password": "أعد كتابة كلمة المرور",
|
||||||
|
"login_placeholder": "mail@example.com"
|
||||||
|
},
|
||||||
|
"reports": {
|
||||||
|
"title": "تقرير",
|
||||||
|
"from_date": "من تاريخ",
|
||||||
|
"to_date": "حتى تاريخ",
|
||||||
|
"status": "الحالة",
|
||||||
|
"paid": "مدفوع",
|
||||||
|
"unpaid": "غير مدفوع",
|
||||||
|
"download_pdf": "تنزيل PDF",
|
||||||
|
"view_pdf": "عرض PDF",
|
||||||
|
"update_report": "تحديث التقرير",
|
||||||
|
"report": "تقرير | تقارير",
|
||||||
|
"profit_loss": {
|
||||||
|
"profit_loss": "الخسائر والأرباح",
|
||||||
|
"to_date": "حتى تاريخ",
|
||||||
|
"from_date": "من تاريخ",
|
||||||
|
"date_range": "اختر مدى التاريخ"
|
||||||
|
},
|
||||||
|
"sales": {
|
||||||
|
"sales": "المبيعات",
|
||||||
|
"date_range": "اختر مدى التاريخ",
|
||||||
|
"to_date": "حتى تاريخ",
|
||||||
|
"from_date": "من تاريخ",
|
||||||
|
"report_type": "نوع التقرير"
|
||||||
|
},
|
||||||
|
"taxes": {
|
||||||
|
"taxes": "الضرائب",
|
||||||
|
"to_date": "حتى تاريخ",
|
||||||
|
"from_date": "من تاريخ",
|
||||||
|
"date_range": "اختر مدى التاريخ"
|
||||||
|
},
|
||||||
|
"errors": {
|
||||||
|
"required": "حقل مطلوب"
|
||||||
|
},
|
||||||
|
"invoices": {
|
||||||
|
"invoice": "الفاتورة",
|
||||||
|
"invoice_date": "تاريخ الفاتورة",
|
||||||
|
"due_date": "تاريخ الاستحقاق",
|
||||||
|
"amount": "المبلغ المطلوب",
|
||||||
|
"contact_name": "اسم التواصل",
|
||||||
|
"status": "الحالة"
|
||||||
|
},
|
||||||
|
"estimates": {
|
||||||
|
"estimate": "تقدير",
|
||||||
|
"estimate_date": "تاريخ التقدير",
|
||||||
|
"due_date": "مستحق بتاريخ",
|
||||||
|
"estimate_number": "رقم مستحق",
|
||||||
|
"ref_number": "رقم المرجع",
|
||||||
|
"amount": "المبلغ المطلوب",
|
||||||
|
"contact_name": "اسم التواصل",
|
||||||
|
"status": "الحالة"
|
||||||
|
},
|
||||||
|
"expenses": {
|
||||||
|
"expenses": "النفقات",
|
||||||
|
"category": "الفئة",
|
||||||
|
"date": "التاريخ",
|
||||||
|
"amount": "المبلغ المطلوب",
|
||||||
|
"to_date": "حتى تاريخ",
|
||||||
|
"from_date": "من تاريخ",
|
||||||
|
"date_range": "اختر مدى التاريخ"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"menu_title": {
|
||||||
|
"account_settings": "إعدادات الحساب",
|
||||||
|
"company_information": "معلومات المنشأة",
|
||||||
|
"customization": "تخصيص",
|
||||||
|
"preferences": "تفضيلات",
|
||||||
|
"notifications": "تنبيهات",
|
||||||
|
"tax_types": "نوع الضريبة",
|
||||||
|
"expense_category": "فئات النفقات",
|
||||||
|
"update_app": "تحديث النظام"
|
||||||
|
},
|
||||||
|
"title": "إعدادات",
|
||||||
|
"setting": "إعدادات | إعدادات",
|
||||||
|
"general": "عام",
|
||||||
|
"language": "اللغة",
|
||||||
|
"primary_currency": "العملة الرئيسية",
|
||||||
|
"timezone": "المنطقة الزمنية",
|
||||||
|
"date_format": "صيغة التاريخ",
|
||||||
|
"currencies": {
|
||||||
|
"title": "العملات",
|
||||||
|
"currency": "العملة | العملات",
|
||||||
|
"currencies_list": "قائمة العملات",
|
||||||
|
"select_currency": "اختر العملة",
|
||||||
|
"name": "الاسم",
|
||||||
|
"code": "المرجع",
|
||||||
|
"symbol": "الرمز",
|
||||||
|
"precision": "الدقة",
|
||||||
|
"thousand_separator": "فاصل الآلاف",
|
||||||
|
"decimal_separator": "الفاصلة العشرية",
|
||||||
|
"position": "الموقع",
|
||||||
|
"position_of_symbol": "موقع رمز العملة",
|
||||||
|
"right": "يمين",
|
||||||
|
"left": "يسار",
|
||||||
|
"action": "إجراء",
|
||||||
|
"add_currency": "أضف عملة"
|
||||||
|
},
|
||||||
|
"mail": {
|
||||||
|
"host": "خادم البريد",
|
||||||
|
"port": "منفذ البريد",
|
||||||
|
"driver": "مشغل البريد",
|
||||||
|
"secret": "سري",
|
||||||
|
"mailgun_secret": "الرمز السري لـ Mailgun",
|
||||||
|
"mailgun_domain": "المجال",
|
||||||
|
"mailgun_endpoint": "النهاية الطرفية لـ Mailgun",
|
||||||
|
"ses_secret": "SES الرمز السري",
|
||||||
|
"ses_key": "SES مفتاح",
|
||||||
|
"password": "كلمة مرور البريد الالكتروني",
|
||||||
|
"username": "اسم المستخدم للبريد الإلكتروني",
|
||||||
|
"mail_config": "إعدادات البريد الالكتروني",
|
||||||
|
"from_name": "اسم المرسل",
|
||||||
|
"from_mail": "عنوان البريد الالكتروني للمرسل",
|
||||||
|
"encryption": "صيغة ا لتشفير",
|
||||||
|
"mail_config_desc": "أدناه هو نموذج لتكوين برنامج تشغيل البريد الإلكتروني لإرسال رسائل البريد الإلكتروني من التطبيق. يمكنك أيضًا تهيئة موفري الجهات الخارجية مثل Sendgrid و SES إلخ."
|
||||||
|
},
|
||||||
|
"pdf": {
|
||||||
|
"title": "PDF إعدادات",
|
||||||
|
"footer_text": "نص التذييل",
|
||||||
|
"pdf_layout": "اتجاه صفحة PDF"
|
||||||
|
},
|
||||||
|
"company_info": {
|
||||||
|
"company_info": "معلومات الشركة",
|
||||||
|
"company_name": "اسم الشركة",
|
||||||
|
"company_logo": "شعار الشركة",
|
||||||
|
"section_description": "معلومات عن شركتك سيتم عرضها على الفواتير والتقديرات والمستندات الأخرى.",
|
||||||
|
"phone": "الهاتف",
|
||||||
|
"country": "الدولة",
|
||||||
|
"state": "الولاية/المنطقة",
|
||||||
|
"city": "المدينة",
|
||||||
|
"address": "العنوان",
|
||||||
|
"zip": "الرمز البريدي",
|
||||||
|
"save": "حفظ",
|
||||||
|
"updated_message": "تم تحديث معلومات الشركة بنجاح"
|
||||||
|
},
|
||||||
|
"customization": {
|
||||||
|
"customization": "التخصيص",
|
||||||
|
"save": "حفظ",
|
||||||
|
"addresses": {
|
||||||
|
"title": "العنوان",
|
||||||
|
"section_description": "يمكنك ضبط عنوان إرسال فواتير العملاء وتنسيق عنوان شحن العملاء (معروض في PDF فقط).",
|
||||||
|
"customer_billing_address": "عنوان فواتير العميل",
|
||||||
|
"customer_shipping_address": "عنوان الشحن للعميل",
|
||||||
|
"company_address": "عنوان الشركة",
|
||||||
|
"insert_fields": "أضف حقل",
|
||||||
|
"contact": "تواصل",
|
||||||
|
"address": "العنوان",
|
||||||
|
"display_name": "الاسم الظاهر",
|
||||||
|
"primary_contact_name": "مسؤول التواصل الرئيسي",
|
||||||
|
"email": "البريد الإلكتروني",
|
||||||
|
"website": "موقع الإنترنت",
|
||||||
|
"name": "الاسم",
|
||||||
|
"country": "الدولة",
|
||||||
|
"state": "الولاية/المنطقة",
|
||||||
|
"city": "المدينة",
|
||||||
|
"company_name": "اسم الشركة",
|
||||||
|
"address_street_1": "عنوان الشارع 1",
|
||||||
|
"address_street_2": "عنوان الشارع 2",
|
||||||
|
"phone": "الهاتف",
|
||||||
|
"zip_code": "الرمز البريدي",
|
||||||
|
"address_setting_updated": "تم تحديث العنوان بنجاح"
|
||||||
|
},
|
||||||
|
"updated_message": "تم تحديث معلومات الشركة بنجاح",
|
||||||
|
|
||||||
|
"invoices": {
|
||||||
|
"title": "الفواتير",
|
||||||
|
"notes": "ملاحظات",
|
||||||
|
"invoice_prefix": "بادئة رقم الفاتورة",
|
||||||
|
"invoice_settings": "إعدادات الفاتورة",
|
||||||
|
"autogenerate_invoice_number": "ترقيم آلي للفاتورة",
|
||||||
|
"invoice_setting_description": "تعطيل الترقيم الآلي ، إذا كنت لا ترغب في إنشاء أرقام الفاتورة تلقائيًا في كل مرة تقوم فيها بإنشاء فاتورة جديدة.",
|
||||||
|
"enter_invoice_prefix": "أدخل بادئة رقم الفاتورة",
|
||||||
|
"terms_and_conditions": "الأحكام والشروط",
|
||||||
|
"invoice_setting_updated": "تم تحديث إعداد الفاتورة بنجاح"
|
||||||
|
},
|
||||||
|
|
||||||
|
"estimates": {
|
||||||
|
"title": "التقديرات",
|
||||||
|
"estimate_prefix": "بادئة رقم التقدير",
|
||||||
|
"estimate_settings": "إعدادت التقدير",
|
||||||
|
"autogenerate_estimate_number": "ترقيم آلي للتقدير",
|
||||||
|
"estimate_setting_description": "تعطيل الترقيم الآلي ، إذا كنت لا ترغب في إنشاء أرقام التقديرات تلقائيًا في كل مرة تقوم فيها بإنشاء تقدير جديد.",
|
||||||
|
"enter_estimate_prefix": "أدخل بادئة رقم التقدير",
|
||||||
|
"estimate_setting_updated": "تم تحديث إعدادات التقدير بنجاح"
|
||||||
|
},
|
||||||
|
|
||||||
|
"payments": {
|
||||||
|
"title": "المدفوعات",
|
||||||
|
"payment_prefix": "بادئة رقم الدفعة",
|
||||||
|
"payment_settings": "إعدادات الدفعة",
|
||||||
|
"autogenerate_payment_number": "ترقيم آلي للمدفوعات",
|
||||||
|
"payment_setting_description": "تعطيل الترقيم الآلي ، إذا كنت لا ترغب في إنشاء أرقام الدفعة تلقائيًا في كل مرة تقوم فيها بإنشاء دفعة جديدة.",
|
||||||
|
"enter_payment_prefix": "أدخل بادئة رقم الدفعة",
|
||||||
|
"payment_setting_updated": "تم تحديث إعدادات الدفعة بنجاح"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"account_settings": {
|
||||||
|
"profile_picture": "صورة الملف الشخصي",
|
||||||
|
"name": "الاسم",
|
||||||
|
"email": "البريد الإلكتروني",
|
||||||
|
"password": "كلمة المرور",
|
||||||
|
"confirm_password": "أعد كتابة كلمة المرور",
|
||||||
|
"account_settings": "إعدادات الجساب",
|
||||||
|
"save": "حفظ",
|
||||||
|
"section_description": "يمكنك تحديث اسمك والبريد الإلكتروني وكلمة المرور باستخدام النموذج أدناه.",
|
||||||
|
"updated_message": "تم تحديث إعدادات الحساب بنجاح"
|
||||||
|
},
|
||||||
|
"user_profile": {
|
||||||
|
"name": "الاسم",
|
||||||
|
"email": "البريد الإلكتروني",
|
||||||
|
"password": "كلمة المرور",
|
||||||
|
"confirm_password": "أعد كتابة كلمة المرور"
|
||||||
|
},
|
||||||
|
"notification": {
|
||||||
|
"title": "الإشعارات",
|
||||||
|
"email": "إرسال الإشعارات إلى",
|
||||||
|
"description": "ما هي إشعارات البريد الإلكتروني التي ترغب في تلقيها عندما يتغير شيء ما؟",
|
||||||
|
"invoice_viewed": "تم عرض الفاتورة",
|
||||||
|
"invoice_viewed_desc": "عندما يستعرض عميلك الفاتورة المرسلة عبر الشاشة الرئيسية.",
|
||||||
|
"estimate_viewed": "تم عرض التقدير",
|
||||||
|
"estimate_viewed_desc": "عندما يستعرض عميلك التقدير المرسلة عبر الشاشة الرئيسية.",
|
||||||
|
"save": "حفظ",
|
||||||
|
"email_save_message": "تم حفظ البريد الإلكتروني بنجاح",
|
||||||
|
"please_enter_email": "فضلاً أدخل البريد الإلكتروني"
|
||||||
|
},
|
||||||
|
"tax_types": {
|
||||||
|
"title": "أنواع الضرائب",
|
||||||
|
"add_tax": "أضف ضريبة",
|
||||||
|
"description": "يمكنك إضافة أو إزالة الضرائب كما يحلو لك. النظام يدعم الضرائب على العناصر الفردية وكذلك على الفاتورة.",
|
||||||
|
"add_new_tax": "إضافة ضريبة جديدة",
|
||||||
|
"tax_settings": "إعدادات الضريبة",
|
||||||
|
"tax_per_item": "ضريبة على الصنف",
|
||||||
|
"tax_name": "اسم الضريبة",
|
||||||
|
"compound_tax": "ضريبة مجمعة",
|
||||||
|
"percent": "نسبة مؤوية",
|
||||||
|
"action": "إجراء",
|
||||||
|
"tax_setting_description": "قم بتمكين هذا إذا كنت تريد إضافة ضرائب لعناصر الفاتورة الفردية. بشكل افتراضي ، تضاف الضرائب مباشرة إلى الفاتورة.",
|
||||||
|
"created_message": "تم إنشاء نوع الضريبة بنجاح",
|
||||||
|
"updated_message": "تم تحديث نوع الضريبة بنجاح",
|
||||||
|
"deleted_message": "تم حذف نوع الضريبة بنجاح",
|
||||||
|
"confirm_delete": "لن تتمكن من استرجاع نوع الضرية هذا",
|
||||||
|
"already_in_use": "ضريبة قيد الاستخدام"
|
||||||
|
},
|
||||||
|
"expense_category": {
|
||||||
|
"title": "فئات النفقات",
|
||||||
|
"action": "إجراء",
|
||||||
|
"description": "الفئات مطلوبة لإضافة إدخالات النفقات. يمكنك إضافة أو إزالة هذه الفئات وفقًا لتفضيلاتك.",
|
||||||
|
"add_new_category": "إضافة فئة جديدة",
|
||||||
|
"category_name": "اسم الفئة",
|
||||||
|
"category_description": "الوصف",
|
||||||
|
"created_message": "تم إنشاء نوع النفقات بنجاح",
|
||||||
|
"deleted_message": "تم حذف نوع النفقات بنجاح",
|
||||||
|
"updated_message": "تم تحديث نوع النفقات بنجاح",
|
||||||
|
"confirm_delete": "لن تتمكن من استرجاع نوع النفقات هذا",
|
||||||
|
"already_in_use": "نوع قيد الاستخدام"
|
||||||
|
},
|
||||||
|
"preferences": {
|
||||||
|
"currency": "العملة",
|
||||||
|
"language": "اللغة",
|
||||||
|
"time_zone": "المنطة الزمنية",
|
||||||
|
"fiscal_year": "السنة المالية",
|
||||||
|
"date_format": "صيغة التاريخ",
|
||||||
|
"discount_setting": "إعدادات الخصم",
|
||||||
|
"discount_per_item": "خصم على الصنف ",
|
||||||
|
"discount_setting_description": "قم بتمكين هذا إذا كنت تريد إضافة خصم إلى عناصر الفاتورة الفردية. بشكل افتراضي ، يتم إضافة الخصم مباشرة إلى الفاتورة.",
|
||||||
|
"save": "حفظ",
|
||||||
|
"preference": "تفضيل | تفضيلات",
|
||||||
|
"general_settings": "التفضيلات الافتراضية للنظام.",
|
||||||
|
"updated_message": "تم تحديث التفضيلات بنجاح",
|
||||||
|
"select_language": "اختر اللغة",
|
||||||
|
"select_time_zone": "اختر المنطة الزمنية",
|
||||||
|
"select_date_formate": "اختر صيغة التاريخ",
|
||||||
|
"select_financial_year": "اختر السنة المالية"
|
||||||
|
},
|
||||||
|
"update_app": {
|
||||||
|
"title": "تحديث النظام",
|
||||||
|
"description": "يمكنك تحديث النظام بسهولة عن طريق البحث عن تحديث جديد بالنقر فوق الزر أدناه",
|
||||||
|
"check_update": "تحقق من التحديثات",
|
||||||
|
"avail_update": "تحديث جديد متوفر",
|
||||||
|
"next_version": "النسخة الجديدة",
|
||||||
|
"update": "حدث الآن",
|
||||||
|
"update_progress": "قيد التحديث...",
|
||||||
|
"progress_text": "سوف يستغرق التحديث بضع دقائق. يرجى عدم تحديث الشاشة أو إغلاق النافذة قبل انتهاء التحديث",
|
||||||
|
"update_success": "تم تحديث النظام! يرجى الانتظار حتى يتم إعادة تحميل نافذة المتصفح تلقائيًا.",
|
||||||
|
"latest_message": "لا يوجد تحديثات متوفرة! لديك حالياً أحدث نسخة.",
|
||||||
|
"current_version": "النسخة الحالية"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"wizard": {
|
||||||
|
"account_info": "معلومات الحساب",
|
||||||
|
"account_info_desc": "سيتم استخدام التفاصيل أدناه لإنشاء حساب المسؤول الرئيسي. كما يمكنك تغيير التفاصيل في أي وقت بعد تسجيل الدخول.",
|
||||||
|
"name": "الاسم",
|
||||||
|
"email": "البريد الإلكتروني",
|
||||||
|
"password": "كلمة المرور",
|
||||||
|
"confirm_password": "أعد كتابة كلمة المرور",
|
||||||
|
"save_cont": "حفظ واستمرار",
|
||||||
|
"company_info": "معلومات الشركة",
|
||||||
|
"company_info_desc": "سيتم عرض هذه المعلومات على الفواتير. لاحظ أنه يمكنك تعديل هذا لاحقًا في صفحة الإعدادات.",
|
||||||
|
"company_name": "اسم الشركة",
|
||||||
|
"company_logo": "شعار الشركة",
|
||||||
|
"logo_preview": "استعراض الشعار",
|
||||||
|
"preferences": "التفضيلات",
|
||||||
|
"preferences_desc": "التفضيلات الافتراضية للنظام",
|
||||||
|
"country": "الدولة",
|
||||||
|
"state": "الولاية/المنطقة",
|
||||||
|
"city": "المدينة",
|
||||||
|
"address": "العنوان",
|
||||||
|
"street": "العنوان 1 | العنوان 2",
|
||||||
|
"phone": "الهاتف",
|
||||||
|
"zip_code": "الرمز البريدي",
|
||||||
|
"go_back": "للخلف",
|
||||||
|
"currency": "العملة",
|
||||||
|
"language": "اللغة",
|
||||||
|
"time_zone": "المنطة الزمنية",
|
||||||
|
"fiscal_year": "السنة المالية",
|
||||||
|
"date_format": "صيغة التاريخ",
|
||||||
|
"from_address": "من العنوان",
|
||||||
|
"username": "اسم المستخدم",
|
||||||
|
"next": "التالي",
|
||||||
|
"continue": "استمرار",
|
||||||
|
"skip": "تخطي",
|
||||||
|
"database": {
|
||||||
|
"database": "عنوان قاعدة البيانات",
|
||||||
|
"connection": "اتصال قاعدة البيانات",
|
||||||
|
"host": "خادم قاعدة البيانات",
|
||||||
|
"port": "منفذ قاعدة البيانات",
|
||||||
|
"password": "كلمة مرور قاعدة البيانات",
|
||||||
|
"app_url": "عنوان الإنترنت للنظام",
|
||||||
|
"username": "اسم المستخدم لقاعدة البيانات",
|
||||||
|
"db_name": "سم قاعدة البيانات",
|
||||||
|
"desc": "قم بإنشاء قاعدة بيانات على الخادم الخاص بك وتعيين بيانات الاعتماد باستخدام النموذج أدناه."
|
||||||
|
},
|
||||||
|
"permissions": {
|
||||||
|
"permissions": "الأذونات",
|
||||||
|
"permission_confirm_title": "هل أنت متأكد من الاستمرار؟",
|
||||||
|
"permission_confirm_desc": "فشل فحص أذونات المجلد",
|
||||||
|
"permission_desc": "فيما يلي قائمة أذونات المجلد المطلوبة حتى يعمل التطبيق. في حالة فشل فحص الإذن ، تأكد من تحديث أذونات المجلد."
|
||||||
|
},
|
||||||
|
"mail": {
|
||||||
|
"host": "خادم البريد",
|
||||||
|
"port": "منفذ البريد",
|
||||||
|
"driver": "مشغل البريد",
|
||||||
|
"secret": "سري",
|
||||||
|
"mailgun_secret": "الرمز السري لـ Mailgun",
|
||||||
|
"mailgun_domain": "المجال",
|
||||||
|
"mailgun_endpoint": "النهاية الطرفية لـ Mailgun",
|
||||||
|
"ses_secret": "SES الرمز السري",
|
||||||
|
"ses_key": "SES مفتاح",
|
||||||
|
"password": "كلمة مرور البريد الالكتروني",
|
||||||
|
"username": "اسم المستخدم للبريد الإلكتروني",
|
||||||
|
"mail_config": "إعدادات البريد الالكتروني",
|
||||||
|
"from_name": "اسم المرسل",
|
||||||
|
"from_mail": "عنوان البريد الالكتروني للمرسل",
|
||||||
|
"encryption": "صيغة ا لتشفير",
|
||||||
|
"mail_config_desc": "أدناه هو نموذج لتكوين برنامج تشغيل البريد الإلكتروني لإرسال رسائل البريد الإلكتروني من التطبيق. يمكنك أيضًا تهيئة موفري الجهات الخارجية مثل Sendgrid و SES إلخ."
|
||||||
|
},
|
||||||
|
"req": {
|
||||||
|
"system_req": "متطلبات النظام",
|
||||||
|
"php_req_version": "Php (النسخة المطلوبة {version} بحد أدنى)",
|
||||||
|
"check_req": "فحص متطلبات النظام",
|
||||||
|
"system_req_desc": "يحتوي النظام على بعض متطلبات الخادم. تأكد من أن خادمك لديه نسخة php المطلوبة وجميع الامتدادات المذكورة أدناه."
|
||||||
|
},
|
||||||
|
"errors": {
|
||||||
|
"migrate_failed": "فشل إنشاء الجداول",
|
||||||
|
"database_variables_save_error": "غير قادر على الاتصال بقاعدة البيانات باستخدام القيم المقدمة.",
|
||||||
|
"mail_variables_save_error": "فشل تكوين البريد الإلكتروني.",
|
||||||
|
"connection_failed": "فشل اتصال قاعدة البيانات",
|
||||||
|
"database_should_be_empty": "يجب أن تكون قاعدة البيانات فارغة"
|
||||||
|
},
|
||||||
|
"success": {
|
||||||
|
"mail_variables_save_successfully": "تم تكوين البريد الإلكتروني بنجاح",
|
||||||
|
"database_variables_save_successfully": "تم تكوين قاعدة البيانات بنجاح."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"layout_login": {
|
||||||
|
"copyright_crater": "حقوق الطبع والنشر @ كريتر - 2019",
|
||||||
|
"super_simple_invoicing": "فوترة سهلة ومبسطة للغاية",
|
||||||
|
"for_freelancer": "للمبرمجين المستقلين",
|
||||||
|
"small_businesses": "والأعال الصغيرة ",
|
||||||
|
"crater_help": "كريتر يساعدك على تتبع النفقات وتسجيل المدفوعات وإنشاء",
|
||||||
|
"invoices_and_estimates": "الفواتير والتقديرات مع إمكانية اختيار قوالب متعددة."
|
||||||
|
},
|
||||||
|
"validation": {
|
||||||
|
"invalid_url": "عنوان انترنت غير صحيح (مثال: http://www.crater.com)",
|
||||||
|
"required": "حقل مطلوب",
|
||||||
|
"email_incorrect": "بريد الكتروني غير صحيح.",
|
||||||
|
"email_already_taken": "هذا البريد الالكتروني مستخدم مسبقاً",
|
||||||
|
"email_does_not_exist": "لا يوجد كستخدم بهذا البريد الالكتروني",
|
||||||
|
"send_reset_link": "أرسال رابط استعادة كلمة المرور",
|
||||||
|
"not_yet": "ليس بعد؟ أعد الإرسال الآن..",
|
||||||
|
"password_min_length": "كلمة المرور يجب أن تتكون من {count} أحرف على الأقل",
|
||||||
|
"name_min_length": "الاسم يجب أن يتكون من {count} أحرف على الأقل",
|
||||||
|
"enter_valid_tax_rate": "أدخل معدل الضريبة بشكل صحيح",
|
||||||
|
"numbers_only": "أرقام فقط.",
|
||||||
|
"characters_only": "حروف فقط.",
|
||||||
|
"password_incorrect": "يجب أن تكون كلمات المرور متطابقة",
|
||||||
|
"password_length": "يجب أن تكون كلمة المرور بطول {count} حرف.",
|
||||||
|
"qty_must_greater_than_zero": "الكمية يجب أن تكون أكبر من صفر.",
|
||||||
|
"price_greater_than_zero": "السعر يجب أن يكون أكبر من صفر.",
|
||||||
|
"payment_greater_than_zero": "الدفعة يجب أن تكون أكبر من صفر.",
|
||||||
|
"payment_greater_than_due_amount": "مبلغ الدفعة أكثر من المبلغ المستحق لهذه الفاتورة.",
|
||||||
|
"quantity_maxlength": "يجب ألا تزيد الكمية عن 20 رقماً.",
|
||||||
|
"price_maxlength": "يجب ألا يزيد السعر عن 20 رقماً.",
|
||||||
|
"price_minvalue": "يجب أن يكون السعر أكبر من صفر.",
|
||||||
|
"amount_maxlength": "يجب ألا يزيد المبلغ عن 20 رقماً.",
|
||||||
|
"amount_minvalue": "يجب أن يكون المبلغ أكبر من صفر.",
|
||||||
|
"description_maxlength": "يجب ألا يزيد الوصف عن 255 حرفاً.",
|
||||||
|
"maximum_options_error": "الحد الأعلى هو {max} خيارات. قم بإزالة أحد الخيارات لتحديد خيار آخر.",
|
||||||
|
"notes_maxlength": "يجب ألا يزيد حجم الملاحظات عن 255 حرفاً.",
|
||||||
|
"address_maxlength": "يجب ألا يزيد العنوان عن 255 حرفاً.",
|
||||||
|
"ref_number_maxlength": "يجب ألا يزيد الرقم المرجعي عن 255 حرفاً.",
|
||||||
|
"prefix_maxlength": "يجب ألا تزيد البادئة عن 5 أحرف."
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -530,6 +530,7 @@
|
|||||||
"menu_title": {
|
"menu_title": {
|
||||||
"account_settings": "Account Settings",
|
"account_settings": "Account Settings",
|
||||||
"company_information": "Company Information",
|
"company_information": "Company Information",
|
||||||
|
"customization": "Customization",
|
||||||
"preferences": "Preferences",
|
"preferences": "Preferences",
|
||||||
"notifications": "Notifications",
|
"notifications": "Notifications",
|
||||||
"tax_types": "Tax Types",
|
"tax_types": "Tax Types",
|
||||||
@ -598,6 +599,67 @@
|
|||||||
"save": "Save",
|
"save": "Save",
|
||||||
"updated_message": "Company information updated successfully"
|
"updated_message": "Company information updated successfully"
|
||||||
},
|
},
|
||||||
|
"customization": {
|
||||||
|
"customization": "customization",
|
||||||
|
"save": "Save",
|
||||||
|
"addresses": {
|
||||||
|
"title": "Addresses",
|
||||||
|
"section_description": "You can set Customer Billing Address and Customer Shipping Address Format (Displayed in PDF only). ",
|
||||||
|
"customer_billing_address": "Customer Billing Address",
|
||||||
|
"customer_shipping_address": "Customer Shipping Address",
|
||||||
|
"company_address": "Company Address",
|
||||||
|
"insert_fields": "Insert Fields",
|
||||||
|
"contact": "Contact",
|
||||||
|
"address": "Address",
|
||||||
|
"display_name": "Display Name",
|
||||||
|
"primary_contact_name": "Primary Contact Name",
|
||||||
|
"email": "Email",
|
||||||
|
"website": "Website",
|
||||||
|
"name": "Name",
|
||||||
|
"country": "Country",
|
||||||
|
"state": "State",
|
||||||
|
"city": "City",
|
||||||
|
"company_name": "Company Name",
|
||||||
|
"address_street_1": "Address Street 1",
|
||||||
|
"address_street_2": "Address Street 2",
|
||||||
|
"phone": "Phone",
|
||||||
|
"zip_code": "Zip Code",
|
||||||
|
"address_setting_updated": "Address Setting updated successfully"
|
||||||
|
},
|
||||||
|
"updated_message": "Company information updated successfully",
|
||||||
|
|
||||||
|
"invoices": {
|
||||||
|
"title": "Invoices",
|
||||||
|
"notes": "Notes",
|
||||||
|
"invoice_prefix": "Invoice Prefix",
|
||||||
|
"invoice_settings": "Invoice Settings",
|
||||||
|
"autogenerate_invoice_number": "Autogenerate Invoice Number",
|
||||||
|
"invoice_setting_description": "Disable this, If you don't wish to auto-generate invoice numbers each time you create a new invoice.",
|
||||||
|
"enter_invoice_prefix": "Enter invoice prefix",
|
||||||
|
"terms_and_conditions": "Terms and Conditions",
|
||||||
|
"invoice_setting_updated": "Invoice Setting updated successfully"
|
||||||
|
},
|
||||||
|
|
||||||
|
"estimates": {
|
||||||
|
"title": "Estimates",
|
||||||
|
"estimate_prefix": "Estimate Prefix",
|
||||||
|
"estimate_settings": "Estimate Settings",
|
||||||
|
"autogenerate_estimate_number": "Autogenerate Estimate Number",
|
||||||
|
"estimate_setting_description": "Disable this, If you don't wish to auto-generate estimate numbers each time you create a new estimate.",
|
||||||
|
"enter_estimate_prefix": "Enter estmiate prefix",
|
||||||
|
"estimate_setting_updated": "Estimate Setting updated successfully"
|
||||||
|
},
|
||||||
|
|
||||||
|
"payments": {
|
||||||
|
"title": "Payments",
|
||||||
|
"payment_prefix": "Payment Prefix",
|
||||||
|
"payment_settings": "Payment Settings",
|
||||||
|
"autogenerate_payment_number": "Autogenerate Payment Number",
|
||||||
|
"payment_setting_description": "Disable this, If you don't wish to auto-generate payment numbers each time you create a new payment.",
|
||||||
|
"enter_payment_prefix": "Enter Payment Prefix",
|
||||||
|
"payment_setting_updated": "Payment Setting updated successfully"
|
||||||
|
}
|
||||||
|
},
|
||||||
"account_settings": {
|
"account_settings": {
|
||||||
"profile_picture": "Profile Picture",
|
"profile_picture": "Profile Picture",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
@ -666,7 +728,7 @@
|
|||||||
"date_format": "Date Format",
|
"date_format": "Date Format",
|
||||||
"discount_setting": "Discount Setting",
|
"discount_setting": "Discount Setting",
|
||||||
"discount_per_item": "Discount Per Item ",
|
"discount_per_item": "Discount Per Item ",
|
||||||
"discount_setting_description": "Enable this if you want to add Discount to individual invoice items. By default, Discount are added directly to the invoice.",
|
"discount_setting_description": "Enable this if you want to add Discount to individual invoice items. By default, Discount is added directly to the invoice.",
|
||||||
"save": "Save",
|
"save": "Save",
|
||||||
"preference": "Preference | Preferences",
|
"preference": "Preference | Preferences",
|
||||||
"general_settings": "Default preferences for the system.",
|
"general_settings": "Default preferences for the system.",
|
||||||
@ -812,6 +874,7 @@
|
|||||||
"maximum_options_error": "Maximum of {max} options selected. First remove a selected option to select another.",
|
"maximum_options_error": "Maximum of {max} options selected. First remove a selected option to select another.",
|
||||||
"notes_maxlength": "Notes should not be greater than 255 characters.",
|
"notes_maxlength": "Notes should not be greater than 255 characters.",
|
||||||
"address_maxlength": "Address should not be greater than 255 characters.",
|
"address_maxlength": "Address should not be greater than 255 characters.",
|
||||||
"ref_number_maxlength": "Ref Number should not be greater than 255 characters."
|
"ref_number_maxlength": "Ref Number should not be greater than 255 characters.",
|
||||||
|
"prefix_maxlength": "Prefix should not be greater than 5 characters."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import VueI18n from 'vue-i18n'
|
|||||||
import en from './en.json'
|
import en from './en.json'
|
||||||
import fr from './fr.json'
|
import fr from './fr.json'
|
||||||
import es from './es.json'
|
import es from './es.json'
|
||||||
|
import ar from './ar.json'
|
||||||
|
|
||||||
Vue.use(VueI18n)
|
Vue.use(VueI18n)
|
||||||
|
|
||||||
@ -11,7 +12,8 @@ const i18n = new VueI18n({
|
|||||||
messages: {
|
messages: {
|
||||||
en,
|
en,
|
||||||
fr,
|
fr,
|
||||||
es
|
es,
|
||||||
|
ar
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -66,6 +66,7 @@ import ReportLayout from './views/reports/layout/Index.vue'
|
|||||||
// Settings
|
// Settings
|
||||||
import SettingsLayout from './views/settings/layout/Index.vue'
|
import SettingsLayout from './views/settings/layout/Index.vue'
|
||||||
import CompanyInfo from './views/settings/CompanyInfo.vue'
|
import CompanyInfo from './views/settings/CompanyInfo.vue'
|
||||||
|
import Customization from './views/settings/Customization.vue'
|
||||||
import Notifications from './views/settings/Notifications.vue'
|
import Notifications from './views/settings/Notifications.vue'
|
||||||
import Preferences from './views/settings/Preferences.vue'
|
import Preferences from './views/settings/Preferences.vue'
|
||||||
import UserProfile from './views/settings/UserProfile.vue'
|
import UserProfile from './views/settings/UserProfile.vue'
|
||||||
@ -309,6 +310,11 @@ const routes = [
|
|||||||
name: 'company.info',
|
name: 'company.info',
|
||||||
component: CompanyInfo
|
component: CompanyInfo
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'customization',
|
||||||
|
name: 'customization',
|
||||||
|
component: Customization
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'user-profile',
|
path: 'user-profile',
|
||||||
name: 'user.profile',
|
name: 'user.profile',
|
||||||
|
|||||||
@ -162,7 +162,7 @@
|
|||||||
:options="billingCountries"
|
:options="billingCountries"
|
||||||
:searchable="true"
|
:searchable="true"
|
||||||
:show-labels="false"
|
:show-labels="false"
|
||||||
:allow-empty="false"
|
:allow-empty="true"
|
||||||
:tabindex="8"
|
:tabindex="8"
|
||||||
:placeholder="$t('general.select_country')"
|
:placeholder="$t('general.select_country')"
|
||||||
label="name"
|
label="name"
|
||||||
@ -265,7 +265,7 @@
|
|||||||
:searchable="true"
|
:searchable="true"
|
||||||
:show-labels="false"
|
:show-labels="false"
|
||||||
:tabindex="16"
|
:tabindex="16"
|
||||||
:allow-empty="false"
|
:allow-empty="true"
|
||||||
:placeholder="$t('general.select_country')"
|
:placeholder="$t('general.select_country')"
|
||||||
label="name"
|
label="name"
|
||||||
track-by="id"
|
track-by="id"
|
||||||
@ -411,6 +411,36 @@ export default {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
},
|
||||||
|
hasBillingAdd () {
|
||||||
|
let billing = this.billing
|
||||||
|
if (
|
||||||
|
billing.name ||
|
||||||
|
billing.country_id ||
|
||||||
|
billing.state ||
|
||||||
|
billing.city ||
|
||||||
|
billing.phone ||
|
||||||
|
billing.zip ||
|
||||||
|
billing.address_street_1 ||
|
||||||
|
billing.address_street_2) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
hasShippingAdd () {
|
||||||
|
let shipping = this.shipping
|
||||||
|
if (
|
||||||
|
shipping.name ||
|
||||||
|
shipping.country_id ||
|
||||||
|
shipping.state ||
|
||||||
|
shipping.city ||
|
||||||
|
shipping.phone ||
|
||||||
|
shipping.zip ||
|
||||||
|
shipping.address_street_1 ||
|
||||||
|
shipping.address_street_2) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@ -418,12 +448,16 @@ export default {
|
|||||||
if (newCountry) {
|
if (newCountry) {
|
||||||
this.billing.country_id = newCountry.id
|
this.billing.country_id = newCountry.id
|
||||||
this.isDisabledBillingState = false
|
this.isDisabledBillingState = false
|
||||||
|
} else {
|
||||||
|
this.billing.country_id = null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
shipping_country (newCountry) {
|
shipping_country (newCountry) {
|
||||||
if (newCountry) {
|
if (newCountry) {
|
||||||
this.shipping.country_id = newCountry.id
|
this.shipping.country_id = newCountry.id
|
||||||
return true
|
return true
|
||||||
|
} else {
|
||||||
|
this.shipping.country_id = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -446,7 +480,14 @@ export default {
|
|||||||
]),
|
]),
|
||||||
async loadCustomer () {
|
async loadCustomer () {
|
||||||
let { data: { customer, currencies, currency } } = await this.fetchCustomer(this.$route.params.id)
|
let { data: { customer, currencies, currency } } = await this.fetchCustomer(this.$route.params.id)
|
||||||
this.formData = customer
|
|
||||||
|
this.formData.id = customer.id
|
||||||
|
this.formData.name = customer.name
|
||||||
|
this.formData.contact_name = customer.contact_name
|
||||||
|
this.formData.email = customer.email
|
||||||
|
this.formData.phone = customer.phone
|
||||||
|
this.formData.currency_id = customer.currency_id
|
||||||
|
this.formData.website = customer.website
|
||||||
|
|
||||||
if (customer.billing_address) {
|
if (customer.billing_address) {
|
||||||
this.billing = customer.billing_address
|
this.billing = customer.billing_address
|
||||||
@ -495,7 +536,16 @@ export default {
|
|||||||
if (this.$v.$invalid) {
|
if (this.$v.$invalid) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
if (this.hasBillingAdd && this.hasShippingAdd) {
|
||||||
this.formData.addresses = [{...this.billing}, {...this.shipping}]
|
this.formData.addresses = [{...this.billing}, {...this.shipping}]
|
||||||
|
} else {
|
||||||
|
if (this.hasBillingAdd) {
|
||||||
|
this.formData.addresses = [{...this.billing}]
|
||||||
|
}
|
||||||
|
if (this.hasShippingAdd) {
|
||||||
|
this.formData.addresses = [{...this.shipping}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (this.isEdit) {
|
if (this.isEdit) {
|
||||||
if (this.currency) {
|
if (this.currency) {
|
||||||
|
|||||||
@ -32,8 +32,8 @@
|
|||||||
class="show-customer"
|
class="show-customer"
|
||||||
>
|
>
|
||||||
<div class="row px-2 mt-1">
|
<div class="row px-2 mt-1">
|
||||||
<div class="col col-6">
|
<div v-if="selectedCustomer.billing_address" class="col col-6">
|
||||||
<div v-if="selectedCustomer.billing_address != null" class="row address-menu">
|
<div class="row address-menu">
|
||||||
<label class="col-sm-4 px-2 title">{{ $t('general.bill_to') }}</label>
|
<label class="col-sm-4 px-2 title">{{ $t('general.bill_to') }}</label>
|
||||||
<div class="col-sm p-0 px-2 content">
|
<div class="col-sm p-0 px-2 content">
|
||||||
<label v-if="selectedCustomer.billing_address.name">
|
<label v-if="selectedCustomer.billing_address.name">
|
||||||
@ -57,8 +57,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-6">
|
<div v-if="selectedCustomer.shipping_address" class="col col-6">
|
||||||
<div v-if="selectedCustomer.shipping_address != null" class="row address-menu">
|
<div class="row address-menu">
|
||||||
<label class="col-sm-4 px-2 title">{{ $t('general.ship_to') }}</label>
|
<label class="col-sm-4 px-2 title">{{ $t('general.ship_to') }}</label>
|
||||||
<div class="col-sm p-0 px-2 content">
|
<div class="col-sm p-0 px-2 content">
|
||||||
<label v-if="selectedCustomer.shipping_address.name">
|
<label v-if="selectedCustomer.shipping_address.name">
|
||||||
@ -84,7 +84,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="customer-content mb-1">
|
<div class="customer-content mb-1">
|
||||||
<label class="email">{{ selectedCustomer.email ? selectedCustomer.email : selectedCustomer.name }}</label>
|
<label class="email">{{ selectedCustomer.name }}</label>
|
||||||
<label class="action" @click="removeCustomer">{{ $t('general.remove') }}</label>
|
<label class="action" @click="removeCustomer">{{ $t('general.remove') }}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -127,14 +127,15 @@
|
|||||||
<div class="row mt-4">
|
<div class="row mt-4">
|
||||||
<div class="col collapse-input">
|
<div class="col collapse-input">
|
||||||
<label>{{ $t('estimates.estimate_number') }}<span class="text-danger"> * </span></label>
|
<label>{{ $t('estimates.estimate_number') }}<span class="text-danger"> * </span></label>
|
||||||
<base-input
|
<base-prefix-input
|
||||||
:invalid="$v.newEstimate.estimate_number.$error"
|
v-model="estimateNumAttribute"
|
||||||
:read-only="true"
|
:invalid="$v.estimateNumAttribute.$error"
|
||||||
v-model="newEstimate.estimate_number"
|
:prefix="estimatePrefix"
|
||||||
icon="hashtag"
|
icon="hashtag"
|
||||||
@input="$v.newEstimate.estimate_number.$touch()"
|
@input="$v.estimateNumAttribute.$touch()"
|
||||||
/>
|
/>
|
||||||
<span v-show="$v.newEstimate.estimate_number.$error && !$v.newEstimate.estimate_number.required" class="text-danger mt-1"> {{ $tc('estimates.errors.required') }} </span>
|
<span v-show="$v.estimateNumAttribute.$error && !$v.estimateNumAttribute.required" class="text-danger mt-1"> {{ $tc('estimates.errors.required') }} </span>
|
||||||
|
<span v-show="!$v.estimateNumAttribute.numeric" class="text-danger mt-1"> {{ $tc('validation.numbers_only') }} </span>
|
||||||
</div>
|
</div>
|
||||||
<div class="col collapse-input">
|
<div class="col collapse-input">
|
||||||
<label>{{ $t('estimates.ref_number') }}</label>
|
<label>{{ $t('estimates.ref_number') }}</label>
|
||||||
@ -320,7 +321,7 @@ import { validationMixin } from 'vuelidate'
|
|||||||
import Guid from 'guid'
|
import Guid from 'guid'
|
||||||
import TaxStub from '../../stub/tax'
|
import TaxStub from '../../stub/tax'
|
||||||
import Tax from './EstimateTax'
|
import Tax from './EstimateTax'
|
||||||
const { required, between, maxLength } = require('vuelidate/lib/validators')
|
const { required, between, maxLength, numeric } = require('vuelidate/lib/validators')
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@ -361,7 +362,9 @@ export default {
|
|||||||
discountPerItem: null,
|
discountPerItem: null,
|
||||||
initLoading: false,
|
initLoading: false,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
maxDiscount: 0
|
maxDiscount: 0,
|
||||||
|
estimatePrefix: null,
|
||||||
|
estimateNumAttribute: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
validations () {
|
validations () {
|
||||||
@ -373,9 +376,6 @@ export default {
|
|||||||
expiry_date: {
|
expiry_date: {
|
||||||
required
|
required
|
||||||
},
|
},
|
||||||
estimate_number: {
|
|
||||||
required
|
|
||||||
},
|
|
||||||
discount_val: {
|
discount_val: {
|
||||||
between: between(0, this.subtotal)
|
between: between(0, this.subtotal)
|
||||||
},
|
},
|
||||||
@ -388,6 +388,10 @@ export default {
|
|||||||
},
|
},
|
||||||
selectedCustomer: {
|
selectedCustomer: {
|
||||||
required
|
required
|
||||||
|
},
|
||||||
|
estimateNumAttribute: {
|
||||||
|
required,
|
||||||
|
numeric
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -559,6 +563,8 @@ export default {
|
|||||||
this.taxPerItem = response.data.tax_per_item
|
this.taxPerItem = response.data.tax_per_item
|
||||||
this.selectedCurrency = this.defaultCurrency
|
this.selectedCurrency = this.defaultCurrency
|
||||||
this.estimateTemplates = response.data.estimateTemplates
|
this.estimateTemplates = response.data.estimateTemplates
|
||||||
|
this.estimatePrefix = response.data.estimate_prefix
|
||||||
|
this.estimateNumAttribute = response.data.nextEstimateNumber
|
||||||
}
|
}
|
||||||
this.initLoading = false
|
this.initLoading = false
|
||||||
return
|
return
|
||||||
@ -574,8 +580,9 @@ export default {
|
|||||||
let today = new Date()
|
let today = new Date()
|
||||||
this.newEstimate.estimate_date = moment(today).toString()
|
this.newEstimate.estimate_date = moment(today).toString()
|
||||||
this.newEstimate.expiry_date = moment(today).add(7, 'days').toString()
|
this.newEstimate.expiry_date = moment(today).add(7, 'days').toString()
|
||||||
this.newEstimate.estimate_number = response.data.nextEstimateNumber
|
|
||||||
this.itemList = response.data.items
|
this.itemList = response.data.items
|
||||||
|
this.estimatePrefix = response.data.estimate_prefix
|
||||||
|
this.estimateNumAttribute = response.data.nextEstimateNumberAttribute
|
||||||
}
|
}
|
||||||
this.initLoading = false
|
this.initLoading = false
|
||||||
},
|
},
|
||||||
@ -604,6 +611,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.isLoading = true
|
this.isLoading = true
|
||||||
|
this.newEstimate.estimate_number = this.estimatePrefix + '-' + this.estimateNumAttribute
|
||||||
|
|
||||||
let data = {
|
let data = {
|
||||||
...this.newEstimate,
|
...this.newEstimate,
|
||||||
@ -637,7 +645,11 @@ export default {
|
|||||||
this.isLoading = false
|
this.isLoading = false
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
this.isLoading = false
|
this.isLoading = false
|
||||||
console.log(err)
|
if (err.response.data.errors.estimate_number) {
|
||||||
|
window.toastr['error'](err.response.data.errors.estimate_number)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
window.toastr['error'](err.response.data.message)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
submitUpdate (data) {
|
submitUpdate (data) {
|
||||||
@ -650,7 +662,11 @@ export default {
|
|||||||
this.isLoading = false
|
this.isLoading = false
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
this.isLoading = false
|
this.isLoading = false
|
||||||
console.log(err)
|
if (err.response.data.errors.estimate_number) {
|
||||||
|
window.toastr['error'](err.response.data.errors.estimate_number)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
window.toastr['error'](err.response.data.message)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
checkItemsData (index, isValid) {
|
checkItemsData (index, isValid) {
|
||||||
|
|||||||
@ -30,8 +30,8 @@
|
|||||||
<div
|
<div
|
||||||
v-if="selectedCustomer" class="show-customer">
|
v-if="selectedCustomer" class="show-customer">
|
||||||
<div class="row px-2 mt-1">
|
<div class="row px-2 mt-1">
|
||||||
<div class="col col-6">
|
<div v-if="selectedCustomer.billing_address" class="col col-6">
|
||||||
<div v-if="selectedCustomer.billing_address" class="row address-menu">
|
<div class="row address-menu">
|
||||||
<label class="col-sm-4 px-2 title">{{ $t('general.bill_to') }}</label>
|
<label class="col-sm-4 px-2 title">{{ $t('general.bill_to') }}</label>
|
||||||
<div class="col-sm p-0 px-2 content">
|
<div class="col-sm p-0 px-2 content">
|
||||||
<label v-if="selectedCustomer.billing_address.name">
|
<label v-if="selectedCustomer.billing_address.name">
|
||||||
@ -55,8 +55,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-6">
|
<div v-if="selectedCustomer.shipping_address" class="col col-6">
|
||||||
<div v-if="selectedCustomer.shipping_address" class="row address-menu">
|
<div class="row address-menu">
|
||||||
<label class="col-sm-4 px-2 title">{{ $t('general.ship_to') }}</label>
|
<label class="col-sm-4 px-2 title">{{ $t('general.ship_to') }}</label>
|
||||||
<div class="col-sm p-0 px-2 content">
|
<div class="col-sm p-0 px-2 content">
|
||||||
<label v-if="selectedCustomer.shipping_address.name">
|
<label v-if="selectedCustomer.shipping_address.name">
|
||||||
@ -127,14 +127,15 @@
|
|||||||
<div class="row mt-4">
|
<div class="row mt-4">
|
||||||
<div class="col collapse-input">
|
<div class="col collapse-input">
|
||||||
<label>{{ $t('invoices.invoice_number') }}<span class="text-danger"> * </span></label>
|
<label>{{ $t('invoices.invoice_number') }}<span class="text-danger"> * </span></label>
|
||||||
<base-input
|
<base-prefix-input
|
||||||
:invalid="$v.newInvoice.invoice_number.$error"
|
v-model="invoiceNumAttribute"
|
||||||
:read-only="true"
|
:invalid="$v.invoiceNumAttribute.$error"
|
||||||
v-model="newInvoice.invoice_number"
|
:prefix="invoicePrefix"
|
||||||
icon="hashtag"
|
icon="hashtag"
|
||||||
@input="$v.newInvoice.invoice_number.$touch()"
|
@input="$v.invoiceNumAttribute.$touch()"
|
||||||
/>
|
/>
|
||||||
<span v-show="$v.newInvoice.invoice_number.$error && !$v.newInvoice.invoice_number.required" class="text-danger mt-1"> {{ $tc('validation.required') }} </span>
|
<span v-show="$v.invoiceNumAttribute.$error && !$v.invoiceNumAttribute.required" class="text-danger mt-1"> {{ $tc('validation.required') }} </span>
|
||||||
|
<span v-show="!$v.invoiceNumAttribute.numeric" class="text-danger mt-1"> {{ $tc('validation.numbers_only') }} </span>
|
||||||
</div>
|
</div>
|
||||||
<div class="col collapse-input">
|
<div class="col collapse-input">
|
||||||
<label>{{ $t('invoices.ref_number') }}</label>
|
<label>{{ $t('invoices.ref_number') }}</label>
|
||||||
@ -320,7 +321,7 @@ import { validationMixin } from 'vuelidate'
|
|||||||
import Guid from 'guid'
|
import Guid from 'guid'
|
||||||
import TaxStub from '../../stub/tax'
|
import TaxStub from '../../stub/tax'
|
||||||
import Tax from './InvoiceTax'
|
import Tax from './InvoiceTax'
|
||||||
const { required, between, maxLength } = require('vuelidate/lib/validators')
|
const { required, between, maxLength, numeric } = require('vuelidate/lib/validators')
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@ -361,7 +362,9 @@ export default {
|
|||||||
discountPerItem: null,
|
discountPerItem: null,
|
||||||
initLoading: false,
|
initLoading: false,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
maxDiscount: 0
|
maxDiscount: 0,
|
||||||
|
invoicePrefix: null,
|
||||||
|
invoiceNumAttribute: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
validations () {
|
validations () {
|
||||||
@ -373,9 +376,6 @@ export default {
|
|||||||
due_date: {
|
due_date: {
|
||||||
required
|
required
|
||||||
},
|
},
|
||||||
invoice_number: {
|
|
||||||
required
|
|
||||||
},
|
|
||||||
discount_val: {
|
discount_val: {
|
||||||
between: between(0, this.subtotal)
|
between: between(0, this.subtotal)
|
||||||
},
|
},
|
||||||
@ -388,6 +388,10 @@ export default {
|
|||||||
},
|
},
|
||||||
selectedCustomer: {
|
selectedCustomer: {
|
||||||
required
|
required
|
||||||
|
},
|
||||||
|
invoiceNumAttribute: {
|
||||||
|
required,
|
||||||
|
numeric
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -559,6 +563,8 @@ export default {
|
|||||||
this.taxPerItem = response.data.tax_per_item
|
this.taxPerItem = response.data.tax_per_item
|
||||||
this.selectedCurrency = this.defaultCurrency
|
this.selectedCurrency = this.defaultCurrency
|
||||||
this.invoiceTemplates = response.data.invoiceTemplates
|
this.invoiceTemplates = response.data.invoiceTemplates
|
||||||
|
this.invoicePrefix = response.data.invoice_prefix
|
||||||
|
this.invoiceNumAttribute = response.data.nextInvoiceNumber
|
||||||
}
|
}
|
||||||
this.initLoading = false
|
this.initLoading = false
|
||||||
return
|
return
|
||||||
@ -574,8 +580,9 @@ export default {
|
|||||||
let today = new Date()
|
let today = new Date()
|
||||||
this.newInvoice.invoice_date = moment(today).toString()
|
this.newInvoice.invoice_date = moment(today).toString()
|
||||||
this.newInvoice.due_date = moment(today).add(7, 'days').toString()
|
this.newInvoice.due_date = moment(today).add(7, 'days').toString()
|
||||||
this.newInvoice.invoice_number = response.data.nextInvoiceNumber
|
|
||||||
this.itemList = response.data.items
|
this.itemList = response.data.items
|
||||||
|
this.invoicePrefix = response.data.invoice_prefix
|
||||||
|
this.invoiceNumAttribute = response.data.nextInvoiceNumberAttribute
|
||||||
}
|
}
|
||||||
this.initLoading = false
|
this.initLoading = false
|
||||||
},
|
},
|
||||||
@ -604,6 +611,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.isLoading = true
|
this.isLoading = true
|
||||||
|
this.newInvoice.invoice_number = this.invoicePrefix + '-' + this.invoiceNumAttribute
|
||||||
|
|
||||||
let data = {
|
let data = {
|
||||||
...this.newInvoice,
|
...this.newInvoice,
|
||||||
@ -637,6 +645,10 @@ export default {
|
|||||||
this.isLoading = false
|
this.isLoading = false
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
this.isLoading = false
|
this.isLoading = false
|
||||||
|
if (err.response.data.errors.invoice_number) {
|
||||||
|
window.toastr['error'](err.response.data.errors.invoice_number)
|
||||||
|
return true
|
||||||
|
}
|
||||||
console.log(err)
|
console.log(err)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@ -653,6 +665,10 @@ export default {
|
|||||||
}
|
}
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
this.isLoading = false
|
this.isLoading = false
|
||||||
|
if (err.response.data.errors.invoice_number) {
|
||||||
|
window.toastr['error'](err.response.data.errors.invoice_number)
|
||||||
|
return true
|
||||||
|
}
|
||||||
console.log(err)
|
console.log(err)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|||||||
@ -40,16 +40,15 @@
|
|||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label">{{ $t('payments.payment_number') }}</label><span class="text-danger"> *</span>
|
<label class="form-label">{{ $t('payments.payment_number') }}</label><span class="text-danger"> *</span>
|
||||||
<base-input
|
<base-prefix-input
|
||||||
:invalid="$v.formData.payment_number.$error"
|
:invalid="$v.paymentNumAttribute.$error"
|
||||||
v-model.trim="formData.payment_number"
|
v-model.trim="paymentNumAttribute"
|
||||||
read-only
|
:prefix="paymentPrefix"
|
||||||
type="text"
|
@input="$v.paymentNumAttribute.$touch()"
|
||||||
name="email"
|
|
||||||
@input="$v.formData.payment_number.$touch()"
|
|
||||||
/>
|
/>
|
||||||
<div v-if="$v.formData.payment_number.$error">
|
<div v-if="$v.paymentNumAttribute.$error">
|
||||||
<span v-if="!$v.formData.payment_number.required" class="text-danger">{{ $tc('validation.required') }}</span>
|
<span v-if="!$v.paymentNumAttribute.required" class="text-danger">{{ $tc('validation.required') }}</span>
|
||||||
|
<span v-if="!$v.paymentNumAttribute.numeric" class="text-danger">{{ $tc('validation.numbers_only') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -155,7 +154,7 @@ import { mapActions, mapGetters } from 'vuex'
|
|||||||
import MultiSelect from 'vue-multiselect'
|
import MultiSelect from 'vue-multiselect'
|
||||||
import { validationMixin } from 'vuelidate'
|
import { validationMixin } from 'vuelidate'
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
const { required, between, maxLength } = require('vuelidate/lib/validators')
|
const { required, between, maxLength, numeric } = require('vuelidate/lib/validators')
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { MultiSelect },
|
components: { MultiSelect },
|
||||||
@ -184,7 +183,9 @@ export default {
|
|||||||
invoiceList: [],
|
invoiceList: [],
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
maxPayableAmount: Number.MAX_SAFE_INTEGER,
|
maxPayableAmount: Number.MAX_SAFE_INTEGER,
|
||||||
isSettingInitialData: true
|
isSettingInitialData: true,
|
||||||
|
paymentNumAttribute: null,
|
||||||
|
paymentPrefix: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
validations () {
|
validations () {
|
||||||
@ -193,9 +194,6 @@ export default {
|
|||||||
required
|
required
|
||||||
},
|
},
|
||||||
formData: {
|
formData: {
|
||||||
payment_number: {
|
|
||||||
required
|
|
||||||
},
|
|
||||||
payment_date: {
|
payment_date: {
|
||||||
required
|
required
|
||||||
},
|
},
|
||||||
@ -206,6 +204,10 @@ export default {
|
|||||||
notes: {
|
notes: {
|
||||||
maxLength: maxLength(255)
|
maxLength: maxLength(255)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
paymentNumAttribute: {
|
||||||
|
required,
|
||||||
|
numeric
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -297,6 +299,8 @@ export default {
|
|||||||
this.customer = response.data.payment.user
|
this.customer = response.data.payment.user
|
||||||
this.formData.payment_date = moment(response.data.payment.payment_date, 'YYYY-MM-DD').toString()
|
this.formData.payment_date = moment(response.data.payment.payment_date, 'YYYY-MM-DD').toString()
|
||||||
this.formData.amount = parseFloat(response.data.payment.amount)
|
this.formData.amount = parseFloat(response.data.payment.amount)
|
||||||
|
this.paymentPrefix = response.data.payment_prefix
|
||||||
|
this.paymentNumAttribute = response.data.nextPaymentNumber
|
||||||
if (response.data.payment.invoice !== null) {
|
if (response.data.payment.invoice !== null) {
|
||||||
this.maxPayableAmount = parseInt(response.data.payment.amount) + parseInt(response.data.payment.invoice.due_amount)
|
this.maxPayableAmount = parseInt(response.data.payment.amount) + parseInt(response.data.payment.invoice.due_amount)
|
||||||
this.invoice = response.data.payment.invoice
|
this.invoice = response.data.payment.invoice
|
||||||
@ -305,7 +309,8 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
let response = await this.fetchCreatePayment()
|
let response = await this.fetchCreatePayment()
|
||||||
this.customerList = response.data.customers
|
this.customerList = response.data.customers
|
||||||
this.formData.payment_number = response.data.nextPaymentNumber
|
this.paymentNumAttribute = response.data.nextPaymentNumberAttribute
|
||||||
|
this.paymentPrefix = response.data.payment_prefix
|
||||||
this.formData.payment_date = moment(new Date()).toString()
|
this.formData.payment_date = moment(new Date()).toString()
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@ -332,6 +337,9 @@ export default {
|
|||||||
if (this.$v.$invalid) {
|
if (this.$v.$invalid) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.formData.payment_number = this.paymentPrefix + '-' + this.paymentNumAttribute
|
||||||
|
|
||||||
if (this.isEdit) {
|
if (this.isEdit) {
|
||||||
let data = {
|
let data = {
|
||||||
editData: {
|
editData: {
|
||||||
@ -340,6 +348,7 @@ export default {
|
|||||||
},
|
},
|
||||||
id: this.$route.params.id
|
id: this.$route.params.id
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
let response = await this.updatePayment(data)
|
let response = await this.updatePayment(data)
|
||||||
if (response.data.success) {
|
if (response.data.success) {
|
||||||
window.toastr['success'](this.$t('payments.updated_message'))
|
window.toastr['success'](this.$t('payments.updated_message'))
|
||||||
@ -351,12 +360,21 @@ export default {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
window.toastr['error'](response.data.error)
|
window.toastr['error'](response.data.error)
|
||||||
|
} catch (err) {
|
||||||
|
this.isLoading = false
|
||||||
|
if (err.response.data.errors.payment_number) {
|
||||||
|
window.toastr['error'](err.response.data.errors.payment_number)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
window.toastr['error'](err.response.data.message)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let data = {
|
let data = {
|
||||||
...this.formData,
|
...this.formData,
|
||||||
payment_date: moment(this.formData.payment_date).format('DD/MM/YYYY')
|
payment_date: moment(this.formData.payment_date).format('DD/MM/YYYY')
|
||||||
}
|
}
|
||||||
this.isLoading = true
|
this.isLoading = true
|
||||||
|
try {
|
||||||
let response = await this.addPayment(data)
|
let response = await this.addPayment(data)
|
||||||
if (response.data.success) {
|
if (response.data.success) {
|
||||||
window.toastr['success'](this.$t('payments.created_message'))
|
window.toastr['success'](this.$t('payments.created_message'))
|
||||||
@ -369,6 +387,14 @@ export default {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
window.toastr['error'](response.data.error)
|
window.toastr['error'](response.data.error)
|
||||||
|
} catch (err) {
|
||||||
|
this.isLoading = false
|
||||||
|
if (err.response.data.errors.payment_number) {
|
||||||
|
window.toastr['error'](err.response.data.errors.payment_number)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
window.toastr['error'](err.response.data.message)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
385
resources/assets/js/views/settings/Customization.vue
Normal file
385
resources/assets/js/views/settings/Customization.vue
Normal file
@ -0,0 +1,385 @@
|
|||||||
|
<template>
|
||||||
|
<div class="setting-main-container customization">
|
||||||
|
<div class="card setting-card">
|
||||||
|
<ul class="tabs">
|
||||||
|
<li class="tab" @click="setActiveTab('INVOICES')">
|
||||||
|
<a :class="['tab-link', {'a-active': activeTab === 'INVOICES'}]" href="#">{{ $t('settings.customization.invoices.title') }}</a>
|
||||||
|
</li>
|
||||||
|
<li class="tab" @click="setActiveTab('ESTIMATES')">
|
||||||
|
<a :class="['tab-link', {'a-active': activeTab === 'ESTIMATES'}]" href="#">{{ $t('settings.customization.estimates.title') }}</a>
|
||||||
|
</li>
|
||||||
|
<li class="tab" @click="setActiveTab('PAYMENTS')">
|
||||||
|
<a :class="['tab-link', {'a-active': activeTab === 'PAYMENTS'}]" href="#">{{ $t('settings.customization.payments.title') }}</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<!-- Invoices Tab -->
|
||||||
|
<transition name="fade-customize">
|
||||||
|
<div v-if="activeTab === 'INVOICES'" class="invoice-tab">
|
||||||
|
<form action="" class="form-section" @submit.prevent="updateInvoiceSetting">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12 mb-4">
|
||||||
|
<label class="input-label">{{ $t('settings.customization.invoices.invoice_prefix') }}</label>
|
||||||
|
<base-input
|
||||||
|
v-model="invoices.invoice_prefix"
|
||||||
|
:invalid="$v.invoices.invoice_prefix.$error"
|
||||||
|
class="prefix-input"
|
||||||
|
@input="$v.invoices.invoice_prefix.$touch()"
|
||||||
|
@keyup="changeToUppercase('INVOICES')"
|
||||||
|
/>
|
||||||
|
<span v-show="!$v.invoices.invoice_prefix.required" class="text-danger mt-1">{{ $t('validation.required') }}</span>
|
||||||
|
<span v-if="!$v.invoices.invoice_prefix.maxLength" class="text-danger">{{ $t('validation.prefix_maxlength') }}</span>
|
||||||
|
<span v-if="!$v.invoices.invoice_prefix.alpha" class="text-danger">{{ $t('validation.characters_only') }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<base-button
|
||||||
|
icon="save"
|
||||||
|
color="theme"
|
||||||
|
type="submit"
|
||||||
|
>
|
||||||
|
{{ $t('settings.customization.save') }}
|
||||||
|
</base-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
</form>
|
||||||
|
<div class="col-md-12 mt-3">
|
||||||
|
<div class="page-header">
|
||||||
|
<h3 class="page-title">
|
||||||
|
{{ $t('settings.customization.invoices.invoice_settings') }}
|
||||||
|
</h3>
|
||||||
|
<div class="flex-box">
|
||||||
|
<div class="left">
|
||||||
|
<base-switch
|
||||||
|
v-model="invoiceAutogenerate"
|
||||||
|
class="btn-switch"
|
||||||
|
@change="setInvoiceSetting"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="right ml-15">
|
||||||
|
<p class="box-title"> {{ $t('settings.customization.invoices.autogenerate_invoice_number') }} </p>
|
||||||
|
<p class="box-desc"> {{ $t('settings.customization.invoices.invoice_setting_description') }} </p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
|
||||||
|
<!-- Estimates Tab -->
|
||||||
|
<transition name="fade-customize">
|
||||||
|
<div v-if="activeTab === 'ESTIMATES'" class="estimate-tab">
|
||||||
|
<form action="" class="form-section" @submit.prevent="updateEstimateSetting">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12 mb-4">
|
||||||
|
<label class="input-label">{{ $t('settings.customization.estimates.estimate_prefix') }}</label>
|
||||||
|
<base-input
|
||||||
|
v-model="estimates.estimate_prefix"
|
||||||
|
:invalid="$v.estimates.estimate_prefix.$error"
|
||||||
|
class="prefix-input"
|
||||||
|
@input="$v.estimates.estimate_prefix.$touch()"
|
||||||
|
@keyup="changeToUppercase('ESTIMATES')"
|
||||||
|
/>
|
||||||
|
<span v-show="!$v.estimates.estimate_prefix.required" class="text-danger mt-1">{{ $t('validation.required') }}</span>
|
||||||
|
<span v-if="!$v.estimates.estimate_prefix.maxLength" class="text-danger">{{ $t('validation.prefix_maxlength') }}</span>
|
||||||
|
<span v-if="!$v.estimates.estimate_prefix.alpha" class="text-danger">{{ $t('validation.characters_only') }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<base-button
|
||||||
|
icon="save"
|
||||||
|
color="theme"
|
||||||
|
type="submit"
|
||||||
|
>
|
||||||
|
{{ $t('settings.customization.save') }}
|
||||||
|
</base-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
</form>
|
||||||
|
<div class="col-md-12 mt-3">
|
||||||
|
<div class="page-header">
|
||||||
|
<h3 class="page-title">
|
||||||
|
{{ $t('settings.customization.estimates.estimate_settings') }}
|
||||||
|
</h3>
|
||||||
|
<div class="flex-box">
|
||||||
|
<div class="left">
|
||||||
|
<base-switch
|
||||||
|
v-model="estimateAutogenerate"
|
||||||
|
class="btn-switch"
|
||||||
|
@change="setEstimateSetting"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="right ml-15">
|
||||||
|
<p class="box-title"> {{ $t('settings.customization.estimates.autogenerate_estimate_number') }} </p>
|
||||||
|
<p class="box-desc"> {{ $t('settings.customization.estimates.estimate_setting_description') }} </p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
|
||||||
|
<!-- Payments Tab -->
|
||||||
|
<transition name="fade-customize">
|
||||||
|
<div v-if="activeTab === 'PAYMENTS'" class="payment-tab">
|
||||||
|
<form action="" class="form-section" @submit.prevent="updatePaymentSetting">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12 mb-4">
|
||||||
|
<label class="input-label">{{ $t('settings.customization.payments.payment_prefix') }}</label>
|
||||||
|
<base-input
|
||||||
|
v-model="payments.payment_prefix"
|
||||||
|
:invalid="$v.payments.payment_prefix.$error"
|
||||||
|
class="prefix-input"
|
||||||
|
@input="$v.payments.payment_prefix.$touch()"
|
||||||
|
@keyup="changeToUppercase('PAYMENTS')"
|
||||||
|
/>
|
||||||
|
<span v-show="!$v.payments.payment_prefix.required" class="text-danger mt-1">{{ $t('validation.required') }}</span>
|
||||||
|
<span v-if="!$v.payments.payment_prefix.maxLength" class="text-danger">{{ $t('validation.prefix_maxlength') }}</span>
|
||||||
|
<span v-if="!$v.payments.payment_prefix.alpha" class="text-danger">{{ $t('validation.characters_only') }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<base-button
|
||||||
|
icon="save"
|
||||||
|
color="theme"
|
||||||
|
type="submit"
|
||||||
|
>
|
||||||
|
{{ $t('settings.customization.save') }}
|
||||||
|
</base-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<hr>
|
||||||
|
<div class="col-md-12 mt-4">
|
||||||
|
<div class="page-header">
|
||||||
|
<h3 class="page-title">
|
||||||
|
{{ $t('settings.customization.payments.payment_settings') }}
|
||||||
|
</h3>
|
||||||
|
<div class="flex-box">
|
||||||
|
<div class="left">
|
||||||
|
<base-switch
|
||||||
|
v-model="paymentAutogenerate"
|
||||||
|
class="btn-switch"
|
||||||
|
@change="setPaymentSetting"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="right ml-15">
|
||||||
|
<p class="box-title"> {{ $t('settings.customization.payments.autogenerate_payment_number') }} </p>
|
||||||
|
<p class="box-desc"> {{ $t('settings.customization.payments.payment_setting_description') }} </p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { validationMixin } from 'vuelidate'
|
||||||
|
const { required, maxLength, alpha } = require('vuelidate/lib/validators')
|
||||||
|
export default {
|
||||||
|
mixins: [validationMixin],
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
activeTab: 'INVOICES',
|
||||||
|
invoiceAutogenerate: false,
|
||||||
|
estimateAutogenerate: false,
|
||||||
|
paymentAutogenerate: false,
|
||||||
|
invoices: {
|
||||||
|
invoice_prefix: null,
|
||||||
|
invoice_notes: null,
|
||||||
|
invoice_terms_and_conditions: null
|
||||||
|
},
|
||||||
|
estimates: {
|
||||||
|
estimate_prefix: null,
|
||||||
|
estimate_notes: null,
|
||||||
|
estimate_terms_and_conditions: null
|
||||||
|
},
|
||||||
|
payments: {
|
||||||
|
payment_prefix: null
|
||||||
|
},
|
||||||
|
currentData: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
activeTab () {
|
||||||
|
this.loadData()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
validations: {
|
||||||
|
invoices: {
|
||||||
|
invoice_prefix: {
|
||||||
|
required,
|
||||||
|
maxLength: maxLength(5),
|
||||||
|
alpha
|
||||||
|
}
|
||||||
|
},
|
||||||
|
estimates: {
|
||||||
|
estimate_prefix: {
|
||||||
|
required,
|
||||||
|
maxLength: maxLength(5),
|
||||||
|
alpha
|
||||||
|
}
|
||||||
|
},
|
||||||
|
payments: {
|
||||||
|
payment_prefix: {
|
||||||
|
required,
|
||||||
|
maxLength: maxLength(5),
|
||||||
|
alpha
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
this.loadData()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async setInvoiceSetting () {
|
||||||
|
let data = {
|
||||||
|
key: 'invoice_auto_generate',
|
||||||
|
value: this.invoiceAutogenerate ? 'YES' : 'NO'
|
||||||
|
}
|
||||||
|
let response = await window.axios.put('/api/settings/update-setting', data)
|
||||||
|
if (response.data) {
|
||||||
|
window.toastr['success'](this.$t('general.setting_updated'))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async setEstimateSetting () {
|
||||||
|
let data = {
|
||||||
|
key: 'estimate_auto_generate',
|
||||||
|
value: this.estimateAutogenerate ? 'YES' : 'NO'
|
||||||
|
}
|
||||||
|
let response = await window.axios.put('/api/settings/update-setting', data)
|
||||||
|
if (response.data) {
|
||||||
|
window.toastr['success'](this.$t('general.setting_updated'))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
changeToUppercase (currentTab) {
|
||||||
|
if (currentTab === 'INVOICES') {
|
||||||
|
this.invoices.invoice_prefix = this.invoices.invoice_prefix.toUpperCase()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentTab === 'ESTIMATES') {
|
||||||
|
this.estimates.estimate_prefix = this.estimates.estimate_prefix.toUpperCase()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentTab === 'PAYMENTS') {
|
||||||
|
this.payments.payment_prefix = this.payments.payment_prefix.toUpperCase()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async setPaymentSetting () {
|
||||||
|
let data = {
|
||||||
|
key: 'payment_auto_generate',
|
||||||
|
value: this.paymentAutogenerate ? 'YES' : 'NO'
|
||||||
|
}
|
||||||
|
let response = await window.axios.put('/api/settings/update-setting', data)
|
||||||
|
if (response.data) {
|
||||||
|
window.toastr['success'](this.$t('general.setting_updated'))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async loadData () {
|
||||||
|
let res = await window.axios.get('/api/settings/get-customize-setting')
|
||||||
|
|
||||||
|
if (res.data) {
|
||||||
|
this.invoices.invoice_prefix = res.data.invoice_prefix
|
||||||
|
this.invoices.invoice_notes = res.data.invoice_notes
|
||||||
|
this.invoices.invoice_terms_and_conditions = res.data.invoice_terms_and_conditions
|
||||||
|
this.estimates.estimate_prefix = res.data.estimate_prefix
|
||||||
|
this.estimates.estimate_notes = res.data.estimate_notes
|
||||||
|
this.estimates.estimate_terms_and_conditions = res.data.estimate_terms_and_conditions
|
||||||
|
this.payments.payment_prefix = res.data.payment_prefix
|
||||||
|
|
||||||
|
if (res.data.invoice_auto_generate === 'YES') {
|
||||||
|
this.invoiceAutogenerate = true
|
||||||
|
} else {
|
||||||
|
this.invoiceAutogenerate = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.data.estimate_auto_generate === 'YES') {
|
||||||
|
this.estimateAutogenerate = true
|
||||||
|
} else {
|
||||||
|
this.estimateAutogenerate = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.data.payment_auto_generate === 'YES') {
|
||||||
|
this.paymentAutogenerate = true
|
||||||
|
} else {
|
||||||
|
this.paymentAutogenerate = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async updateInvoiceSetting () {
|
||||||
|
this.$v.invoices.$touch()
|
||||||
|
|
||||||
|
if (this.$v.invoices.$invalid) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = {type: 'INVOICES', ...this.invoices}
|
||||||
|
|
||||||
|
if (this.updateSetting(data)) {
|
||||||
|
window.toastr['success'](this.$t('settings.customization.invoices.invoice_setting_updated'))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async updateEstimateSetting () {
|
||||||
|
this.$v.estimates.$touch()
|
||||||
|
|
||||||
|
if (this.$v.estimates.$invalid) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = {type: 'ESTIMATES', ...this.estimates}
|
||||||
|
|
||||||
|
if (this.updateSetting(data)) {
|
||||||
|
window.toastr['success'](this.$t('settings.customization.estimates.estimate_setting_updated'))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async updatePaymentSetting () {
|
||||||
|
this.$v.payments.$touch()
|
||||||
|
|
||||||
|
if (this.$v.payments.$invalid) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = {type: 'PAYMENTS', ...this.payments}
|
||||||
|
|
||||||
|
if (this.updateSetting(data)) {
|
||||||
|
window.toastr['success'](this.$t('settings.customization.payments.payment_setting_updated'))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async updateSetting (data) {
|
||||||
|
let res = await window.axios.put('/api/settings/update-customize-setting', data)
|
||||||
|
|
||||||
|
if (res.data.success) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
setActiveTab (val) {
|
||||||
|
this.activeTab = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
.fade-customize-enter-active {
|
||||||
|
transition: opacity 0.9s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-customize-leave-active {
|
||||||
|
transition: opacity 0s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-customize-enter, .fade-customize-leave-to /* .fade-leave-active below version 2.1.8 */ {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -45,6 +45,12 @@ export default {
|
|||||||
icon: 'building',
|
icon: 'building',
|
||||||
iconType: 'far'
|
iconType: 'far'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
link: '/admin/settings/customization',
|
||||||
|
title: 'settings.menu_title.customization',
|
||||||
|
icon: 'edit',
|
||||||
|
iconType: 'fa'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
link: '/admin/settings/preferences',
|
link: '/admin/settings/preferences',
|
||||||
title: 'settings.menu_title.preferences',
|
title: 'settings.menu_title.preferences',
|
||||||
|
|||||||
@ -203,8 +203,10 @@ export default {
|
|||||||
this.$emit('next')
|
this.$emit('next')
|
||||||
window.toastr['success'](this.$t('wizard.success.' + response.data.success))
|
window.toastr['success'](this.$t('wizard.success.' + response.data.success))
|
||||||
return true
|
return true
|
||||||
} else {
|
} else if (response.data.error) {
|
||||||
window.toastr['error'](this.$t('wizard.errors.' + response.data.error))
|
window.toastr['error'](this.$t('wizard.errors.' + response.data.error))
|
||||||
|
} else if (response.data.error_message) {
|
||||||
|
window.toastr['error'](response.data.error_message)
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
window.toastr['error'](e.response.data.message)
|
window.toastr['error'](e.response.data.message)
|
||||||
|
|||||||
@ -54,7 +54,7 @@
|
|||||||
/>
|
/>
|
||||||
<div v-if="$v.profileData.email.$error">
|
<div v-if="$v.profileData.email.$error">
|
||||||
<span v-if="!$v.profileData.email.required" class="text-danger">{{ $tc('validation.required') }}</span>
|
<span v-if="!$v.profileData.email.required" class="text-danger">{{ $tc('validation.required') }}</span>
|
||||||
<span v-if="!$v.profileData.email.email" class="text-danger">{{ $tc('validation.required') }}</span>
|
<span v-if="!$v.profileData.email.email" class="text-danger">{{ $tc('validation.email_incorrect') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -145,7 +145,7 @@ export default {
|
|||||||
},
|
},
|
||||||
password: {
|
password: {
|
||||||
required,
|
required,
|
||||||
minLength: minLength(5)
|
minLength: minLength(8)
|
||||||
},
|
},
|
||||||
confirm_password: {
|
confirm_password: {
|
||||||
required: requiredIf('isRequired'),
|
required: requiredIf('isRequired'),
|
||||||
|
|||||||
54
resources/assets/sass/components/base/base-prefix-input.scss
vendored
Normal file
54
resources/assets/sass/components/base/base-prefix-input.scss
vendored
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
.base-prefix-input {
|
||||||
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
padding: 2px 2px;
|
||||||
|
flex-direction: row;
|
||||||
|
background: #FFFFFF;
|
||||||
|
border: 1px solid $ls-color-gray--light;
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
width: 13px;
|
||||||
|
height: 18px;
|
||||||
|
color: $ls-color-gray;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 900;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 16px;
|
||||||
|
margin-top: 17px;
|
||||||
|
margin-left: 20px;
|
||||||
|
z-index: 1;
|
||||||
|
transform: translate(-50%,-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
padding: 0 0 0 0;
|
||||||
|
margin: 0 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prefix-label {
|
||||||
|
display: flex;
|
||||||
|
height: 18px;
|
||||||
|
color: #55547A;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 16px;
|
||||||
|
padding: 9px 2px 9px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prefix-input-field {
|
||||||
|
width: 100%;
|
||||||
|
padding: 8px 13px;
|
||||||
|
padding-left: 1px;
|
||||||
|
text-align: left;
|
||||||
|
background: #FFFFFF;
|
||||||
|
border: none;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 21px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
2
resources/assets/sass/crater.scss
vendored
2
resources/assets/sass/crater.scss
vendored
@ -48,6 +48,7 @@
|
|||||||
@import 'components/base/base-text-area';
|
@import 'components/base/base-text-area';
|
||||||
@import "components/base/base-switch";
|
@import "components/base/base-switch";
|
||||||
@import 'components/base/base-loader/index';
|
@import 'components/base/base-loader/index';
|
||||||
|
@import 'components/base/base-prefix-input';
|
||||||
|
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
@ -91,6 +92,7 @@
|
|||||||
@import 'pages/login';
|
@import 'pages/login';
|
||||||
@import 'pages/login-3';
|
@import 'pages/login-3';
|
||||||
@import 'pages/404';
|
@import 'pages/404';
|
||||||
|
@import 'pages/customization';
|
||||||
@import 'pages/settings';
|
@import 'pages/settings';
|
||||||
@import 'pages/invoices/create';
|
@import 'pages/invoices/create';
|
||||||
@import 'pages/invoices/view';
|
@import 'pages/invoices/view';
|
||||||
|
|||||||
39
resources/assets/sass/pages/customization.scss
vendored
Normal file
39
resources/assets/sass/pages/customization.scss
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
.customization {
|
||||||
|
|
||||||
|
.prefix-input {
|
||||||
|
max-width: 30%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-section {
|
||||||
|
padding: 8px 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.invoice-customization-card {
|
||||||
|
border: 1px solid #EBF1FA;border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: $x-small-breakpoint) {
|
||||||
|
.address-customization-card {
|
||||||
|
|
||||||
|
.address-fields-container {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
.fields-list {
|
||||||
|
border-right: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabs {
|
||||||
|
|
||||||
|
.tab {
|
||||||
|
padding: 10px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -3,9 +3,11 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>Estimate</title>
|
<title>Estimate</title>
|
||||||
{{-- <link href="https://fonts.googleapis.com/css?family=Poppins&display=swap" rel="stylesheet"> --}}
|
{{-- <link href="https://fonts.googleapis.com/css?family=Poppins&display=swap" rel="stylesheet"> --}}
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||||
|
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
body {
|
body {
|
||||||
font-family: 'Roboto', sans-serif;
|
font-family: "DejaVu Sans";
|
||||||
}
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
@ -58,13 +60,11 @@
|
|||||||
margin-left:160px;
|
margin-left:160px;
|
||||||
}
|
}
|
||||||
.header {
|
.header {
|
||||||
font-family: 'Roboto', sans-serif;
|
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
color: rgba(0, 0, 0, 0.7);
|
color: rgba(0, 0, 0, 0.7);
|
||||||
}
|
}
|
||||||
|
|
||||||
.TextColor1 {
|
.TextColor1 {
|
||||||
font-family: 'Roboto', sans-serif;
|
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
color: rgba(0, 0, 0, 0.5);
|
color: rgba(0, 0, 0, 0.5);
|
||||||
}
|
}
|
||||||
@ -339,7 +339,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.notes {
|
.notes {
|
||||||
font-family: 'Roboto', sans-serif;
|
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
@ -352,7 +351,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.notes-label {
|
.notes-label {
|
||||||
font-family: 'Roboto', sans-serif;
|
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
@ -410,7 +408,7 @@
|
|||||||
<div class="bill-address-container">
|
<div class="bill-address-container">
|
||||||
@include('app.pdf.estimate.partials.billing-address')
|
@include('app.pdf.estimate.partials.billing-address')
|
||||||
</div>
|
</div>
|
||||||
@if($estimate->user->billingaddress && ($estimate->user->billingaddress->name || $estimate->user->billingaddress->address_street_1 || $estimate->user->billingaddress->address_street_2 || $estimate->user->billingaddress->country || $estimate->user->billingaddress->state || $estimate->user->billingaddress->city || $estimate->user->billingaddress->zip || $estimate->user->billingaddress->phone))
|
@if($estimate->user->billingaddress)
|
||||||
<div class="ship-address-container">
|
<div class="ship-address-container">
|
||||||
@else
|
@else
|
||||||
<div class="ship-address-container " style="float:left;padding-left:0px;">
|
<div class="ship-address-container " style="float:left;padding-left:0px;">
|
||||||
|
|||||||
@ -3,9 +3,11 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>Estimate</title>
|
<title>Estimate</title>
|
||||||
{{-- <link href="https://fonts.googleapis.com/css?family=Poppins&display=swap" rel="stylesheet"> --}}
|
{{-- <link href="https://fonts.googleapis.com/css?family=Poppins&display=swap" rel="stylesheet"> --}}
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||||
|
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
body {
|
body {
|
||||||
font-family: 'Roboto', sans-serif;
|
font-family: "DejaVu Sans";
|
||||||
}
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
@ -62,13 +64,11 @@
|
|||||||
margin-left:160px;
|
margin-left:160px;
|
||||||
}
|
}
|
||||||
.header {
|
.header {
|
||||||
font-family: 'Roboto', sans-serif;
|
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
color: rgba(0, 0, 0, 0.7);
|
color: rgba(0, 0, 0, 0.7);
|
||||||
}
|
}
|
||||||
|
|
||||||
.TextColor1 {
|
.TextColor1 {
|
||||||
font-family: 'Roboto', sans-serif;
|
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
color: rgba(0, 0, 0, 0.5);
|
color: rgba(0, 0, 0, 0.5);
|
||||||
}
|
}
|
||||||
@ -364,7 +364,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.notes {
|
.notes {
|
||||||
font-family: 'Roboto', sans-serif;
|
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
@ -377,7 +376,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.notes-label {
|
.notes-label {
|
||||||
font-family: 'Roboto', sans-serif;
|
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
@ -421,7 +419,7 @@
|
|||||||
<div class="ship-address-container">
|
<div class="ship-address-container">
|
||||||
@include('app.pdf.estimate.partials.shipping-address')
|
@include('app.pdf.estimate.partials.shipping-address')
|
||||||
</div>
|
</div>
|
||||||
@if($estimate->user->shippingaddress && ($estimate->user->shippingaddress->name || $estimate->user->shippingaddress->address_street_1 || $estimate->user->shippingaddress->address_street_2 || $estimate->user->shippingaddress->country || $estimate->user->shippingaddress->state || $estimate->user->shippingaddress->city || $estimate->user->shippingaddress->zip || $estimate->user->phone))
|
@if($estimate->user->shippingaddress)
|
||||||
<div class="bill-address-container">
|
<div class="bill-address-container">
|
||||||
@else
|
@else
|
||||||
<div class="bill-address-container" style="float:right;padding-right:0px;">
|
<div class="bill-address-container" style="float:right;padding-right:0px;">
|
||||||
|
|||||||
@ -3,9 +3,11 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>Estimate</title>
|
<title>Estimate</title>
|
||||||
{{-- <link href="https://fonts.googleapis.com/css?family=Poppins&display=swap" rel="stylesheet"> --}}
|
{{-- <link href="https://fonts.googleapis.com/css?family=Poppins&display=swap" rel="stylesheet"> --}}
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||||
|
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
body {
|
body {
|
||||||
font-family: 'Roboto', sans-serif;
|
font-family: "DejaVu Sans";
|
||||||
}
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
@ -64,13 +66,11 @@
|
|||||||
margin-left:160px;
|
margin-left:160px;
|
||||||
}
|
}
|
||||||
.header {
|
.header {
|
||||||
font-family: 'Roboto', sans-serif;
|
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
color: rgba(0, 0, 0, 0.7);
|
color: rgba(0, 0, 0, 0.7);
|
||||||
}
|
}
|
||||||
|
|
||||||
.TextColor1 {
|
.TextColor1 {
|
||||||
font-family: 'Roboto', sans-serif;
|
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
color: rgba(0, 0, 0, 0.5);
|
color: rgba(0, 0, 0, 0.5);
|
||||||
}
|
}
|
||||||
@ -372,7 +372,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.notes {
|
.notes {
|
||||||
font-family: 'Roboto', sans-serif;
|
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
@ -385,7 +384,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.notes-label {
|
.notes-label {
|
||||||
font-family: 'Roboto', sans-serif;
|
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
@ -426,7 +424,7 @@
|
|||||||
<div style="float:left;">
|
<div style="float:left;">
|
||||||
@include('app.pdf.estimate.partials.billing-address')
|
@include('app.pdf.estimate.partials.billing-address')
|
||||||
</div>
|
</div>
|
||||||
@if($estimate->user->billingaddress && ($estimate->user->billingaddress->name || $estimate->user->billingaddress->address_street_1 || $estimate->user->billingaddress->address_street_2 || $estimate->user->billingaddress->country || $estimate->user->billingaddress->state || $estimate->user->billingaddress->city || $estimate->user->billingaddress->zip || $estimate->user->billingaddress->phone))
|
@if($estimate->user->billingaddress)
|
||||||
<div style="float:right;">
|
<div style="float:right;">
|
||||||
@else
|
@else
|
||||||
<div style="float:left;">
|
<div style="float:left;">
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
@if($estimate->user->billingaddress)
|
@if($estimate->user->billingaddress)
|
||||||
@if($estimate->user->billingaddress->name || $estimate->user->billingaddress->address_street_1 || $estimate->user->billingaddress->address_street_2 || $estimate->user->billingaddress->country || $estimate->user->billingaddress->state || $estimate->user->billingaddress->city || $estimate->user->billingaddress->zip || $estimate->user->billingaddress->phone)
|
|
||||||
<p class="bill-to">Bill To,</p>
|
<p class="bill-to">Bill To,</p>
|
||||||
@endif
|
|
||||||
@if($estimate->user->billingaddress->name)
|
@if($estimate->user->billingaddress->name)
|
||||||
<p class="bill-user-name">
|
<p class="bill-user-name">
|
||||||
{{$estimate->user->billingaddress->name}}
|
{{$estimate->user->billingaddress->name}}
|
||||||
@ -16,11 +14,11 @@
|
|||||||
{{$estimate->user->billingaddress->address_street_2}}<br>
|
{{$estimate->user->billingaddress->address_street_2}}<br>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if($estimate->user->billingaddress->city && $estimate->user->billingaddress->city)
|
@if($estimate->user->billingaddress->city)
|
||||||
{{$estimate->user->billingaddress->city}},
|
{{$estimate->user->billingaddress->city}},
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if($estimate->user->billingaddress->state && $estimate->user->billingaddress->state)
|
@if($estimate->user->billingaddress->state)
|
||||||
{{$estimate->user->billingaddress->state}}.
|
{{$estimate->user->billingaddress->state}}.
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
@if($estimate->user->shippingaddress)
|
@if($estimate->user->shippingaddress)
|
||||||
@if($estimate->user->shippingaddress->name || $estimate->user->shippingaddress->address_street_1 || $estimate->user->shippingaddress->address_street_2 || $estimate->user->shippingaddress->country || $estimate->user->shippingaddress->state || $estimate->user->shippingaddress->city || $estimate->user->shippingaddress->zip || $estimate->user->phone)
|
|
||||||
<p class="ship-to">Ship To,</p>
|
<p class="ship-to">Ship To,</p>
|
||||||
@endif
|
|
||||||
@if($estimate->user->shippingaddress->name)
|
@if($estimate->user->shippingaddress->name)
|
||||||
<p class="ship-user-name">
|
<p class="ship-user-name">
|
||||||
{{$estimate->user->shippingaddress->name}}
|
{{$estimate->user->shippingaddress->name}}
|
||||||
|
|||||||
@ -18,24 +18,48 @@
|
|||||||
@endphp
|
@endphp
|
||||||
@foreach ($estimate->items as $item)
|
@foreach ($estimate->items as $item)
|
||||||
<tr class="item-details">
|
<tr class="item-details">
|
||||||
<td class="inv-item items" style="text-align: right; color: #040405; padding-right: 20px; vertical-align: top;">{{$index}}</td>
|
<td
|
||||||
<td class="inv-item items" style="text-align: left; color: #040405;padding-left: 0px">
|
class="inv-item items"
|
||||||
<span>{{ $item->name }}</span><br>
|
style="text-align: right; color: #040405; padding-right: 20px; vertical-align: top;"
|
||||||
<span style="text-align: left; color: #595959; font-size: 9px; font-weight:300; line-height: 12px;">{{ $item->description }}</span>
|
>
|
||||||
|
{{$index}}
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
class="inv-item items"
|
||||||
|
style="text-align: left; color: #040405;padding-left: 0px"
|
||||||
|
>
|
||||||
|
<span>{{ $item->name }}</span><br>
|
||||||
|
<span
|
||||||
|
style="text-align: left; color: #595959; font-size: 9px; font-weight:300; line-height: 12px;"
|
||||||
|
>
|
||||||
|
{{ $item->description }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
class="inv-item items"
|
||||||
|
style="text-align: right; color: #040405; padding-right: 20px"
|
||||||
|
>
|
||||||
|
{{$item->quantity}}
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
class="inv-item items"
|
||||||
|
style="text-align: right; color: #040405; padding-right: 40px"
|
||||||
|
>
|
||||||
|
{!! format_money_pdf($item->price, $estimate->user->currency) !!}
|
||||||
</td>
|
</td>
|
||||||
<td class="inv-item items" style="text-align: right; color: #040405; padding-right: 20px">{{$item->quantity}}</td>
|
|
||||||
<td class="inv-item items" style="text-align: right; color: #040405; padding-right: 40px">{{$item->price/100}}</td>
|
|
||||||
@if($estimate->discount_per_item === 'YES')
|
@if($estimate->discount_per_item === 'YES')
|
||||||
<td class="inv-item items" style="text-align: right; color: #040405; padding-left: 10px">
|
<td class="inv-item items" style="text-align: right; color: #040405; padding-left: 10px">
|
||||||
@if($item->discount_type === 'fixed')
|
@if($item->discount_type === 'fixed')
|
||||||
{{$item->discount_val/100}}
|
{!! format_money_pdf($item->discount_val, $estimate->user->currency) !!}
|
||||||
@endif
|
@endif
|
||||||
@if($item->discount_type === 'percentage')
|
@if($item->discount_type === 'percentage')
|
||||||
{{$item->discount}}%
|
{{$item->discount}}%
|
||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
@endif
|
@endif
|
||||||
<td class="inv-item items" style="text-align: right; color: #040405;">{{$item->total/100}}</td>
|
<td class="inv-item items" style="text-align: right; color: #040405;">
|
||||||
|
{!! format_money_pdf($item->total, $estimate->user->currency) !!}
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@php
|
@php
|
||||||
$index += 1
|
$index += 1
|
||||||
@ -47,7 +71,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td class="no-borde" style="color: #55547A; padding-left:10px; font-size:12px;">Subtotal</td>
|
<td class="no-borde" style="color: #55547A; padding-left:10px; font-size:12px;">Subtotal</td>
|
||||||
<td class="no-border items"
|
<td class="no-border items"
|
||||||
style="padding-right:10px; text-align: right; font-size:12px; color: #040405; font-weight: 500;">{!! format_money_pdf($estimate->sub_total) !!}</td>
|
style="padding-right:10px; text-align: right; font-size:12px; color: #040405; font-weight: 500;">{!! format_money_pdf($estimate->sub_total, $estimate->user->currency) !!}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
@if ($estimate->tax_per_item === 'YES')
|
@if ($estimate->tax_per_item === 'YES')
|
||||||
@ -57,7 +81,7 @@
|
|||||||
{{$labels[$i]}}
|
{{$labels[$i]}}
|
||||||
</td>
|
</td>
|
||||||
<td class="no-border items padd2" style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; color: #040405">
|
<td class="no-border items padd2" style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; color: #040405">
|
||||||
{!! format_money_pdf($taxes[$i]) !!}
|
{!! format_money_pdf($taxes[$i], $estimate->user->currency) !!}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endfor
|
@endfor
|
||||||
@ -68,7 +92,7 @@
|
|||||||
{{$tax->name.' ('.$tax->percent.'%)'}}
|
{{$tax->name.' ('.$tax->percent.'%)'}}
|
||||||
</td>
|
</td>
|
||||||
<td class="no-border items padd2" style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; color: #040405">
|
<td class="no-border items padd2" style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; color: #040405">
|
||||||
{!! format_money_pdf($tax->amount) !!}
|
{!! format_money_pdf($tax->amount, $estimate->user->currency) !!}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
@ -77,14 +101,19 @@
|
|||||||
@if ($estimate->discount_per_item === 'NO')
|
@if ($estimate->discount_per_item === 'NO')
|
||||||
<tr>
|
<tr>
|
||||||
<td class="no-border" style="padding-left:10px; text-align:left; font-size:12px; color: #55547A;">
|
<td class="no-border" style="padding-left:10px; text-align:left; font-size:12px; color: #55547A;">
|
||||||
|
@if($estimate->discount_type === 'fixed')
|
||||||
|
Discount
|
||||||
|
@endif
|
||||||
|
@if($estimate->discount_type === 'percentage')
|
||||||
Discount ({{$estimate->discount}}%)
|
Discount ({{$estimate->discount}}%)
|
||||||
|
@endif
|
||||||
</td>
|
</td>
|
||||||
<td class="no-border items padd2" style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; color: #040405">
|
<td class="no-border items padd2" style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; color: #040405">
|
||||||
@if($estimate->discount_type === 'fixed')
|
@if($estimate->discount_type === 'fixed')
|
||||||
{!! format_money_pdf($estimate->discount_val) !!}
|
{!! format_money_pdf($estimate->discount_val, $estimate->user->currency) !!}
|
||||||
@endif
|
@endif
|
||||||
@if($estimate->discount_type === 'percentage')
|
@if($estimate->discount_type === 'percentage')
|
||||||
{!! format_money_pdf($estimate->discount_val) !!}
|
{!! format_money_pdf($estimate->discount_val, $estimate->user->currency) !!}
|
||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -103,7 +132,7 @@
|
|||||||
class="no-border total-border-right items padd8"
|
class="no-border total-border-right items padd8"
|
||||||
style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; padding-top:20px; color: #5851DB"
|
style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; padding-top:20px; color: #5851DB"
|
||||||
>
|
>
|
||||||
{!! format_money_pdf($estimate->total)!!}
|
{!! format_money_pdf($estimate->total, $estimate->user->currency)!!}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@ -3,9 +3,11 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>Invoice</title>
|
<title>Invoice</title>
|
||||||
{{-- <link href="https://fonts.googleapis.com/css?family=Poppins&display=swap" rel="stylesheet"> --}}
|
{{-- <link href="https://fonts.googleapis.com/css?family=Poppins&display=swap" rel="stylesheet"> --}}
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||||
|
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
body {
|
body {
|
||||||
font-family: 'Roboto', sans-serif;
|
font-family: "DejaVu Sans";
|
||||||
}
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
@ -59,13 +61,11 @@
|
|||||||
margin-left:160px;
|
margin-left:160px;
|
||||||
}
|
}
|
||||||
.header {
|
.header {
|
||||||
font-family: 'Roboto', sans-serif;
|
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
color: rgba(0, 0, 0, 0.7);
|
color: rgba(0, 0, 0, 0.7);
|
||||||
}
|
}
|
||||||
|
|
||||||
.TextColor1 {
|
.TextColor1 {
|
||||||
font-family: 'Roboto', sans-serif;
|
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
color: rgba(0, 0, 0, 0.5);
|
color: rgba(0, 0, 0, 0.5);
|
||||||
}
|
}
|
||||||
@ -346,7 +346,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.notes {
|
.notes {
|
||||||
font-family: 'Roboto', sans-serif;
|
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
@ -359,7 +358,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.notes-label {
|
.notes-label {
|
||||||
font-family: 'Roboto', sans-serif;
|
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
@ -416,9 +414,8 @@
|
|||||||
<div class="bill-add">
|
<div class="bill-add">
|
||||||
<div class="bill-address-container">
|
<div class="bill-address-container">
|
||||||
@include('app.pdf.invoice.partials.billing-address')
|
@include('app.pdf.invoice.partials.billing-address')
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@if($invoice->user->billingaddress->name || $invoice->user->billingaddress->address_street_1 || $invoice->user->billingaddress->address_street_2 || $invoice->user->billingaddress->country || $invoice->user->billingaddress->state || $invoice->user->billingaddress->city || $invoice->user->billingaddress->zip || $invoice->user->billingaddress->phone)
|
@if($invoice->user->billingaddress)
|
||||||
<div class="ship-address-container">
|
<div class="ship-address-container">
|
||||||
@else
|
@else
|
||||||
<div class="ship-address-container " style="float:left;padding-left:0px;">
|
<div class="ship-address-container " style="float:left;padding-left:0px;">
|
||||||
|
|||||||
@ -3,9 +3,10 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>Invoice</title>
|
<title>Invoice</title>
|
||||||
{{-- <link href="https://fonts.googleapis.com/css?family=Poppins&display=swap" rel="stylesheet"> --}}
|
{{-- <link href="https://fonts.googleapis.com/css?family=Poppins&display=swap" rel="stylesheet"> --}}
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
body {
|
body {
|
||||||
font-family: 'Roboto', sans-serif;
|
font-family: "DejaVu Sans";
|
||||||
}
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
@ -61,13 +62,11 @@
|
|||||||
margin-left:160px;
|
margin-left:160px;
|
||||||
}
|
}
|
||||||
.header {
|
.header {
|
||||||
font-family: 'Roboto', sans-serif;
|
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
color: rgba(0, 0, 0, 0.7);
|
color: rgba(0, 0, 0, 0.7);
|
||||||
}
|
}
|
||||||
|
|
||||||
.TextColor1 {
|
.TextColor1 {
|
||||||
font-family: 'Roboto', sans-serif;
|
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
color: rgba(0, 0, 0, 0.5);
|
color: rgba(0, 0, 0, 0.5);
|
||||||
}
|
}
|
||||||
@ -373,7 +372,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.notes {
|
.notes {
|
||||||
font-family: 'Roboto', sans-serif;
|
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
@ -386,7 +384,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.notes-label {
|
.notes-label {
|
||||||
font-family: 'Roboto', sans-serif;
|
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
@ -431,7 +428,7 @@
|
|||||||
<div class="ship-address-container">
|
<div class="ship-address-container">
|
||||||
@include('app.pdf.invoice.partials.shipping-address')
|
@include('app.pdf.invoice.partials.shipping-address')
|
||||||
</div>
|
</div>
|
||||||
@if($invoice->user->shippingaddress->name || $invoice->user->shippingaddress->address_street_1 || $invoice->user->shippingaddress->address_street_2 || $invoice->user->shippingaddress->country || $invoice->user->shippingaddress->state || $invoice->user->shippingaddress->city || $invoice->user->shippingaddress->zip || $invoice->user->phone)
|
@if($invoice->user->shippingaddress)
|
||||||
<div class="bill-address-container">
|
<div class="bill-address-container">
|
||||||
@else
|
@else
|
||||||
<div class="bill-address-container" style="float:right;padding-right:0px;">
|
<div class="bill-address-container" style="float:right;padding-right:0px;">
|
||||||
|
|||||||
@ -3,9 +3,11 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>Invoice</title>
|
<title>Invoice</title>
|
||||||
{{-- <link href="https://fonts.googleapis.com/css?family=Poppins&display=swap" rel="stylesheet"> --}}
|
{{-- <link href="https://fonts.googleapis.com/css?family=Poppins&display=swap" rel="stylesheet"> --}}
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||||
|
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
body {
|
body {
|
||||||
font-family: 'Roboto', sans-serif;
|
font-family: "DejaVu Sans";
|
||||||
}
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
@ -64,13 +66,11 @@
|
|||||||
margin-left:160px;
|
margin-left:160px;
|
||||||
}
|
}
|
||||||
.header {
|
.header {
|
||||||
font-family: 'Roboto', sans-serif;
|
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
color: rgba(0, 0, 0, 0.7);
|
color: rgba(0, 0, 0, 0.7);
|
||||||
}
|
}
|
||||||
|
|
||||||
.TextColor1 {
|
.TextColor1 {
|
||||||
font-family: 'Roboto', sans-serif;
|
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
color: rgba(0, 0, 0, 0.5);
|
color: rgba(0, 0, 0, 0.5);
|
||||||
}
|
}
|
||||||
@ -382,7 +382,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.notes {
|
.notes {
|
||||||
font-family: 'Roboto', sans-serif;
|
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
@ -395,7 +394,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.notes-label {
|
.notes-label {
|
||||||
font-family: 'Roboto', sans-serif;
|
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
@ -436,7 +434,7 @@
|
|||||||
<div style="float:left;">
|
<div style="float:left;">
|
||||||
@include('app.pdf.invoice.partials.billing-address')
|
@include('app.pdf.invoice.partials.billing-address')
|
||||||
</div>
|
</div>
|
||||||
@if($invoice->user->billingaddress->name || $invoice->user->billingaddress->address_street_1 || $invoice->user->billingaddress->address_street_2 || $invoice->user->billingaddress->country || $invoice->user->billingaddress->state || $invoice->user->billingaddress->city || $invoice->user->billingaddress->zip || $invoice->user->billingaddress->phone)
|
@if($invoice->user->billingaddress)
|
||||||
<div style="float:right;">
|
<div style="float:right;">
|
||||||
@else
|
@else
|
||||||
<div style="float:left;">
|
<div style="float:left;">
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
@if($invoice->user->billingaddress)
|
@if($invoice->user->billingaddress)
|
||||||
@if($invoice->user->billingaddress->name || $invoice->user->billingaddress->address_street_1 || $invoice->user->billingaddress->address_street_2 || $invoice->user->billingaddress->country || $invoice->user->billingaddress->state || $invoice->user->billingaddress->city || $invoice->user->billingaddress->zip || $invoice->user->billingaddress->phone)
|
|
||||||
<p class="bill-to">Bill To,</p>
|
<p class="bill-to">Bill To,</p>
|
||||||
@endif
|
|
||||||
@if($invoice->user->billingaddress->name)
|
@if($invoice->user->billingaddress->name)
|
||||||
<p class="bill-user-name">
|
<p class="bill-user-name">
|
||||||
{{$invoice->user->billingaddress->name}}
|
{{$invoice->user->billingaddress->name}}
|
||||||
|
|||||||
@ -3,6 +3,6 @@
|
|||||||
<div class="notes-label">
|
<div class="notes-label">
|
||||||
Notes
|
Notes
|
||||||
</div>
|
</div>
|
||||||
{{$invoice->notes}}
|
{!! $invoice->notes !!}
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
@if($invoice->user->shippingaddress)
|
@if($invoice->user->shippingaddress)
|
||||||
@if($invoice->user->shippingaddress->name || $invoice->user->shippingaddress->address_street_1 || $invoice->user->shippingaddress->address_street_2 || $invoice->user->shippingaddress->country || $invoice->user->shippingaddress->state || $invoice->user->shippingaddress->city || $invoice->user->shippingaddress->zip || $invoice->user->phone)
|
|
||||||
<p class="ship-to">Ship To,</p>
|
<p class="ship-to">Ship To,</p>
|
||||||
@endif
|
|
||||||
@if($invoice->user->shippingaddress->name)
|
@if($invoice->user->shippingaddress->name)
|
||||||
<p class="ship-user-name">
|
<p class="ship-user-name">
|
||||||
{{$invoice->user->shippingaddress->name}}
|
{{$invoice->user->shippingaddress->name}}
|
||||||
|
|||||||
@ -18,24 +18,47 @@
|
|||||||
@endphp
|
@endphp
|
||||||
@foreach ($invoice->items as $item)
|
@foreach ($invoice->items as $item)
|
||||||
<tr class="item-details">
|
<tr class="item-details">
|
||||||
<td class="inv-item items" style="text-align: right; color: #040405; padding-right: 20px; vertical-align: top;">{{$index}}</td>
|
<td
|
||||||
<td class="inv-item items" style="text-align: left; color: #040405;padding-left: 0px">
|
class="inv-item items"
|
||||||
|
style="text-align: right; color: #040405; padding-right: 20px; vertical-align: top;"
|
||||||
|
>
|
||||||
|
{{$index}}
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
class="inv-item items"
|
||||||
|
style="text-align: left; color: #040405;padding-left: 0px"
|
||||||
|
>
|
||||||
<span>{{ $item->name }}</span><br>
|
<span>{{ $item->name }}</span><br>
|
||||||
<span style="text-align: left; color: #595959; font-size: 9px; font-weight:300; line-height: 12px;">{{ $item->description }}</span>
|
<span style="text-align: left; color: #595959; font-size: 9px; font-weight:300; line-height: 12px;">{{ $item->description }}</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="inv-item items" style="text-align: right; color: #040405; padding-right: 20px">{{$item->quantity}}</td>
|
<td
|
||||||
<td class="inv-item items" style="text-align: right; color: #040405; padding-right: 40px">{{$item->price/100}}</td>
|
class="inv-item items"
|
||||||
|
style="text-align: right; color: #040405; padding-right: 20px"
|
||||||
|
>
|
||||||
|
{{$item->quantity}}
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
class="inv-item items"
|
||||||
|
style="text-align: right; color: #040405; padding-right: 40px"
|
||||||
|
>
|
||||||
|
{!! format_money_pdf($item->price, $invoice->user->currency) !!}
|
||||||
|
</td>
|
||||||
@if($invoice->discount_per_item === 'YES')
|
@if($invoice->discount_per_item === 'YES')
|
||||||
<td class="inv-item items" style="text-align: right; color: #040405; padding-left: 10px">
|
<td class="inv-item items" style="text-align: right; color: #040405; padding-left: 10px">
|
||||||
@if($item->discount_type === 'fixed')
|
@if($item->discount_type === 'fixed')
|
||||||
{{$item->discount_val/100}}
|
{!! format_money_pdf($item->discount_val, $invoice->user->currency) !!}
|
||||||
@endif
|
@endif
|
||||||
@if($item->discount_type === 'percentage')
|
@if($item->discount_type === 'percentage')
|
||||||
{{$item->discount}}%
|
{{$item->discount}}%
|
||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
@endif
|
@endif
|
||||||
<td class="inv-item items" style="text-align: right; color: #040405;">{{$item->total/100}}</td>
|
<td
|
||||||
|
class="inv-item items"
|
||||||
|
style="text-align: right; color: #040405;"
|
||||||
|
>
|
||||||
|
{!! format_money_pdf($item->total, $invoice->user->currency) !!}
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@php
|
@php
|
||||||
$index += 1
|
$index += 1
|
||||||
@ -47,7 +70,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td class="no-borde" style="color: #55547A; padding-left:10px; font-size:12px;">Subtotal</td>
|
<td class="no-borde" style="color: #55547A; padding-left:10px; font-size:12px;">Subtotal</td>
|
||||||
<td class="no-border items"
|
<td class="no-border items"
|
||||||
style="padding-right:10px; text-align: right; font-size:12px; color: #040405; font-weight: 500;">{!! format_money_pdf($invoice->sub_total) !!}</td>
|
style="padding-right:10px; text-align: right; font-size:12px; color: #040405; font-weight: 500;">{!! format_money_pdf($invoice->sub_total, $invoice->user->currency) !!}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
@if ($invoice->tax_per_item === 'YES')
|
@if ($invoice->tax_per_item === 'YES')
|
||||||
@ -57,7 +80,7 @@
|
|||||||
{{$labels[$i]}}
|
{{$labels[$i]}}
|
||||||
</td>
|
</td>
|
||||||
<td class="no-border items padd2" style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; color: #040405">
|
<td class="no-border items padd2" style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; color: #040405">
|
||||||
{!! format_money_pdf($taxes[$i]) !!}
|
{!! format_money_pdf($taxes[$i], $invoice->user->currency) !!}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endfor
|
@endfor
|
||||||
@ -68,7 +91,7 @@
|
|||||||
{{$tax->name.' ('.$tax->percent.'%)'}}
|
{{$tax->name.' ('.$tax->percent.'%)'}}
|
||||||
</td>
|
</td>
|
||||||
<td class="no-border items padd2" style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; color: #040405">
|
<td class="no-border items padd2" style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; color: #040405">
|
||||||
{!! format_money_pdf($tax->amount) !!}
|
{!! format_money_pdf($tax->amount, $invoice->user->currency) !!}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
@ -77,14 +100,19 @@
|
|||||||
@if ($invoice->discount_per_item === 'NO')
|
@if ($invoice->discount_per_item === 'NO')
|
||||||
<tr>
|
<tr>
|
||||||
<td class="no-border" style="padding-left:10px; text-align:left; font-size:12px; color: #55547A;">
|
<td class="no-border" style="padding-left:10px; text-align:left; font-size:12px; color: #55547A;">
|
||||||
|
@if($invoice->discount_type === 'fixed')
|
||||||
|
Discount
|
||||||
|
@endif
|
||||||
|
@if($invoice->discount_type === 'percentage')
|
||||||
Discount ({{$invoice->discount}}%)
|
Discount ({{$invoice->discount}}%)
|
||||||
|
@endif
|
||||||
</td>
|
</td>
|
||||||
<td class="no-border items padd2" style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; color: #040405">
|
<td class="no-border items padd2" style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; color: #040405">
|
||||||
@if($invoice->discount_type === 'fixed')
|
@if($invoice->discount_type === 'fixed')
|
||||||
{!! format_money_pdf($invoice->discount_val) !!}
|
{!! format_money_pdf($invoice->discount_val, $invoice->user->currency) !!}
|
||||||
@endif
|
@endif
|
||||||
@if($invoice->discount_type === 'percentage')
|
@if($invoice->discount_type === 'percentage')
|
||||||
{!! format_money_pdf($invoice->discount_val) !!}
|
{!! format_money_pdf($invoice->discount_val, $invoice->user->currency) !!}
|
||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -103,7 +131,7 @@
|
|||||||
class="no-border total-border-right items padd8"
|
class="no-border total-border-right items padd8"
|
||||||
style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; padding-top:20px; color: #5851DB"
|
style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; padding-top:20px; color: #5851DB"
|
||||||
>
|
>
|
||||||
{!! format_money_pdf($invoice->total)!!}
|
{!! format_money_pdf($invoice->total, $invoice->user->currency)!!}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
{{-- <link href="https://fonts.googleapis.com/css?family=Poppins&display=swap" rel="stylesheet"> --}}
|
{{-- <link href="https://fonts.googleapis.com/css?family=Poppins&display=swap" rel="stylesheet"> --}}
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
body {
|
body {
|
||||||
font-family: 'Roboto', sans-serif;
|
font-family: "DejaVu Sans";
|
||||||
}
|
}
|
||||||
|
|
||||||
/* html {
|
/* html {
|
||||||
@ -181,10 +181,14 @@
|
|||||||
@foreach ($expenseCategories as $expenseCategory)
|
@foreach ($expenseCategories as $expenseCategory)
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<p class="expense-title">{{ $expenseCategory->category->name }}</p>
|
<p class="expense-title">
|
||||||
|
{{ $expenseCategory->category->name }}
|
||||||
|
</p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p class="expense-money">{!! format_money_pdf($expenseCategory->total_amount) !!}</p>
|
<p class="expense-money">
|
||||||
|
{!! format_money_pdf($expenseCategory->total_amount) !!}
|
||||||
|
</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
{{-- <link href="https://fonts.googleapis.com/css?family=Poppins&display=swap" rel="stylesheet"> --}}
|
{{-- <link href="https://fonts.googleapis.com/css?family=Poppins&display=swap" rel="stylesheet"> --}}
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
body {
|
body {
|
||||||
font-family: 'Roboto', sans-serif;
|
font-family: "DejaVu Sans";
|
||||||
}
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
@ -220,10 +220,14 @@
|
|||||||
@foreach ($expenseCategories as $expenseCategory)
|
@foreach ($expenseCategories as $expenseCategory)
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<p class="expense-title">{{ $expenseCategory->category->name }}</p>
|
<p class="expense-title">
|
||||||
|
{{ $expenseCategory->category->name }}
|
||||||
|
</p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p class="expense-money">{!! format_money_pdf($expenseCategory->total_amount) !!}</p>
|
<p class="expense-money">
|
||||||
|
{!! format_money_pdf($expenseCategory->total_amount) !!}
|
||||||
|
</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
{{-- <link href="https://fonts.googleapis.com/css?family=Poppins&display=swap" rel="stylesheet"> --}}
|
{{-- <link href="https://fonts.googleapis.com/css?family=Poppins&display=swap" rel="stylesheet"> --}}
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
body {
|
body {
|
||||||
font-family: 'Roboto', sans-serif;
|
font-family: "DejaVu Sans";
|
||||||
}
|
}
|
||||||
|
|
||||||
/* html {
|
/* html {
|
||||||
@ -223,10 +223,14 @@
|
|||||||
@foreach ($customer->invoices as $invoice)
|
@foreach ($customer->invoices as $invoice)
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<p class="expense-title">{{ $invoice->formattedInvoiceDate }} ({{ $invoice->invoice_number }})</p>
|
<p class="expense-title">
|
||||||
|
{{ $invoice->formattedInvoiceDate }} ({{ $invoice->invoice_number }})
|
||||||
|
</p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p class="expense-money">{!! format_money_pdf($invoice->total) !!}</p>
|
<p class="expense-money">
|
||||||
|
{!! format_money_pdf($invoice->total) !!}
|
||||||
|
</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
@ -235,7 +239,9 @@
|
|||||||
<table class="expense-total-table">
|
<table class="expense-total-table">
|
||||||
<tr>
|
<tr>
|
||||||
<td class="expense-total-cell">
|
<td class="expense-total-cell">
|
||||||
<p class="expense-total">{!! format_money_pdf($customer->totalAmount) !!}</p>
|
<p class="expense-total">
|
||||||
|
{!! format_money_pdf($customer->totalAmount) !!}
|
||||||
|
</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@ -249,7 +255,9 @@
|
|||||||
<p class="profit-title">TOTAL SALES</p>
|
<p class="profit-title">TOTAL SALES</p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p class="profit-money">{!! format_money_pdf($totalAmount) !!}</p>
|
<p class="profit-money">
|
||||||
|
{!! format_money_pdf($totalAmount) !!}
|
||||||
|
</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
{{-- <link href="https://fonts.googleapis.com/css?family=Poppins&display=swap" rel="stylesheet"> --}}
|
{{-- <link href="https://fonts.googleapis.com/css?family=Poppins&display=swap" rel="stylesheet"> --}}
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
body {
|
body {
|
||||||
font-family: 'Roboto', sans-serif;
|
font-family: "DejaVu Sans";
|
||||||
}
|
}
|
||||||
|
|
||||||
/* html {
|
/* html {
|
||||||
@ -222,10 +222,14 @@
|
|||||||
<table class="expenses-table">
|
<table class="expenses-table">
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<p class="expense-title">{{ $item->name }}</p>
|
<p class="expense-title">
|
||||||
|
{{ $item->name }}
|
||||||
|
</p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p class="expense-money">{!! format_money_pdf($item->total_amount) !!}</p>
|
<p class="expense-money">
|
||||||
|
{!! format_money_pdf($item->total_amount) !!}
|
||||||
|
</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@ -235,7 +239,9 @@
|
|||||||
<table class="expense-total-table">
|
<table class="expense-total-table">
|
||||||
<tr>
|
<tr>
|
||||||
<td class="expense-total-cell">
|
<td class="expense-total-cell">
|
||||||
<p class="expense-total">{!! format_money_pdf($totalAmount) !!}</p>
|
<p class="expense-total">
|
||||||
|
{!! format_money_pdf($totalAmount) !!}
|
||||||
|
</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@ -248,7 +254,9 @@
|
|||||||
<p class="profit-title">TOTAL SALES</p>
|
<p class="profit-title">TOTAL SALES</p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p class="profit-money">{!! format_money_pdf($totalAmount) !!}</p>
|
<p class="profit-money">
|
||||||
|
{!! format_money_pdf($totalAmount) !!}
|
||||||
|
</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
{{-- <link href="https://fonts.googleapis.com/css?family=Poppins&display=swap" rel="stylesheet"> --}}
|
{{-- <link href="https://fonts.googleapis.com/css?family=Poppins&display=swap" rel="stylesheet"> --}}
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
body {
|
body {
|
||||||
font-family: 'Roboto', sans-serif;
|
font-family: "DejaVu Sans";
|
||||||
}
|
}
|
||||||
|
|
||||||
/* html {
|
/* html {
|
||||||
@ -174,10 +174,14 @@
|
|||||||
<table class="header">
|
<table class="header">
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<p class="heading-text">{{ $company->name }}</p>
|
<p class="heading-text">
|
||||||
|
{{ $company->name }}
|
||||||
|
</p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p class="heading-date-range">{{ $from_date }} - {{ $to_date }}</p>
|
<p class="heading-date-range">
|
||||||
|
{{ $from_date }} - {{ $to_date }}
|
||||||
|
</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@ -192,10 +196,14 @@
|
|||||||
@foreach ($taxTypes as $tax)
|
@foreach ($taxTypes as $tax)
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<p class="tax-title">{{ $tax->taxType->name }}</p>
|
<p class="tax-title">
|
||||||
|
{{ $tax->taxType->name }}
|
||||||
|
</p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p class="tax-money">{!! format_money_pdf($tax->total_tax_amount) !!}</p>
|
<p class="tax-money">
|
||||||
|
{!! format_money_pdf($tax->total_tax_amount) !!}
|
||||||
|
</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
@ -207,7 +215,9 @@
|
|||||||
<table class="tax-total-table">
|
<table class="tax-total-table">
|
||||||
<tr>
|
<tr>
|
||||||
<td class="tax-total-cell">
|
<td class="tax-total-cell">
|
||||||
<p class="tax-total">{!! format_money_pdf($totalTaxAmount) !!}</p>
|
<p class="tax-total">
|
||||||
|
{!! format_money_pdf($totalTaxAmount) !!}
|
||||||
|
</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@ -217,7 +227,9 @@
|
|||||||
<p class="total-tax-title">TOTAL TAX</p>
|
<p class="total-tax-title">TOTAL TAX</p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p class="total-tax-money">{!! format_money_pdf($totalTaxAmount) !!}</p>
|
<p class="total-tax-money">
|
||||||
|
{!! format_money_pdf($totalTaxAmount) !!}
|
||||||
|
</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@ -348,6 +348,16 @@ Route::group(['middleware' => 'api'], function () {
|
|||||||
'uses' => 'CompanyController@updateSetting'
|
'uses' => 'CompanyController@updateSetting'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
Route::get('/get-customize-setting', [
|
||||||
|
'as' => 'admin.get.customize.setting',
|
||||||
|
'uses' => 'CompanyController@getCustomizeSetting'
|
||||||
|
]);
|
||||||
|
|
||||||
|
Route::put('/update-customize-setting', [
|
||||||
|
'as' => 'admin.update.customize.setting',
|
||||||
|
'uses' => 'CompanyController@updateCustomizeSetting'
|
||||||
|
]);
|
||||||
|
|
||||||
Route::get('/environment/mail', [
|
Route::get('/environment/mail', [
|
||||||
'as' => 'admin.environment.mail',
|
'as' => 'admin.environment.mail',
|
||||||
'uses' => 'EnvironmentController@getMailDrivers'
|
'uses' => 'EnvironmentController@getMailDrivers'
|
||||||
|
|||||||
Reference in New Issue
Block a user