Merge branch 'version-200' into 'dev'

Version 200

See merge request mohit.panjvani/crater-web!85
This commit is contained in:
Mohit Panjwani
2019-11-27 06:02:38 +00:00
48 changed files with 607 additions and 53926 deletions

View File

@ -4,8 +4,6 @@ namespace Crater;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Crater\User; use Crater\User;
use Crater\Country; use Crater\Country;
use Crater\State;
use Crater\City;
class Address extends Model class Address extends Model
{ {
@ -16,8 +14,8 @@ class Address extends Model
'name', 'name',
'address_street_1', 'address_street_1',
'address_street_2', 'address_street_2',
'city_id', 'city',
'state_id', 'state',
'country_id', 'country_id',
'zip', 'zip',
'phone', 'phone',
@ -35,14 +33,4 @@ class Address extends Model
{ {
return $this->belongsTo(Country::class); return $this->belongsTo(Country::class);
} }
public function state()
{
return $this->belongsTo(State::class);
}
public function city()
{
return $this->belongsTo(City::class);
}
} }

View File

@ -1,18 +0,0 @@
<?php
namespace Crater;
use Illuminate\Database\Eloquent\Model;
use Crater\State;
class City extends Model
{
public function state()
{
return $this->belongsTo(State::class);
}
public function address()
{
return $this->hasMany(Address::class);
}
}

View File

@ -2,15 +2,9 @@
namespace Crater; namespace Crater;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Crater\State;
class Country extends Model class Country extends Model
{ {
public function states()
{
return $this->hasMany(State::class);
}
public function address() public function address()
{ {
return $this->hasMany(Address::class); return $this->hasMany(Address::class);

View File

@ -56,7 +56,7 @@ class CompanyController extends Controller
public function getAdminCompany() public function getAdminCompany()
{ {
$user = User::with(['addresses', 'addresses.country', 'addresses.state', 'addresses.city', 'company'])->find(1); $user = User::with(['addresses', 'addresses.country', 'company'])->find(1);
return response()->json([ return response()->json([
'user' => $user 'user' => $user
@ -75,9 +75,9 @@ class CompanyController extends Controller
$company->addMediaFromRequest('logo')->toMediaCollection('logo'); $company->addMediaFromRequest('logo')->toMediaCollection('logo');
} }
$fields = $request->only(['address_street_1', 'address_street_2', 'city_id', 'state_id', 'country_id', 'zip', 'phone']); $fields = $request->only(['address_street_1', 'address_street_2', 'city', 'state', 'country_id', 'zip', 'phone']);
$address = Address::updateOrCreate(['user_id' => 1], $fields); $address = Address::updateOrCreate(['user_id' => 1], $fields);
$user = User::with(['addresses', 'addresses.country', 'addresses.state', 'addresses.city', 'company'])->find(1); $user = User::with(['addresses', 'addresses.country', 'company'])->find(1);
return response()->json([ return response()->json([
'user' => $user, 'user' => $user,

View File

@ -80,8 +80,8 @@ class CustomersController extends Controller
$newAddress->name = $address["name"]; $newAddress->name = $address["name"];
$newAddress->address_street_1 = $address["address_street_1"]; $newAddress->address_street_1 = $address["address_street_1"];
$newAddress->address_street_2 = $address["address_street_2"]; $newAddress->address_street_2 = $address["address_street_2"];
$newAddress->city_id = $address["city_id"]; $newAddress->city = $address["city"];
$newAddress->state_id = $address["state_id"]; $newAddress->state = $address["state"];
$newAddress->country_id = $address["country_id"]; $newAddress->country_id = $address["country_id"];
$newAddress->zip = $address["zip"]; $newAddress->zip = $address["zip"];
$newAddress->phone = $address["phone"]; $newAddress->phone = $address["phone"];
@ -187,8 +187,8 @@ class CustomersController extends Controller
$newAddress->name = $address["name"]; $newAddress->name = $address["name"];
$newAddress->address_street_1 = $address["address_street_1"]; $newAddress->address_street_1 = $address["address_street_1"];
$newAddress->address_street_2 = $address["address_street_2"]; $newAddress->address_street_2 = $address["address_street_2"];
$newAddress->city_id = $address["city_id"]; $newAddress->city = $address["city"];
$newAddress->state_id = $address["state_id"]; $newAddress->state = $address["state"];
$newAddress->country_id = $address["country_id"]; $newAddress->country_id = $address["country_id"];
$newAddress->zip = $address["zip"]; $newAddress->zip = $address["zip"];
$newAddress->phone = $address["phone"]; $newAddress->phone = $address["phone"];

View File

@ -90,7 +90,7 @@ class FrontendController extends Controller
} }
} }
$companyAddress = User::with(['addresses', 'addresses.country', 'addresses.state', 'addresses.city'])->find(1); $companyAddress = User::with(['addresses', 'addresses.country'])->find(1);
$colors = [ $colors = [
'invoice_primary_color', 'invoice_primary_color',
@ -189,7 +189,7 @@ class FrontendController extends Controller
} }
} }
$companyAddress = User::with(['addresses', 'addresses.country', 'addresses.state', 'addresses.city'])->find(1); $companyAddress = User::with(['addresses', 'addresses.country'])->find(1);
$colors = [ $colors = [
'invoice_primary_color', 'invoice_primary_color',
@ -262,7 +262,7 @@ class FrontendController extends Controller
$estimateTemplate = EstimateTemplate::find($estimate->estimate_template_id); $estimateTemplate = EstimateTemplate::find($estimate->estimate_template_id);
$company = Company::find($estimate->company_id); $company = Company::find($estimate->company_id);
$companyAddress = User::with(['addresses', 'addresses.country', 'addresses.state', 'addresses.city'])->find(1); $companyAddress = User::with(['addresses', 'addresses.country'])->find(1);
$logo = $company->getMedia('logo')->first(); $logo = $company->getMedia('logo')->first();
if($logo) { if($logo) {
@ -338,7 +338,7 @@ class FrontendController extends Controller
$invoiceTemplate = InvoiceTemplate::find($invoice->invoice_template_id); $invoiceTemplate = InvoiceTemplate::find($invoice->invoice_template_id);
$company = Company::find($invoice->company_id); $company = Company::find($invoice->company_id);
$companyAddress = User::with(['addresses', 'addresses.country', 'addresses.state', 'addresses.city'])->find(1); $companyAddress = User::with(['addresses', 'addresses.country'])->find(1);
$logo = $company->getMedia('logo')->first(); $logo = $company->getMedia('logo')->first();

View File

@ -3,8 +3,6 @@ namespace Crater\Http\Controllers;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Crater\Country; use Crater\Country;
use Crater\State;
use Crater\City;
class LocationController extends Controller class LocationController extends Controller
{ {
@ -14,18 +12,4 @@ class LocationController extends Controller
'countries' => Country::all() 'countries' => Country::all()
]); ]);
} }
public function getStates($id)
{
return response()->json([
'states' => Country::find($id)->states
]);
}
public function getCities($id)
{
return response()->json([
'cities' => State::find($id)->cities
]);
}
} }

View File

@ -58,8 +58,6 @@ class OnboardingController extends Controller
$user = User::with([ $user = User::with([
'addresses', 'addresses',
'addresses.country', 'addresses.country',
'addresses.state',
'addresses.city',
'company' 'company'
])->find(1); ])->find(1);
@ -156,8 +154,8 @@ class OnboardingController extends Controller
$fields = $request->only([ $fields = $request->only([
'address_street_1', 'address_street_1',
'address_street_2', 'address_street_2',
'city_id', 'city',
'state_id', 'state',
'country_id', 'country_id',
'zip', 'zip',
'phone' 'phone'

View File

@ -12,10 +12,10 @@ class Listener
* @param $event * @param $event
* @return boolean * @return boolean
*/ */
protected function check($event) protected function isListenerFired($event)
{ {
// Do not apply to the same or newer versions // Do not apply to the same or newer versions
if (version_compare(static::VERSION, $event->old, '>')) { if (version_compare(static::VERSION, $event->old, '<')) {
return true; return true;
} }

View File

@ -5,9 +5,11 @@ namespace Crater\Listeners\Updates\v1;
use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\InteractsWithQueue;
use Crater\Events\UpdateFinished; use Crater\Events\UpdateFinished;
use Crater\Listeners\Updates\Listener;
use Crater\Setting; use Crater\Setting;
use Crater\Currency;
class Version110 class Version110 extends Listener
{ {
const VERSION = '1.1.0'; const VERSION = '1.1.0';
@ -29,11 +31,85 @@ class Version110
*/ */
public function handle(UpdateFinished $event) public function handle(UpdateFinished $event)
{ {
if (!$this->check($event)) { if ($this->isListenerFired($event)) {
return; return;
} }
// Add currencies
$this->addCurrencies();
// Update Crater app version // Update Crater app version
Setting::setSetting('version', static::VERSION); Setting::setSetting('version', static::VERSION);
} }
private function addCurrencies() {
$currencies = [
'13' => [
'symbol' => 'S$'
],
'16' => [
'symbol' => '₫'
],
'17' => [
'symbol' => 'Fr.'
],
'21' => [
'symbol' => '฿'
],
'22' => [
'symbol' => '₦'
],
'26' => [
'symbol' => 'HK$'
],
'35' => [
'symbol' => 'NAƒ'
],
'38' => [
'symbol' => 'GH₵'
],
'39' => [
'symbol' => 'Лв.'
],
'42' => [
'symbol' => 'RON'
],
'44' => [
'symbol' => 'SِAR'
],
'46' => [
'symbol' => 'Rf'
],
'47' => [
'symbol' => '₡'
],
'54' => [
'symbol' => '‎د.ت'
],
'55' => [
'symbol' => '₽'
],
'57' => [
'symbol' => 'ر.ع.'
],
'58' => [
'symbol' => '₴'
],
];
foreach ($currencies as $key => $currency) {
Currency::updateOrCreate(['id' => $key], $currency);
}
Currency::create([
'name' => 'Kuwaiti Dinar',
'code' => 'KWD',
'symbol' => 'KWD ',
'precision' => '3',
'thousand_separator' => ',',
'decimal_separator' => '.'
]);
}
} }

View File

@ -0,0 +1,110 @@
<?php
namespace Crater\Listeners\Updates\v2;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Database\Schema\Blueprint;
use Crater\Listeners\Updates\Listener;
use Crater\Listeners\Updates\v2\Version200;
use Crater\Events\UpdateFinished;
use Crater\Setting;
use Crater\Address;
class Version200 extends Listener
{
const VERSION = '2.0.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;
}
// Replace state and city id to name
$this->replaceStateAndCityName();
// Drop states and cities foreign key
$this->dropForeignKey();
// Remove states and cities tables
$this->dropSchemas();
// Delete state & city models, migrations & seeders
$this->deleteFiles();
// Update Crater app version
$this->updateVersion();
}
private function replaceStateAndCityName() {
\Schema::table('addresses', function (Blueprint $table) {
$table->string('state')->nullable();
$table->string('city')->nullable();
});
$addresses = \Crater\Address::all();
foreach ($addresses as $add) {
$city = \Crater\City::find($add->city_id);
if($city) {
$add->city = $city->name;
}
$state = \Crater\State::find($add->state_id);
if($state) {
$add->state = $state->name;
}
$add->save();
}
}
private function dropForeignKey() {
\Schema::table('addresses', function (Blueprint $table) {
$table->dropForeign('addresses_state_id_foreign');
$table->dropForeign('addresses_city_id_foreign');
$table->dropColumn('state_id');
$table->dropColumn('city_id');
});
}
private function dropSchemas() {
\Schema::disableForeignKeyConstraints();
\Schema::dropIfExists('states');
\Schema::dropIfExists('cities');
\Schema::enableForeignKeyConstraints();
}
private function deleteFiles() {
\File::delete(
database_path('migrations/2017_05_06_172817_create_cities_table.php'),
database_path('migrations/2017_05_06_173711_create_states_table.php'),
database_path('seeds/StatesTableSeeder.php'),
database_path('seeds/CitiesTableSeeder.php'),
app_path('City.php'),
app_path('State.php')
);
}
private function updateVersion() {
Setting::setSetting('version', static::VERSION);
}
}

View File

@ -6,6 +6,7 @@ use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification; use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Crater\Events\UpdateFinished; use Crater\Events\UpdateFinished;
use Crater\Listeners\Updates\v1\Version110; use Crater\Listeners\Updates\v1\Version110;
use Crater\Listeners\Updates\v2\Version200;
class EventServiceProvider extends ServiceProvider class EventServiceProvider extends ServiceProvider
{ {
@ -17,6 +18,7 @@ class EventServiceProvider extends ServiceProvider
protected $listen = [ protected $listen = [
UpdateFinished::class=> [ UpdateFinished::class=> [
Version110::class, Version110::class,
Version200::class,
], ],
Registered::class => [ Registered::class => [
SendEmailVerificationNotification::class, SendEmailVerificationNotification::class,

View File

@ -1,25 +0,0 @@
<?php
namespace Crater;
use Illuminate\Database\Eloquent\Model;
use Crater\City;
use Crater\Country;
use Crater\Address;
class State extends Model
{
public function cities()
{
return $this->hasMany(City::class);
}
public function country()
{
return $this->belongsTo(Country::class);
}
public function address()
{
return $this->hasMany(Address::class);
}
}

View File

@ -10,6 +10,7 @@
"require": { "require": {
"php": "^7.2", "php": "^7.2",
"barryvdh/laravel-dompdf": "^0.8.1", "barryvdh/laravel-dompdf": "^0.8.1",
"doctrine/dbal": "^2.10",
"fideloper/proxy": "^4.0", "fideloper/proxy": "^4.0",
"guzzlehttp/guzzle": "^6.3", "guzzlehttp/guzzle": "^6.3",
"intervention/image": "^2.3", "intervention/image": "^2.3",

484
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "2a5e8d91a2be3144e2812dd708dc14b7", "content-hash": "e7cf4f0a8e1e7d60cc72b34ed4c730ce",
"packages": [ "packages": [
{ {
"name": "barryvdh/laravel-dompdf", "name": "barryvdh/laravel-dompdf",
@ -158,6 +158,247 @@
"description": "implementation of xdg base directory specification for php", "description": "implementation of xdg base directory specification for php",
"time": "2014-10-24T07:27:01+00:00" "time": "2014-10-24T07:27:01+00:00"
}, },
{
"name": "doctrine/cache",
"version": "v1.8.1",
"source": {
"type": "git",
"url": "https://github.com/doctrine/cache.git",
"reference": "d4374ae95b36062d02ef310100ed33d78738d76c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/cache/zipball/d4374ae95b36062d02ef310100ed33d78738d76c",
"reference": "d4374ae95b36062d02ef310100ed33d78738d76c",
"shasum": ""
},
"require": {
"php": "~7.1"
},
"conflict": {
"doctrine/common": ">2.2,<2.4"
},
"require-dev": {
"alcaeus/mongo-php-adapter": "^1.1",
"doctrine/coding-standard": "^4.0",
"mongodb/mongodb": "^1.1",
"phpunit/phpunit": "^7.0",
"predis/predis": "~1.0"
},
"suggest": {
"alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.8.x-dev"
}
},
"autoload": {
"psr-4": {
"Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
],
"description": "Caching library offering an object-oriented API for many cache backends",
"homepage": "https://www.doctrine-project.org",
"keywords": [
"cache",
"caching"
],
"time": "2019-10-28T09:31:32+00:00"
},
{
"name": "doctrine/dbal",
"version": "v2.10.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/dbal.git",
"reference": "0c9a646775ef549eb0a213a4f9bd4381d9b4d934"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/dbal/zipball/0c9a646775ef549eb0a213a4f9bd4381d9b4d934",
"reference": "0c9a646775ef549eb0a213a4f9bd4381d9b4d934",
"shasum": ""
},
"require": {
"doctrine/cache": "^1.0",
"doctrine/event-manager": "^1.0",
"ext-pdo": "*",
"php": "^7.2"
},
"require-dev": {
"doctrine/coding-standard": "^6.0",
"jetbrains/phpstorm-stubs": "^2019.1",
"phpstan/phpstan": "^0.11.3",
"phpunit/phpunit": "^8.4.1",
"symfony/console": "^2.0.5|^3.0|^4.0|^5.0"
},
"suggest": {
"symfony/console": "For helpful console commands such as SQL execution and import of files."
},
"bin": [
"bin/doctrine-dbal"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.10.x-dev",
"dev-develop": "3.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Doctrine\\DBAL\\": "lib/Doctrine/DBAL"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
}
],
"description": "Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.",
"homepage": "https://www.doctrine-project.org/projects/dbal.html",
"keywords": [
"abstraction",
"database",
"db2",
"dbal",
"mariadb",
"mssql",
"mysql",
"oci8",
"oracle",
"pdo",
"pgsql",
"postgresql",
"queryobject",
"sasql",
"sql",
"sqlanywhere",
"sqlite",
"sqlserver",
"sqlsrv"
],
"time": "2019-11-03T16:50:43+00:00"
},
{
"name": "doctrine/event-manager",
"version": "v1.0.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/event-manager.git",
"reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/event-manager/zipball/a520bc093a0170feeb6b14e9d83f3a14452e64b3",
"reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3",
"shasum": ""
},
"require": {
"php": "^7.1"
},
"conflict": {
"doctrine/common": "<2.9@dev"
},
"require-dev": {
"doctrine/coding-standard": "^4.0",
"phpunit/phpunit": "^7.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Doctrine\\Common\\": "lib/Doctrine/Common"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
},
{
"name": "Marco Pivetta",
"email": "ocramius@gmail.com"
}
],
"description": "Doctrine Event Manager component",
"homepage": "https://www.doctrine-project.org/projects/event-manager.html",
"keywords": [
"event",
"eventdispatcher",
"eventmanager"
],
"time": "2018-06-11T11:59:03+00:00"
},
{ {
"name": "doctrine/inflector", "name": "doctrine/inflector",
"version": "v1.3.0", "version": "v1.3.0",
@ -5307,247 +5548,6 @@
], ],
"time": "2019-05-27T17:52:04+00:00" "time": "2019-05-27T17:52:04+00:00"
}, },
{
"name": "doctrine/cache",
"version": "v1.8.1",
"source": {
"type": "git",
"url": "https://github.com/doctrine/cache.git",
"reference": "d4374ae95b36062d02ef310100ed33d78738d76c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/cache/zipball/d4374ae95b36062d02ef310100ed33d78738d76c",
"reference": "d4374ae95b36062d02ef310100ed33d78738d76c",
"shasum": ""
},
"require": {
"php": "~7.1"
},
"conflict": {
"doctrine/common": ">2.2,<2.4"
},
"require-dev": {
"alcaeus/mongo-php-adapter": "^1.1",
"doctrine/coding-standard": "^4.0",
"mongodb/mongodb": "^1.1",
"phpunit/phpunit": "^7.0",
"predis/predis": "~1.0"
},
"suggest": {
"alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.8.x-dev"
}
},
"autoload": {
"psr-4": {
"Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
],
"description": "Caching library offering an object-oriented API for many cache backends",
"homepage": "https://www.doctrine-project.org",
"keywords": [
"cache",
"caching"
],
"time": "2019-10-28T09:31:32+00:00"
},
{
"name": "doctrine/dbal",
"version": "v2.10.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/dbal.git",
"reference": "0c9a646775ef549eb0a213a4f9bd4381d9b4d934"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/dbal/zipball/0c9a646775ef549eb0a213a4f9bd4381d9b4d934",
"reference": "0c9a646775ef549eb0a213a4f9bd4381d9b4d934",
"shasum": ""
},
"require": {
"doctrine/cache": "^1.0",
"doctrine/event-manager": "^1.0",
"ext-pdo": "*",
"php": "^7.2"
},
"require-dev": {
"doctrine/coding-standard": "^6.0",
"jetbrains/phpstorm-stubs": "^2019.1",
"phpstan/phpstan": "^0.11.3",
"phpunit/phpunit": "^8.4.1",
"symfony/console": "^2.0.5|^3.0|^4.0|^5.0"
},
"suggest": {
"symfony/console": "For helpful console commands such as SQL execution and import of files."
},
"bin": [
"bin/doctrine-dbal"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.10.x-dev",
"dev-develop": "3.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Doctrine\\DBAL\\": "lib/Doctrine/DBAL"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
}
],
"description": "Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.",
"homepage": "https://www.doctrine-project.org/projects/dbal.html",
"keywords": [
"abstraction",
"database",
"db2",
"dbal",
"mariadb",
"mssql",
"mysql",
"oci8",
"oracle",
"pdo",
"pgsql",
"postgresql",
"queryobject",
"sasql",
"sql",
"sqlanywhere",
"sqlite",
"sqlserver",
"sqlsrv"
],
"time": "2019-11-03T16:50:43+00:00"
},
{
"name": "doctrine/event-manager",
"version": "v1.0.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/event-manager.git",
"reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/event-manager/zipball/a520bc093a0170feeb6b14e9d83f3a14452e64b3",
"reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3",
"shasum": ""
},
"require": {
"php": "^7.1"
},
"conflict": {
"doctrine/common": "<2.9@dev"
},
"require-dev": {
"doctrine/coding-standard": "^4.0",
"phpunit/phpunit": "^7.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Doctrine\\Common\\": "lib/Doctrine/Common"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
},
{
"name": "Marco Pivetta",
"email": "ocramius@gmail.com"
}
],
"description": "Doctrine Event Manager component",
"homepage": "https://www.doctrine-project.org/projects/event-manager.html",
"keywords": [
"event",
"eventdispatcher",
"eventmanager"
],
"time": "2018-06-11T11:59:03+00:00"
},
{ {
"name": "doctrine/instantiator", "name": "doctrine/instantiator",
"version": "1.2.0", "version": "1.2.0",

View File

@ -4,11 +4,11 @@ return [
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Crater Requirements | Crater Configuration
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| |
*/ */
'version' => '1.1.0', 'version' => '2.0.0',
]; ];

View File

@ -10,9 +10,9 @@ $factory->define(Address::class, function (Faker $faker) {
'name' => $faker->name, 'name' => $faker->name,
'address_street_1' => $faker->streetAddress, 'address_street_1' => $faker->streetAddress,
'address_street_2' => $faker->streetAddress, 'address_street_2' => $faker->streetAddress,
'city_id' => 5909, 'city' => $faker->city,
'state_id' => 42, 'state' => $faker->state,
'country_id' => 1, 'country_id' => 231,
'zip' => $faker->postcode, 'zip' => $faker->postcode,
'phone' => $faker->phoneNumber, 'phone' => $faker->phoneNumber,
'fax' => $faker->phoneNumber, 'fax' => $faker->phoneNumber,

View File

@ -1,33 +0,0 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateCitiesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('cities', function (Blueprint $table) {
$table->engine = 'InnoDB';
$table->increments('id')->index();
$table->string('name');
$table->integer('state_id');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('cities');
}
}

View File

@ -1,32 +0,0 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateStatesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('states', function (Blueprint $table) {
$table->increments('id')->index();
$table->string('name');
$table->integer('country_id');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('states');
}
}

View File

@ -18,10 +18,8 @@ class CreateAddressesTable extends Migration
$table->string('name')->nullable(); $table->string('name')->nullable();
$table->string('address_street_1')->nullable(); $table->string('address_street_1')->nullable();
$table->string('address_street_2')->nullable(); $table->string('address_street_2')->nullable();
$table->integer('city_id')->unsigned()->nullable(); $table->string('city')->nullable();
$table->foreign('city_id')->references('id')->on('cities'); $table->string('state')->nullable();
$table->integer('state_id')->unsigned()->nullable();
$table->foreign('state_id')->references('id')->on('states');
$table->integer('country_id')->unsigned()->nullable(); $table->integer('country_id')->unsigned()->nullable();
$table->foreign('country_id')->references('id')->on('countries'); $table->foreign('country_id')->references('id')->on('countries');
$table->string('zip')->nullable(); $table->string('zip')->nullable();

File diff suppressed because it is too large Load Diff

View File

@ -122,7 +122,7 @@ class CurrenciesTableSeeder extends Seeder
[ [
'name' => 'Singapore Dollar', 'name' => 'Singapore Dollar',
'code' => 'SGD', 'code' => 'SGD',
'symbol' => '', 'symbol' => 'S$',
'precision' => '2', 'precision' => '2',
'thousand_separator' => ',', 'thousand_separator' => ',',
'decimal_separator' => '.' 'decimal_separator' => '.'
@ -147,7 +147,7 @@ class CurrenciesTableSeeder extends Seeder
[ [
'name' => 'Vietnamese Dong', 'name' => 'Vietnamese Dong',
'code' => 'VND', 'code' => 'VND',
'symbol' => '', 'symbol' => '',
'precision' => '0', 'precision' => '0',
'thousand_separator' => '.', 'thousand_separator' => '.',
'decimal_separator' => ',' 'decimal_separator' => ','
@ -155,7 +155,7 @@ class CurrenciesTableSeeder extends Seeder
[ [
'name' => 'Swiss Franc', 'name' => 'Swiss Franc',
'code' => 'CHF', 'code' => 'CHF',
'symbol' => '', 'symbol' => 'Fr.',
'precision' => '2', 'precision' => '2',
'thousand_separator' => '\'', 'thousand_separator' => '\'',
'decimal_separator' => '.' 'decimal_separator' => '.'
@ -187,7 +187,7 @@ class CurrenciesTableSeeder extends Seeder
[ [
'name' => 'Thai Baht', 'name' => 'Thai Baht',
'code' => 'THB', 'code' => 'THB',
'symbol' => '', 'symbol' => '฿',
'precision' => '2', 'precision' => '2',
'thousand_separator' => ',', 'thousand_separator' => ',',
'decimal_separator' => '.' 'decimal_separator' => '.'
@ -195,7 +195,7 @@ class CurrenciesTableSeeder extends Seeder
[ [
'name' => 'Nigerian Naira', 'name' => 'Nigerian Naira',
'code' => 'NGN', 'code' => 'NGN',
'symbol' => '', 'symbol' => '',
'precision' => '2', 'precision' => '2',
'thousand_separator' => ',', 'thousand_separator' => ',',
'decimal_separator' => '.' 'decimal_separator' => '.'
@ -227,7 +227,7 @@ class CurrenciesTableSeeder extends Seeder
[ [
'name' => 'Hong Kong Dollar', 'name' => 'Hong Kong Dollar',
'code' => 'HKD', 'code' => 'HKD',
'symbol' => '', 'symbol' => 'HK$',
'precision' => '2', 'precision' => '2',
'thousand_separator' => ',', 'thousand_separator' => ',',
'decimal_separator' => '.' 'decimal_separator' => '.'
@ -299,7 +299,7 @@ class CurrenciesTableSeeder extends Seeder
[ [
'name' => 'Netherlands Antillean Guilder', 'name' => 'Netherlands Antillean Guilder',
'code' => 'ANG', 'code' => 'ANG',
'symbol' => '', 'symbol' => 'NAƒ',
'precision' => '2', 'precision' => '2',
'thousand_separator' => '.', 'thousand_separator' => '.',
'decimal_separator' => ',' 'decimal_separator' => ','
@ -323,7 +323,7 @@ class CurrenciesTableSeeder extends Seeder
[ [
'name' => 'Ghanaian Cedi', 'name' => 'Ghanaian Cedi',
'code' => 'GHS', 'code' => 'GHS',
'symbol' => '', 'symbol' => 'GH₵',
'precision' => '2', 'precision' => '2',
'thousand_separator' => ',', 'thousand_separator' => ',',
'decimal_separator' => '.' 'decimal_separator' => '.'
@ -331,7 +331,7 @@ class CurrenciesTableSeeder extends Seeder
[ [
'name' => 'Bulgarian Lev', 'name' => 'Bulgarian Lev',
'code' => 'BGN', 'code' => 'BGN',
'symbol' => '', 'symbol' => 'Лв.',
'precision' => '2', 'precision' => '2',
'thousand_separator' => ' ', 'thousand_separator' => ' ',
'decimal_separator' => '.' 'decimal_separator' => '.'
@ -355,7 +355,7 @@ class CurrenciesTableSeeder extends Seeder
[ [
'name' => 'Romanian New Leu', 'name' => 'Romanian New Leu',
'code' => 'RON', 'code' => 'RON',
'symbol' => '', 'symbol' => 'RON',
'precision' => '2', 'precision' => '2',
'thousand_separator' => ',', 'thousand_separator' => ',',
'decimal_separator' => '.' 'decimal_separator' => '.'
@ -371,7 +371,7 @@ class CurrenciesTableSeeder extends Seeder
[ [
'name' => 'Saudi Riyal', 'name' => 'Saudi Riyal',
'code' => 'SAR', 'code' => 'SAR',
'symbol' => '', 'symbol' => 'SِAR',
'precision' => '2', 'precision' => '2',
'thousand_separator' => ',', 'thousand_separator' => ',',
'decimal_separator' => '.' 'decimal_separator' => '.'
@ -387,7 +387,7 @@ class CurrenciesTableSeeder extends Seeder
[ [
'name' => 'Maldivian Rufiyaa', 'name' => 'Maldivian Rufiyaa',
'code' => 'MVR', 'code' => 'MVR',
'symbol' => '', 'symbol' => 'Rf',
'precision' => '2', 'precision' => '2',
'thousand_separator' => ',', 'thousand_separator' => ',',
'decimal_separator' => '.' 'decimal_separator' => '.'
@ -395,7 +395,7 @@ class CurrenciesTableSeeder extends Seeder
[ [
'name' => 'Costa Rican Colón', 'name' => 'Costa Rican Colón',
'code' => 'CRC', 'code' => 'CRC',
'symbol' => '', 'symbol' => '',
'precision' => '2', 'precision' => '2',
'thousand_separator' => ',', 'thousand_separator' => ',',
'decimal_separator' => '.' 'decimal_separator' => '.'
@ -454,7 +454,7 @@ class CurrenciesTableSeeder extends Seeder
[ [
'name' => 'Tunisian Dinar', 'name' => 'Tunisian Dinar',
'code' => 'TND', 'code' => 'TND',
'symbol' => '', 'symbol' => '‎د.ت',
'precision' => '2', 'precision' => '2',
'thousand_separator' => ',', 'thousand_separator' => ',',
'decimal_separator' => '.' 'decimal_separator' => '.'
@ -462,7 +462,7 @@ class CurrenciesTableSeeder extends Seeder
[ [
'name' => 'Russian Ruble', 'name' => 'Russian Ruble',
'code' => 'RUB', 'code' => 'RUB',
'symbol' => '', 'symbol' => '',
'precision' => '2', 'precision' => '2',
'thousand_separator' => ',', 'thousand_separator' => ',',
'decimal_separator' => '.' 'decimal_separator' => '.'
@ -479,7 +479,7 @@ class CurrenciesTableSeeder extends Seeder
[ [
'name' => 'Omani Rial', 'name' => 'Omani Rial',
'code' => 'OMR', 'code' => 'OMR',
'symbol' => '', 'symbol' => 'ر.ع.',
'precision' => '2', 'precision' => '2',
'thousand_separator' => ',', 'thousand_separator' => ',',
'decimal_separator' => '.' 'decimal_separator' => '.'
@ -487,7 +487,7 @@ class CurrenciesTableSeeder extends Seeder
[ [
'name' => 'Ukrainian Hryvnia', 'name' => 'Ukrainian Hryvnia',
'code' => 'UAH', 'code' => 'UAH',
'symbol' => '', 'symbol' => '',
'precision' => '2', 'precision' => '2',
'thousand_separator' => ',', 'thousand_separator' => ',',
'decimal_separator' => '.' 'decimal_separator' => '.'

View File

@ -14,8 +14,6 @@ class DatabaseSeeder extends Seeder
$this->call(CurrenciesTableSeeder::class); $this->call(CurrenciesTableSeeder::class);
$this->call(RoleSeeder::class); $this->call(RoleSeeder::class);
$this->call(CountriesTableSeeder::class); $this->call(CountriesTableSeeder::class);
$this->call(StatesTableSeeder::class);
$this->call(CitiesTableSeeder::class);
$this->call(EstimateTemplateSeeder::class); $this->call(EstimateTemplateSeeder::class);
$this->call(InvoiceTemplateSeeder::class); $this->call(InvoiceTemplateSeeder::class);
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
{ {
"/assets/js/app.js": "/assets/js/app.js?id=0de16e5183b0d24fd95d", "/assets/js/app.js": "/assets/js/app.js?id=af9e4f2aa907d480466c",
"/assets/css/crater.css": "/assets/css/crater.css?id=361d275866b6299acb36" "/assets/css/crater.css": "/assets/css/crater.css?id=9d83f53c3915b38417e0"
} }

View File

@ -163,44 +163,24 @@
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label input-label">{{ $t('customers.state') }}</label> <label class="col-sm-4 col-form-label input-label">{{ $t('customers.state') }}</label>
<div class="col-sm-7"> <div class="col-sm-7">
<base-select <base-input
v-model="billingState" v-model="billing.state"
:options="billingStates" type="text"
:searchable="true" name="billingState"
:show-labels="false"
:placeholder="$t('general.select_state')"
:disabled="isDisabledBillingState"
track-by="id"
label="name"
/> />
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label input-label">{{ $t('customers.city') }}</label> <label class="col-sm-4 col-form-label input-label">{{ $t('customers.city') }}</label>
<div class="col-sm-7">
<base-select
v-model="billingCity"
:options="billingCities"
:searchable="true"
:show-labels="false"
:placeholder="$t('general.select_city')"
:disabled="isDisabledBillingCity"
track-by="id"
label="name"
/>
</div>
</div>
<!-- <div class="form-group row">
<label class="col-sm-4 col-form-label">Zip Code</label>
<div class="col-sm-7"> <div class="col-sm-7">
<base-input <base-input
v-model="billing.zip" v-model="billing.city"
type="text" type="text"
name="billingCity"
/> />
</div> </div>
</div> --> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label input-label">{{ $t('customers.zip_code') }}</label> <label class="col-sm-4 col-form-label input-label">{{ $t('customers.zip_code') }}</label>
@ -294,15 +274,10 @@
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label input-label">{{ $t('customers.state') }}</label> <label class="col-sm-4 col-form-label input-label">{{ $t('customers.state') }}</label>
<div class="col-sm-7"> <div class="col-sm-7">
<base-select <base-input
v-model="shippingState" v-model="shipping.state"
:options="shippingStates" type="text"
:searchable="true" name="shippingState"
:show-labels="false"
:placeholder="$t('general.select_state')"
:disabled="isDisabledShippingState"
track-by="id"
label="name"
/> />
</div> </div>
</div> </div>
@ -310,15 +285,10 @@
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label input-label">{{ $t('customers.city') }}</label> <label class="col-sm-4 col-form-label input-label">{{ $t('customers.city') }}</label>
<div class="col-sm-7"> <div class="col-sm-7">
<base-select <base-input
v-model="shippingCity" v-model="shipping.city"
:options="shippingCities" type="text"
:searchable="true" name="shippingCity"
:show-labels="false"
:placeholder="$t('general.select_city')"
:disabled="isDisabledShippingCity"
track-by="id"
label="name"
/> />
</div> </div>
</div> </div>
@ -372,16 +342,8 @@ export default {
return { return {
isLoading: false, isLoading: false,
countryList: [], countryList: [],
billingStates: [],
billingCities: [],
billingCountry: null, billingCountry: null,
billingState: null,
billingCity: null,
shippingStates: [],
shippingCities: [],
shippingCountry: null, shippingCountry: null,
shippingState: null,
shippingCity: null,
isCopyFromBilling: false, isCopyFromBilling: false,
currencyList: [], currencyList: [],
currency: '', currency: '',
@ -442,61 +404,14 @@ export default {
billingCountry () { billingCountry () {
if (this.billingCountry) { if (this.billingCountry) {
this.billing.country_id = this.billingCountry.id this.billing.country_id = this.billingCountry.id
this.isDisabledBillingState = false
this.fetchBillingStates(this.billingCountry.id)
this.billingState = null
this.billingCity = null
return true return true
} }
}, },
billingState () {
if (this.billingState) {
this.billing.state_id = this.billingState.id
this.isDisabledBillingCity = false
this.fetchBillingCities(this.billingState.id)
this.billingCity = null
return true
}
this.billingCity = null
this.isDisabledBillingCity = true
},
billingCity () {
if (this.billingCity) {
this.billing.city_id = this.billingCity.id
}
},
shippingCountry () { shippingCountry () {
if (this.shippingCountry) { if (this.shippingCountry) {
this.shipping.country_id = this.shippingCountry.id this.shipping.country_id = this.shippingCountry.id
this.isDisabledShippingState = false
this.fetchShippingStates(this.shippingCountry.id)
if (this.isCopyFromBilling) {
return true return true
} }
this.shippingState = null
this.shippingCity = null
return true
}
},
shippingState () {
if (this.shippingState) {
this.shipping.state_id = this.shippingState.id
this.isDisabledShippingCity = false
this.fetchShippingCities(this.shippingState.id)
if (this.isCopyFromBilling) {
this.isCopyFromBilling = false
return true
}
this.shippingCity = null
return true
}
this.shippingCity = null
this.isDisabledShippingCity = true
},
shippingCity () {
if (this.shippingCity) {
this.shipping.city_id = this.shippingCity.id
}
} }
}, },
mounted () { mounted () {
@ -529,16 +444,8 @@ export default {
addresses: [] addresses: []
} }
this.billingStates = []
this.billingCities = []
this.billingCountry = null this.billingCountry = null
this.billingState = null
this.billingCity = null
this.shippingStates = []
this.shippingCities = []
this.shippingCountry = null this.shippingCountry = null
this.shippingState = null
this.shippingCity = null
this.billing = {...AddressStub} this.billing = {...AddressStub}
this.shipping = {...AddressStub} this.shipping = {...AddressStub}
@ -553,13 +460,9 @@ export default {
this.isCopyFromBilling = true this.isCopyFromBilling = true
this.shipping = {...this.billing, type: 'shipping'} this.shipping = {...this.billing, type: 'shipping'}
this.shippingCountry = this.billingCountry this.shippingCountry = this.billingCountry
this.shippingState = this.billingState
this.shippingCity = this.billingCity
} else { } else {
this.shipping = {...AddressStub, type: 'shipping'} this.shipping = {...AddressStub, type: 'shipping'}
this.shippingCountry = null this.shippingCountry = null
this.shippingState = null
this.shippingCity = null
} }
}, },
async loadData () { async loadData () {
@ -633,30 +536,6 @@ export default {
if (res) { if (res) {
this.countryList = res.data.countries this.countryList = res.data.countries
} }
},
async fetchBillingStates (id) {
let res = await window.axios.get(`/api/states/${id}`)
if (res) {
this.billingStates = res.data.states
}
},
async fetchBillingCities (id) {
let res = await window.axios.get(`/api/cities/${id}`)
if (res) {
this.billingCities = res.data.cities
}
},
async fetchShippingStates (id) {
let res = await window.axios.get(`/api/states/${id}`)
if (res) {
this.shippingStates = res.data.states
}
},
async fetchShippingCities (id) {
let res = await window.axios.get(`/api/cities/${id}`)
if (res) {
this.shippingCities = res.data.cities
}
} }
} }
} }

View File

@ -689,7 +689,7 @@ export default {
update: 'Update Now', update: 'Update Now',
update_progress: 'Update in progress...', update_progress: 'Update in progress...',
progress_text: 'It will just take a few minutes. Please do not refresh the screen or close the window before the update finishes', progress_text: 'It will just take a few minutes. Please do not refresh the screen or close the window before the update finishes',
update_success: 'App has been updated successfully', update_success: 'App has been updated! Please wait while your browser window gets reloaded automatically.',
latest_message: 'No update available! You are on the latest version.', latest_message: 'No update available! You are on the latest version.',
current_version: 'Current Version' current_version: 'Current Version'
} }
@ -740,6 +740,8 @@ export default {
}, },
permissions: { permissions: {
permissions: 'Permissions', permissions: 'Permissions',
permission_confirm_title: 'Are you sure you want to continue?',
permission_confirm_desc: 'Folder permission check failed',
permission_desc: 'Below is the list of folder permissions which are required in order for the app to work. If the permission check fails, make sure to update your folder permissions.' permission_desc: 'Below is the list of folder permissions which are required in order for the app to work. If the permission check fails, make sure to update your folder permissions.'
}, },
mail: { mail: {

View File

@ -685,7 +685,7 @@ export default {
update: 'Actualizar', update: 'Actualizar',
update_progress: 'Actualización en progreso...', update_progress: 'Actualización en progreso...',
progress_text: 'Solo tomará unos minutos. No actualice la pantalla ni cierre la ventana antes de que finalice la actualización.', progress_text: 'Solo tomará unos minutos. No actualice la pantalla ni cierre la ventana antes de que finalice la actualización.',
update_success: 'La aplicación se actualizó correctamente', update_success: '¡La aplicación ha sido actualizada! Espere mientras la ventana de su navegador se vuelve a cargar automáticamente.',
latest_message: '¡Actualización no disponible! Estás en la última versión.', latest_message: '¡Actualización no disponible! Estás en la última versión.',
current_version: 'Versión actual' current_version: 'Versión actual'
} }
@ -735,6 +735,8 @@ export default {
}, },
permissions: { permissions: {
permissions: 'Permisos', permissions: 'Permisos',
permission_confirm_title: 'Estás seguro de que quieres continuar?',
permission_confirm_desc: 'Error de verificación de permisos de carpeta',
permission_desc: 'A continuación se muestra la lista de permisos de carpeta necesarios para que la aplicación funcione. Si la verificación de permisos falla, asegúrese de actualizar los permisos de su carpeta.' permission_desc: 'A continuación se muestra la lista de permisos de carpeta necesarios para que la aplicación funcione. Si la verificación de permisos falla, asegúrese de actualizar los permisos de su carpeta.'
}, },
mail: { mail: {

View File

@ -688,7 +688,7 @@ export default {
update: 'Mettre à jour maintenant', update: 'Mettre à jour maintenant',
update_progress: 'Mise à jour en cours...', update_progress: 'Mise à jour en cours...',
progress_text: "Cela ne prendra que quelques minutes. S'il vous plaît ne pas actualiser l'écran ou fermer la fenêtre avant la fin de la mise à jour", progress_text: "Cela ne prendra que quelques minutes. S'il vous plaît ne pas actualiser l'écran ou fermer la fenêtre avant la fin de la mise à jour",
update_success: "L'application a été mise à jour avec succès", update_success: 'App a été mis à jour! Veuillez patienter pendant le rechargement automatique de la fenêtre de votre navigateur.',
latest_message: 'Pas de mise a jour disponible! Vous êtes sur la dernière version.', latest_message: 'Pas de mise a jour disponible! Vous êtes sur la dernière version.',
current_version: 'Version actuelle' current_version: 'Version actuelle'
} }
@ -738,6 +738,8 @@ export default {
}, },
permissions: { permissions: {
permissions: 'Les permissions', permissions: 'Les permissions',
permission_confirm_title: 'Es-tu sur de vouloir continuer?',
permission_confirm_desc: 'La vérification de l\'autorisation du dossier a échoué',
permission_desc: "Vous trouverez ci-dessous la liste des autorisations de dossier requises pour le fonctionnement de l'application. Si la vérification des autorisations échoue, veillez à mettre à jour vos autorisations de dossier." permission_desc: "Vous trouverez ci-dessous la liste des autorisations de dossier requises pour le fonctionnement de l'application. Si la vérification des autorisations échoue, veillez à mettre à jour vos autorisations de dossier."
}, },
mail: { mail: {

View File

@ -36,7 +36,9 @@ export const addCustomer = ({ commit, dispatch, state }, data) => {
export const updateCustomer = ({ commit, dispatch, state }, data) => { export const updateCustomer = ({ commit, dispatch, state }, data) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
window.axios.put(`/api/customers/${data.id}`, data).then((response) => { window.axios.put(`/api/customers/${data.id}`, data).then((response) => {
if(response.data.success){
commit(types.UPDATE_CUSTOMER, response.data) commit(types.UPDATE_CUSTOMER, response.data)
}
resolve(response) resolve(response)
}).catch((err) => { }).catch((err) => {
reject(err) reject(err)

View File

@ -3,8 +3,8 @@ export default {
phone: null, phone: null,
address_street_1: null, address_street_1: null,
address_street_2: null, address_street_2: null,
city_id: null, city: null,
state_id: null, state: null,
country_id: null, country_id: null,
zip: null, zip: null,
type: null type: null

View File

@ -119,16 +119,10 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="form-label">{{ $t('customers.state') }}</label> <label class="form-label">{{ $t('customers.state') }}</label>
<base-select <base-input
v-model="billing_state" v-model="billing.state"
:options="billingStates" name="billing.state"
:searchable="true" type="text"
:show-labels="false"
:tabindex="9"
:disabled="isDisabledBillingState"
:placeholder="$t('general.select_state')"
label="name"
track-by="id"
/> />
</div> </div>
<div class="form-group"> <div class="form-group">
@ -176,16 +170,10 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="form-label">{{ $t('customers.city') }}</label> <label class="form-label">{{ $t('customers.city') }}</label>
<base-select <base-input
v-model="billing_city" v-model="billing.city"
:options="billingCities" name="billing.city"
:searchable="true" type="text"
:show-labels="false"
:disabled="isDisabledBillingCity"
:tabindex="10"
:placeholder="$t('general.select_city')"
label="name"
track-by="id"
/> />
</div> </div>
<div class="form-group"> <div class="form-group">
@ -233,16 +221,10 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="form-label">{{ $t('customers.state') }}</label> <label class="form-label">{{ $t('customers.state') }}</label>
<base-select <base-input
v-model="shipping_state" v-model="shipping.state"
:options="shippingStates" name="shipping.state"
:searchable="true" type="text"
:show-labels="false"
:tabindex="17"
:disabled="isDisabledShippingState"
:placeholder="$t('general.select_state')"
label="name"
track-by="id"
/> />
</div> </div>
<div class="form-group"> <div class="form-group">
@ -290,16 +272,10 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="form-label">{{ $t('customers.city') }}</label> <label class="form-label">{{ $t('customers.city') }}</label>
<base-select <base-input
v-model="shipping_city" v-model="shipping.city"
:options="shippingCities" name="shipping.city"
:searchable="true" type="text"
:show-labels="false"
:tabindex="18"
:disabled="isDisabledShippingCity"
:placeholder="$t('general.select_city')"
label="name"
track-by="id"
/> />
</div> </div>
<div class="form-group"> <div class="form-group">
@ -344,7 +320,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 AddressStub from '../../stub/address' import AddressStub from '../../stub/address'
const { required, minLength, email, numeric, url, maxLength } = require('vuelidate/lib/validators') const { required, minLength, email, url, maxLength } = require('vuelidate/lib/validators')
export default { export default {
components: { MultiSelect }, components: { MultiSelect },
@ -366,8 +342,8 @@ export default {
billing: { billing: {
name: null, name: null,
country_id: null, country_id: null,
state_id: null, state: null,
city_id: null, city: null,
phone: null, phone: null,
zip: null, zip: null,
address_street_1: null, address_street_1: null,
@ -377,8 +353,8 @@ export default {
shipping: { shipping: {
name: null, name: null,
country_id: null, country_id: null,
state_id: null, state: null,
city_id: null, city: null,
phone: null, phone: null,
zip: null, zip: null,
address_street_1: null, address_street_1: null,
@ -386,26 +362,12 @@ export default {
type: 'shipping' type: 'shipping'
}, },
currencyList: [], currencyList: [],
isDisabledBillingState: true,
isDisabledBillingCity: true,
isDisabledShippingState: true,
isDisabledShippingCity: true,
billing_country: null, billing_country: null,
billing_city: null,
billing_state: null,
shipping_country: null, shipping_country: null,
shipping_city: null,
shipping_state: null,
billingCountries: [], billingCountries: [],
billingStates: [], shippingCountries: []
billingCities: [],
shippingCountries: [],
shippingStates: [],
shippingCities: []
} }
}, },
validations: { validations: {
@ -455,61 +417,13 @@ export default {
if (newCountry) { if (newCountry) {
this.billing.country_id = newCountry.id this.billing.country_id = newCountry.id
this.isDisabledBillingState = false this.isDisabledBillingState = false
this.billing_state = null
this.billing_city = null
this.fetchBillingState()
}
},
billing_state (newState) {
if (newState) {
this.billing.state_id = newState.id
this.isDisabledBillingCity = false
this.billing_city = null
this.fetchBillingCities()
return true
}
this.billing_city = null
this.isDisabledBillingCity = true
return true
},
billing_city (newCity) {
if (newCity) {
this.billing.city_id = newCity.id
} }
}, },
shipping_country (newCountry) { shipping_country (newCountry) {
if (newCountry) { if (newCountry) {
this.shipping.country_id = newCountry.id this.shipping.country_id = newCountry.id
this.isDisabledShippingState = false
this.fetchShippingState()
if (this.isCopyFromBilling) {
return true return true
} }
this.shipping_state = null
this.shipping_city = null
return true
}
},
shipping_state (newState) {
if (newState) {
this.shipping.state_id = newState.id
this.isDisabledShippingCity = false
this.fetchShippingCities()
if (this.isCopyFromBilling) {
this.isCopyFromBilling = false
return true
}
this.shipping_city = null
return true
}
this.shipping_city = null
this.isDisabledShippingCity = true
return true
},
shipping_city (newCity) {
if (newCity) {
this.shipping.city_id = newCity.id
}
} }
}, },
mounted () { mounted () {
@ -624,42 +538,6 @@ export default {
} }
} }
} }
},
async fetchBillingState () {
let res = await window.axios.get(`/api/states/${this.billing_country.id}`)
if (res) {
this.billingStates = res.data.states
}
if (this.isEdit) {
this.billing_state = this.billingStates.find((state) => state.id === this.billing.state_id)
}
},
async fetchBillingCities () {
let res = await window.axios.get(`/api/cities/${this.billing_state.id}`)
if (res) {
this.billingCities = res.data.cities
}
if (this.isEdit) {
this.billing_city = this.billingCities.find((city) => city.id === this.billing.city_id)
}
},
async fetchShippingState () {
let res = await window.axios.get(`/api/states/${this.shipping_country.id}`)
if (res) {
this.shippingStates = res.data.states
}
if (this.isEdit) {
this.shipping_state = this.shippingStates.find((s) => s.id === this.shipping.state_id)
}
},
async fetchShippingCities () {
let res = await window.axios.get(`/api/cities/${this.shipping_state.id}`)
if (res) {
this.shippingCities = res.data.cities
}
if (this.isEdit) {
this.shipping_city = this.shippingCities.find((c) => c.id === this.shipping.city_id)
}
} }
} }
} }

View File

@ -1,459 +0,0 @@
<template>
<div class="header-bottom">
<div class="header-nav vue-dropdown-menu">
<v-dropdown active-url="/admin/dashboard">
<template slot="title">
<a href="#">
<i class="icon-fa icon-fa-dashboard"/>{{ $t('navigation.dashboard') }}
<span class="icon-fa arrow icon-fa-fw"/>
</a>
</template>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/dashboard/basic">
Basic
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/dashboard/ecommerce">
Ecommerce
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/dashboard/finance">
Finance
</router-link>
</template>
</v-dropdown-item>
</v-dropdown>
<v-dropdown active-url="/admin/layouts">
<template slot="title">
<a href="#">
<i class="icon-fa icon-fa-th-large"/>Layouts
<span class="icon-fa arrow icon-fa-fw"/>
</a>
</template>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/layouts/sidebar">
Sidebar
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/layouts/horizontal">
Horizontal
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/layouts/icons-sidebar">
Icon Sidebar
</router-link>
</template>
</v-dropdown-item>
</v-dropdown>
<v-dropdown active-url="/admin/basic-ui">
<template slot="title">
<a href="#">
<i class="icon-fa icon-fa-star"/>Basic UI
<span class="icon-fa arrow icon-fa-fw"/>
</a>
</template>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/basic-ui/buttons">
Buttons
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/basic-ui/cards">
Cards
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/basic-ui/tabs">
Tabs &amp; Accordians
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/basic-ui/typography">
Typography
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/basic-ui/tables">
Tables
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/basic-ui/modals">
Modals
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/basic-ui/progress-bars">
Progress Bar
</router-link>
</template>
</v-dropdown-item>
</v-dropdown>
<v-dropdown active-url="/admin/components">
<template slot="title">
<a href="#">
<i class="icon-fa icon-fa-puzzle-piece"/>Components
<span class="icon-fa arrow icon-fa-fw"/>
</a>
</template>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/components/calendar">
Calendar
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/components/datatables">
Jquery Datatables
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/components/mail-box">
MailBox
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/components/calendar">
Calendar
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/components/datatables">
Jquery Datatables
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/components/image-cropper">
ImageCropper
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/components/image-zoom">
ImageZoom
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/components/nestable-list">
Nestable List
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/components/nestable-tree">
Nestable Tree
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/components/notifications">
Notifications
</router-link>
</template>
</v-dropdown-item>
<v-dropdown active-url="/admin/layouts">
<template slot="title">
<a href="#">
<i class="icon-fa icon-fa-th-large"/>Layouts
<span class="icon-fa arrow icon-fa-fw"/>
</a>
</template>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/layouts/sidebar">
Sidebar
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/layouts/horizontal">
Horizontal
</router-link>
</template>
</v-dropdown-item>
</v-dropdown>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/components/sweet-modals">
Sweet Modals
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/components/image-zoom">
ImageZoom
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/components/mail-box">
MailBox
</router-link>
</template>
</v-dropdown-item>
</v-dropdown>
<v-dropdown active-url="/admin/chart">
<template slot="title">
<a href="#">
<i class="icon-fa icon-fa-bar-chart"/>Charts
<span class="icon-fa arrow icon-fa-fw"/>
</a>
</template>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/charts/amchart">
AM Charts
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/charts/chartjs">
Chart JS
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/charts/gauge">
Gauges
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/charts/morris">
Morris
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/charts/sparkline">
Sparkline
</router-link>
</template>
</v-dropdown-item>
</v-dropdown>
<v-dropdown active-url="/admin/icons">
<template slot="title">
<a href="#">
<i class="icon-fa icon-fa-eye"/>Icons
<span class="icon-fa arrow icon-fa-fw"/>
</a>
</template>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/icons/icomoon">
IcoMoon
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/icons/fontawesome">
Font Awesome
</router-link>
</template>
</v-dropdown-item>
</v-dropdown>
<v-dropdown active-url="/admin/forms">
<template slot="title">
<a href="#">
<i class="icon-fa icon-fa-rocket"/>Form
<span class="icon-fa arrow icon-fa-fw"/>
</a>
</template>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/forms/general">
General Elements
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/forms/advanced">
Advanced Elements
</router-link>
</template>
</v-dropdown-item><v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/forms/layouts">
Form Layouts
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/forms/validation">
Form Validation
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/forms/wizards">
Form Wizard
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/forms/wizards-2">
Form Wizard 2
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/forms/wizards-3">
Form Wizard 3
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/forms/editors">
Editors
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/forms/vee">
Vee Validate
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/forms/vuelidate">
Vuelidate
</router-link>
</template>
</v-dropdown-item>
</v-dropdown>
<v-dropdown active-url="/admin/gallery">
<template slot="title">
<a href="#">
<i class="icon-fa icon-fa-image"/>Gallery
<span class="icon-fa arrow icon-fa-fw"/>
</a>
</template>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/gallery/grid">
Grid
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/gallery/masonry-grid">
Masonry Grid
</router-link>
</template>
</v-dropdown-item>
</v-dropdown>
<v-dropdown active-url="/admin/users">
<template slot="title">
<a href="#">
<i class="icon-fa icon-fa-user"/>Users
<span class="icon-fa arrow icon-fa-fw"/>
</a>
</template>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/users/profile">
Profile
</router-link>
</template>
</v-dropdown-item>
<v-dropdown-item>
<template slot="item-title">
<router-link to="/admin/users">
All Users
</router-link>
</template>
</v-dropdown-item>
</v-dropdown>
<v-dropdown active-url="/admin/todo-item">
<template slot="title">
<router-link to="/admin/todo-item">
<i class="icon-fa icon-fa-check"/>Todos
</router-link>
</template>
</v-dropdown>
<v-dropdown active-url="/admin/settings">
<template slot="title">
<router-link to="/admin/settings">
<i class="icon-fa icon-fa-cogs"/>Settings
</router-link>
</template>
</v-dropdown>
</div>
</div>
</template>
<script type="text/babel">
import VDropdown from '../../../components/dropdown/VDropdown'
import VDropdownItem from '../../../components/dropdown/VDropdownItem'
export default {
components: {
VDropdown,
VDropdownItem
},
data () {
return {
sidebar: 'sidebar'
}
}
}
</script>

View File

@ -263,9 +263,6 @@ export default {
} }
}, },
async mounted () { async mounted () {
// if (!this.$route.params.id) {
// this.$refs.baseSelect.$refs.search.focus()
// }
this.$nextTick(() => { this.$nextTick(() => {
this.loadData() this.loadData()
if (this.$route.params.id && !this.isEdit) { if (this.$route.params.id && !this.isEdit) {

View File

@ -215,15 +215,14 @@
</table-column> </table-column>
</table-component> </table-component>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { mapActions, mapGetters } from 'vuex' import { mapActions, mapGetters } from 'vuex'
import { SweetModal, SweetModalTab } from 'sweet-modal-vue' import { SweetModal, SweetModalTab } from 'sweet-modal-vue'
import CapsuleIcon from '../../components/icon/CapsuleIcon' import CapsuleIcon from '../../components/icon/CapsuleIcon'
import BaseButton from '../../../js/components/base/BaseButton' import BaseButton from '../../../js/components/base/BaseButton'
import { request } from 'http'
export default { export default {
components: { components: {

View File

@ -4,13 +4,6 @@
<div class="row"> <div class="row">
<div class="col-md-8"> <div class="col-md-8">
<label class="report-label">{{ $t('reports.sales.date_range') }}</label> <label class="report-label">{{ $t('reports.sales.date_range') }}</label>
<!-- <base-date-picker
v-model="range"
:invalid="$v.range.$error"
format="yyyy"
minimum-view="year"
@change="$v.range.$touch()"
/> -->
<base-select <base-select
v-model="selectedRange" v-model="selectedRange"
:options="dateRange" :options="dateRange"

View File

@ -52,6 +52,7 @@
</transition> </transition>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
watch: { watch: {

View File

@ -72,37 +72,22 @@
</div> </div>
<div class="col-md-6 mb-4"> <div class="col-md-6 mb-4">
<label class="input-label">{{ $tc('settings.company_info.state') }}</label> <label class="input-label">{{ $tc('settings.company_info.state') }}</label>
<base-select <base-input
v-model="state" v-model="formData.state"
:options="states" :placeholder="$tc('settings.company_info.state')"
:searchable="true" name="state"
:disabled="isDisabledState" type="text"
:show-labels="false"
:placeholder="$t('general.select_state')"
label="name"
track-by="id"
/> />
</div> </div>
<div class="col-md-6 mb-4"> <div class="col-md-6 mb-4">
<label class="input-label">{{ $tc('settings.company_info.city') }}</label> <label class="input-label">{{ $tc('settings.company_info.city') }}</label>
<base-select <base-input
v-model="city" v-model="formData.city"
:options="cities" :placeholder="$tc('settings.company_info.city')"
:searchable="true" name="city"
:show-labels="false" type="text"
:disabled="isDisabledCity"
:placeholder="$t('general.select_city')"
label="name"
track-by="id"
/> />
</div> </div>
<!-- <div class="col-md-6 mb-3">
<label class="input-label">Website</label>
<base-input
v-model="formData.website"
placeholder="Website"
/>
</div> -->
<div class="col-md-6 mb-4"> <div class="col-md-6 mb-4">
<label class="input-label">{{ $tc('settings.company_info.zip') }}</label> <label class="input-label">{{ $tc('settings.company_info.zip') }}</label>
<base-input <base-input
@ -157,7 +142,7 @@ import ImageBox from '../components/ImageBox.vue'
import AvatarCropper from 'vue-avatar-cropper' import AvatarCropper from 'vue-avatar-cropper'
import { validationMixin } from 'vuelidate' import { validationMixin } from 'vuelidate'
import { mapActions } from 'vuex' import { mapActions } from 'vuex'
const { required, email, numeric, maxLength } = require('vuelidate/lib/validators') const { required, email, maxLength } = require('vuelidate/lib/validators')
export default { export default {
components: { AvatarCropper, IconUpload, ImageBox }, components: { AvatarCropper, IconUpload, ImageBox },
@ -184,20 +169,14 @@ export default {
address_street_2: '', address_street_2: '',
website: '', website: '',
country_id: null, country_id: null,
state_id: '', state: '',
city_id: '' city: ''
}, },
isLoading: false, isLoading: false,
isHidden: false, isHidden: false,
country: null, country: null,
previewLogo: null, previewLogo: null,
city: null,
state: null,
countries: [], countries: [],
isDisabledState: true,
isDisabledCity: true,
states: [],
cities: [],
passData: [], passData: [],
fileSendUrl: '/api/settings/company', fileSendUrl: '/api/settings/company',
fileObject: null fileObject: null
@ -206,44 +185,9 @@ export default {
watch: { watch: {
country (newCountry) { country (newCountry) {
this.formData.country_id = newCountry.id this.formData.country_id = newCountry.id
if (this.formData.country_id) {
this.isDisabledState = false
}
this.fetchState()
if (this.isFetchingData) { if (this.isFetchingData) {
return true return true
} }
this.state = null
this.city = null
},
state (newState) {
if (newState !== null && newState !== undefined) {
this.formData.state_id = newState.id
this.fetchCities()
this.isDisabledCity = false
if (this.isFetchingData) {
this.isFetchingData = false
return true
}
this.city = null
return true
}
// this.formData.state_id = null
this.cities = []
this.city = null
// this.formData.city_id = null
this.isDisabledCity = true
return true
},
city (newCity) {
if (newCity !== null && newCity !== undefined) {
this.formData.city_id = newCity.id
return true
}
// this.formData.city_id = null
// return true
} }
}, },
validations: { validations: {
@ -292,9 +236,9 @@ export default {
this.formData.address_street_2 = response.data.user.addresses[0].address_street_2 this.formData.address_street_2 = response.data.user.addresses[0].address_street_2
this.formData.zip = response.data.user.addresses[0].zip this.formData.zip = response.data.user.addresses[0].zip
this.formData.phone = response.data.user.addresses[0].phone this.formData.phone = response.data.user.addresses[0].phone
this.formData.state = response.data.user.addresses[0].state
this.formData.city = response.data.user.addresses[0].city
this.country = response.data.user.addresses[0].country this.country = response.data.user.addresses[0].country
this.state = response.data.user.addresses[0].state
this.city = response.data.user.addresses[0].city
this.previewLogo = response.data.user.company.logo this.previewLogo = response.data.user.company.logo
}, },
async updateCompany () { async updateCompany () {
@ -328,19 +272,6 @@ export default {
if (res) { if (res) {
this.countries = res.data.countries this.countries = res.data.countries
} }
},
async fetchState () {
this.$v.formData.country_id.$touch()
let res = await window.axios.get(`/api/states/${this.country.id}`)
if (res) {
this.states = res.data.states
}
},
async fetchCities () {
let res = await window.axios.get(`/api/cities/${this.state.id}`)
if (res) {
this.cities = res.data.cities
}
} }
} }
} }

View File

@ -17,9 +17,7 @@
<h3 class="page-title mb-3">{{ $t('settings.update_app.avail_update') }}</h3> <h3 class="page-title mb-3">{{ $t('settings.update_app.avail_update') }}</h3>
<label class="input-label">{{ $t('settings.update_app.next_version') }}</label><br> <label class="input-label">{{ $t('settings.update_app.next_version') }}</label><br>
<label class="version">{{ updateData.version }}</label> <label class="version">{{ updateData.version }}</label>
<p class="page-sub-title"> <p class="page-sub-title" style="white-space: pre-wrap;">{{ description }}</p>
{{ description }}
</p>
<base-button size="large" icon="rocket" color="theme" @click="onUpdateApp"> <base-button size="large" icon="rocket" color="theme" @click="onUpdateApp">
{{ $t('settings.update_app.update') }} {{ $t('settings.update_app.update') }}
</base-button> </base-button>
@ -55,13 +53,22 @@ export default {
} }
} }
}, },
created () {
window.addEventListener('beforeunload', (event) => {
if (this.isUpdating) {
event.returnValue = 'Update is in progress!'
}
})
},
mounted () { mounted () {
window.axios.get('/api/settings/app/version').then((res) => { window.axios.get('/api/settings/app/version').then((res) => {
this.currentVersion = res.data.version this.currentVersion = res.data.version
}) })
}, },
methods: { methods: {
closeHandler () {
console.log('closing')
},
async onUpdateApp () { async onUpdateApp () {
try { try {
this.isUpdating = true this.isUpdating = true
@ -69,10 +76,17 @@ export default {
let res = await window.axios.post('/api/update', this.updateData) let res = await window.axios.post('/api/update', this.updateData)
if (res.data.success) { if (res.data.success) {
setTimeout(async () => {
await window.axios.post('/api/update/finish', this.updateData) await window.axios.post('/api/update/finish', this.updateData)
this.isUpdateAvailable = false
window.toastr['success'](this.$t('settings.update_app.update_success')) window.toastr['success'](this.$t('settings.update_app.update_success'))
this.currentVersion = this.updateData.version this.currentVersion = this.updateData.version
this.isUpdateAvailable = false
setTimeout(() => {
location.reload()
}, 2000)
}, 5000)
} else { } else {
console.log(res.data) console.log(res.data)
window.toastr['error'](res.data.error) window.toastr['error'](res.data.error)

View File

@ -64,29 +64,18 @@
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
<label class="form-label">{{ $t('wizard.state') }}</label> <label class="form-label">{{ $t('wizard.state') }}</label>
<base-select <base-input
v-model="state" v-model="companyData.state"
:options="states" name="state"
:searchable="true" type="text"
:show-labels="false"
:disabled="isDisabledState"
:placeholder="$t('general.select_state')"
track-by="id"
label="name"
@input="fetchCities"
/> />
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<label class="form-label">{{ $t('wizard.city') }}</label> <label class="form-label">{{ $t('wizard.city') }}</label>
<base-select <base-input
v-model="city" v-model="companyData.city"
:options="cities" name="city"
:searchable="true" type="text"
:show-labels="false"
:disabled="isDisabledCity"
:placeholder="$t('general.select_city')"
track-by="id"
label="name"
/> />
</div> </div>
</div> </div>
@ -180,8 +169,8 @@ export default {
name: null, name: null,
address_street_1: '', address_street_1: '',
address_street_2: '', address_street_2: '',
city_id: '', city: '',
state_id: '', state: '',
country_id: '', country_id: '',
zip: '', zip: '',
phone: '' phone: ''
@ -190,13 +179,7 @@ export default {
step: 1, step: 1,
countries: [], countries: [],
country: null, country: null,
states: [], previewLogo: null
state: null,
cities: [],
city: null,
previewLogo: null,
isDisabledCity: true,
isDisabledState: true
} }
}, },
validations: { validations: {
@ -218,35 +201,6 @@ export default {
watch: { watch: {
country ({ id }) { country ({ id }) {
this.companyData.country_id = id this.companyData.country_id = id
this.state = null
this.city = null
if (id !== null && id !== undefined) {
this.isDisabledState = false
return true
}
this.isDisabledState = true
return true
},
state (newState) {
if (newState !== null && newState !== undefined) {
this.city = null
this.companyData.state_id = newState.id
this.isDisabledCity = false
return true
}
this.companyData.state_id = null
this.isDisabledCity = true
this.cities = []
this.city = null
this.companyData.city_id = null
return true
},
city (newCity) {
if (newCity !== null && newCity !== undefined) {
this.companyData.city_id = newCity.id
return true
}
this.companyData.city_id = null
return true return true
} }
}, },
@ -307,22 +261,6 @@ export default {
if (res) { if (res) {
this.countries = res.data.countries this.countries = res.data.countries
} }
},
async fetchState () {
this.$v.companyData.country_id.$touch()
let res = await window.axios.get(`/api/states/${this.country.id}`)
if (res) {
this.states = res.data.states
}
},
async fetchCities () {
if (this.state === null || this.state === undefined) {
return false
}
let res = await window.axios.get(`/api/cities/${this.state.id}`)
if (res) {
this.cities = res.data.cities
}
} }
} }
} }

View File

@ -22,7 +22,7 @@
</div> </div>
</div> </div>
<base-button <base-button
v-if="!errors" v-if="isContinue"
class="pull-right mt-5" class="pull-right mt-5"
icon="arrow-right" icon="arrow-right"
right-icon right-icon
@ -39,7 +39,8 @@ export default {
return { return {
loading: false, loading: false,
permissions: [], permissions: [],
errors: false errors: false,
isContinue: false
} }
}, },
created () { created () {
@ -54,6 +55,24 @@ export default {
if (response.data) { if (response.data) {
this.permissions = response.data.permissions.permissions this.permissions = response.data.permissions.permissions
this.errors = response.data.permissions.errors this.errors = response.data.permissions.errors
let self = this
if (this.errors) {
swal({
title: this.$t('wizard.permissions.permission_confirm_title'),
text: this.$t('wizard.permissions.permission_confirm_desc'),
icon: 'warning',
buttons: true,
dangerMode: true
}).then(async (willConfirm) => {
if (willConfirm) {
self.isContinue = true
}
})
} else {
this.isContinue = true
}
this.loading = false this.loading = false
} }
}, },

View File

@ -351,7 +351,8 @@ fieldset[disabled] .multiselect {
color: $ls-color-gray; color: $ls-color-gray;
} }
.multiselect--disabled .multiselect__input { .multiselect--disabled .multiselect__input,
.multiselect--disabled .multiselect__single {
background: $ls-color-gray--light; background: $ls-color-gray--light;
color: $ls-color-gray; color: $ls-color-gray;
} }

View File

@ -49,7 +49,6 @@ Route::group(['prefix' => 'reports'], function () {
}); });
Route::get('/invoices/pdf/{id}', [ Route::get('/invoices/pdf/{id}', [
'as' => 'get.invoice.pdf', 'as' => 'get.invoice.pdf',
'uses' => 'FrontendController@getInvoicePdf' 'uses' => 'FrontendController@getInvoicePdf'

View File

@ -65,8 +65,8 @@ class CompanySettingTest extends TestCase
$company = [ $company = [
'name' => 'XYZ', 'name' => 'XYZ',
'country_id' => 2, 'country_id' => 2,
'state_id' => 3, 'state' => 'city',
'city_id' => 4, 'city' => 'state',
'address_street_1' => 'test1', 'address_street_1' => 'test1',
'address_street_2' => 'test2', 'address_street_2' => 'test2',
'phone' => '1234567890', 'phone' => '1234567890',
@ -80,8 +80,8 @@ class CompanySettingTest extends TestCase
$address2 = $response->decodeResponseJson()['user']['addresses'][0]; $address2 = $response->decodeResponseJson()['user']['addresses'][0];
$this->assertEquals($company['name'], $company2['name']); $this->assertEquals($company['name'], $company2['name']);
$this->assertEquals($company['country_id'], $address2['country_id']); $this->assertEquals($company['country_id'], $address2['country_id']);
$this->assertEquals($company['state_id'], $address2['state_id']); $this->assertEquals($company['state'], $address2['state']);
$this->assertEquals($company['city_id'], $address2['city_id']); $this->assertEquals($company['city'], $address2['city']);
$this->assertEquals($company['address_street_1'], $address2['address_street_1']); $this->assertEquals($company['address_street_1'], $address2['address_street_1']);
$this->assertEquals($company['address_street_2'], $address2['address_street_2']); $this->assertEquals($company['address_street_2'], $address2['address_street_2']);
$this->assertEquals($company['phone'], $address2['phone']); $this->assertEquals($company['phone'], $address2['phone']);

View File

@ -5,8 +5,6 @@ use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker; use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\RefreshDatabase;
use Crater\Country; use Crater\Country;
use Crater\State;
use Crater\City;
use SettingsSeeder; use SettingsSeeder;
class LocationTest extends TestCase class LocationTest extends TestCase
{ {
@ -26,20 +24,4 @@ class LocationTest extends TestCase
$response->assertOk(); $response->assertOk();
} }
/** @test */
public function testGetStates()
{
$response = $this->json('GET', 'api/states/1');
$response->assertOk();
}
/** @test */
public function testGetCities()
{
$response = $this->json('GET', 'api/cities/1');
$response->assertOk();
}
} }