1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-06 03:02:34 +01:00

Working on client import

This commit is contained in:
David Bomba 2020-12-16 21:06:20 +11:00
parent 8df553c4cc
commit 7353687c04
166 changed files with 578 additions and 4 deletions

View File

@ -79,7 +79,7 @@ class ImportController extends Controller
$hash = Str::random(32); $hash = Str::random(32);
//store the csv in cache with an expiry of 10 minutes //store the csv in cache with an expiry of 10 minutes
Cache::put($hash, base64_encode(file_get_contents($request->file('file')->getPathname())), 60); Cache::put($hash, base64_encode(file_get_contents($request->file('file')->getPathname())), 3600);
//parse CSV //parse CSV
$csv_array = $this->getCsvData(file_get_contents($request->file('file')->getPathname())); $csv_array = $this->getCsvData(file_get_contents($request->file('file')->getPathname()));

View File

@ -0,0 +1,352 @@
<?php
namespace App\Import\Transformers;
use Carbon;
use Exception;
/**
* Class BaseTransformer.
*/
class BaseTransformer
{
/**
* @var
*/
protected $maps;
/**
* BaseTransformer constructor.
*
* @param $maps
*/
public function __construct($maps)
{
$this->maps = $maps;
}
/**
* @param $data
* @param $field
*
* @return string
*/
public function getString($data, $field)
{
return (isset($data[$field]) && $data[$field]) ? $data[$field] : '';
}
public function getCurrencyByCode($data)
{
$code = $data['client.currency_id'];
info(print_r($this->maps['currencies']->where('code', $code)->first(),1));
if($code)
return $this->maps['currencies']->where('code', $code)->first()->id;
return $this->maps['company']->settings->currency_id;
}
/**
* @param $name
*
* @return bool
*/
public function hasClient($name)
{
$name = trim(strtolower($name));
return isset($this->maps[ENTITY_CLIENT][$name]);
}
/**
* @param $name
*
* @return bool
*/
public function hasVendor($name)
{
$name = trim(strtolower($name));
return isset($this->maps[ENTITY_VENDOR][$name]);
}
/**
* @param $key
*
* @return bool
*/
public function hasProduct($key)
{
$key = trim(strtolower($key));
return isset($this->maps[ENTITY_PRODUCT][$key]);
}
/**
* @param $data
* @param $field
*
* @return int
*/
public function getNumber($data, $field)
{
return (isset($data->$field) && $data->$field) ? $data->$field : 0;
}
/**
* @param $data
* @param $field
*
* @return float
*/
public function getFloat($data, $field)
{
return (isset($data->$field) && $data->$field) ? Utils::parseFloat($data->$field) : 0;
}
/**
* @param $name
*
* @return null
*/
public function getClientId($name)
{
$name = strtolower(trim($name));
return isset($this->maps[ENTITY_CLIENT][$name]) ? $this->maps[ENTITY_CLIENT][$name] : null;
}
/**
* @param $name
*
* @return null
*/
public function getProduct($data, $key, $field, $default = false)
{
$productKey = trim(strtolower($data->$key));
if (! isset($this->maps['product'][$productKey])) {
return $default;
}
$product = $this->maps['product'][$productKey];
return $product->$field ?: $default;
}
/**
* @param $name
*
* @return null
*/
public function getContact($email)
{
$email = trim(strtolower($email));
if (! isset($this->maps['contact'][$email])) {
return false;
}
return $this->maps['contact'][$email];
}
/**
* @param $name
*
* @return null
*/
public function getCustomer($key)
{
$key = trim($key);
if (! isset($this->maps['customer'][$key])) {
return false;
}
return $this->maps['customer'][$key];
}
/**
* @param $name
*
* @return null
*/
public function getCountryId($name)
{
$name = strtolower(trim($name));
return isset($this->maps['countries'][$name]) ? $this->maps['countries'][$name] : null;
}
/**
* @param $name
*
* @return null
*/
public function getCountryIdBy2($name)
{
$name = strtolower(trim($name));
return isset($this->maps['countries2'][$name]) ? $this->maps['countries2'][$name] : null;
}
/**
* @param $name
*
* @return null
*/
public function getTaxRate($name)
{
$name = strtolower(trim($name));
return isset($this->maps['tax_rates'][$name]) ? $this->maps['tax_rates'][$name] : 0;
}
/**
* @param $name
*
* @return null
*/
public function getTaxName($name)
{
$name = strtolower(trim($name));
return isset($this->maps['tax_names'][$name]) ? $this->maps['tax_names'][$name] : '';
}
/**
* @param $name
*
* @return mixed
*/
public function getFirstName($name)
{
$name = Utils::splitName($name);
return $name[0];
}
/**
* @param $date
* @param string $format
* @param mixed $data
* @param mixed $field
*
* @return null
*/
public function getDate($data, $field)
{
if ($date = data_get($data, $field)) {
try {
$date = new Carbon($date);
} catch (Exception $e) {
// if we fail to parse return blank
$date = false;
}
}
return $date ? $date->format('Y-m-d') : null;
}
/**
* @param $name
*
* @return mixed
*/
public function getLastName($name)
{
$name = Utils::splitName($name);
return $name[1];
}
/**
* @param $number
*
* @return string
*/
public function getInvoiceNumber($number)
{
return $number ? str_pad(trim($number), 4, '0', STR_PAD_LEFT) : null;
}
/**
* @param $invoiceNumber
*
* @return null
*/
public function getInvoiceId($invoiceNumber)
{
$invoiceNumber = $this->getInvoiceNumber($invoiceNumber);
$invoiceNumber = strtolower($invoiceNumber);
return isset($this->maps[ENTITY_INVOICE][$invoiceNumber]) ? $this->maps[ENTITY_INVOICE][$invoiceNumber] : null;
}
/**
* @param $invoiceNumber
*
* @return null
*/
public function getInvoicePublicId($invoiceNumber)
{
$invoiceNumber = $this->getInvoiceNumber($invoiceNumber);
$invoiceNumber = strtolower($invoiceNumber);
return isset($this->maps['invoices'][$invoiceNumber]) ? $this->maps['invoices'][$invoiceNumber]->public_id : null;
}
/**
* @param $invoiceNumber
*
* @return bool
*/
public function hasInvoice($invoiceNumber)
{
$invoiceNumber = $this->getInvoiceNumber($invoiceNumber);
$invoiceNumber = strtolower($invoiceNumber);
return isset($this->maps[ENTITY_INVOICE][$invoiceNumber]);
}
/**
* @param $invoiceNumber
*
* @return null
*/
public function getInvoiceClientId($invoiceNumber)
{
$invoiceNumber = $this->getInvoiceNumber($invoiceNumber);
$invoiceNumber = strtolower($invoiceNumber);
return isset($this->maps[ENTITY_INVOICE.'_'.ENTITY_CLIENT][$invoiceNumber]) ? $this->maps[ENTITY_INVOICE.'_'.ENTITY_CLIENT][$invoiceNumber] : null;
}
/**
* @param $name
*
* @return null
*/
public function getVendorId($name)
{
$name = strtolower(trim($name));
return isset($this->maps[ENTITY_VENDOR][$name]) ? $this->maps[ENTITY_VENDOR][$name] : null;
}
/**
* @param $name
*
* @return null
*/
public function getExpenseCategoryId($name)
{
$name = strtolower(trim($name));
return isset($this->maps[ENTITY_EXPENSE_CATEGORY][$name]) ? $this->maps[ENTITY_EXPENSE_CATEGORY][$name] : null;
}
}

View File

@ -0,0 +1,70 @@
<?php
namespace App\Import\Transformers;
use Illuminate\Support\Str;
/**
* Class ClientTransformer.
*/
class ClientTransformer extends BaseTransformer
{
/**
* @param $data
*
* @return bool|Item
*/
public function transform($data)
{
if (isset($data->name) && $this->hasClient($data->name)) {
return false;
}
$settings = new \stdClass;
$settings->currency_id = (string)$this->getCurrencyByCode($data);
return [
'company_id' => $this->maps['company']->id,
'name' => $this->getString($data, 'client.name'),
'work_phone' => $this->getString($data, 'client.phone'),
'address1' => $this->getString($data, 'client.address1'),
'address2' => $this->getString($data, 'client.address2'),
'city' => $this->getString($data, 'client.city'),
'state' => $this->getString($data, 'client.state'),
'shipping_address1' => $this->getString($data, 'client.shipping_address1'),
'shipping_address2' => $this->getString($data, 'client.shipping_address2'),
'shipping_city' => $this->getString($data, 'client.shipping_city'),
'shipping_state' => $this->getString($data, 'client.shipping_state'),
'shipping_postal_code' => $this->getString($data, 'client.shipping_postal_code'),
'public_notes' => $this->getString($data, 'client.public_notes'),
'private_notes' => $this->getString($data, 'client.private_notes'),
'website' => $this->getString($data, 'client.website'),
'vat_number' => $this->getString($data, 'client.vat_number'),
'id_number' => $this->getString($data, 'client.id_number'),
'custom_value1' => $this->getString($data, 'client.custom1'),
'custom_value2' => $this->getString($data, 'client.custom2'),
'custom_value3' => $this->getString($data, 'client.custom3'),
'custom_value4' => $this->getString($data, 'client.custom4'),
'balance' => $this->getString($data, 'client.balance'),
'paid_to_date' => $this->getString($data, 'client.paid_to_date'),
'credit_balance' => 0,
'settings' => $settings,
'client_hash' => Str::random(40),
'contacts' => [
[
'first_name' => $this->getString($data, 'contact.first_name'),
'last_name' => $this->getString($data, 'contact.last_name'),
'email' => $this->getString($data, 'contact.email'),
'phone' => $this->getString($data, 'contact.phone'),
'custom_value1' => $this->getString($data, 'contact.custom1'),
'custom_value2' => $this->getString($data, 'contact.custom2'),
'custom_value3' => $this->getString($data, 'contact.custom3'),
'custom_value4' => $this->getString($data, 'contact.custom4'),
],
],
'country_id' => isset($data->country_id) ? $this->getCountryId($data->country_id) : null,
'shipping_country_id' => isset($data->shipping_country_id) ? $this->getCountryId($data->shipping_country_id) : null,
];
}
}

View File

@ -11,8 +11,16 @@
namespace App\Jobs\Import; namespace App\Jobs\Import;
use App\Factory\ClientFactory;
use App\Http\Requests\Client\StoreClientRequest;
use App\Import\Transformers\ClientTransformer;
use App\Libraries\MultiDB; use App\Libraries\MultiDB;
use App\Models\Client;
use App\Models\Company; use App\Models\Company;
use App\Models\Currency;
use App\Models\User;
use App\Repositories\ClientContactRepository;
use App\Repositories\ClientRepository;
use Exception; use Exception;
use Illuminate\Bus\Queueable; use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Contracts\Queue\ShouldQueue;
@ -21,8 +29,11 @@ use Illuminate\Http\Request;
use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;
use League\Csv\Reader; use League\Csv\Reader;
use League\Csv\Statement; use League\Csv\Statement;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Auth;
class CSVImport implements ShouldQueue class CSVImport implements ShouldQueue
{ {
@ -40,6 +51,12 @@ class CSVImport implements ShouldQueue
public $column_map; public $column_map;
public $import_array;
public $error_array;
public $maps;
/* /*
[hash] => 2lTm7HVR3i9Zv3y86eQYZIO16yVJ7J6l [hash] => 2lTm7HVR3i9Zv3y86eQYZIO16yVJ7J6l
[entity_type] => client [entity_type] => client
@ -84,7 +101,51 @@ class CSVImport implements ShouldQueue
{ {
MultiDB::setDb($this->company->db); MultiDB::setDb($this->company->db);
foreach($this->getCsv() as $record) { $this->company->owner()->setCompany($this->company);
Auth::login($this->company->owner(), true);
$this->buildMaps();
//sort the array by key
ksort($this->column_map);
//clients
$records = $this->getCsvData();
$contact_repository = new ClientContactRepository();
$client_repository = new ClientRepository($contact_repository);
$client_transformer = new ClientTransformer($this->maps);
if($this->skip_header)
array_shift($records);
foreach($records as $record) {
$keys = $this->column_map;
$values = array_intersect_key($record, $this->column_map);
$client_data = array_combine($keys, $values);
$client = $client_transformer->transform($client_data);
$validator = Validator::make($client, (new StoreClientRequest())->rules());
if ($validator->fails()) {
$this->error_array[] = ['client' => $client, 'error' => json_encode($validator->errors())];
}
else{
$client = $client_repository->save($client, ClientFactory::create($this->company->id, $this->setUser($record)));
if(array_key_exists('client.balance', $client_data))
$client->balance = preg_replace('/[^0-9,.]+/', '', $client_data['client.balance']);
if(array_key_exists('client.paid_to_date', $client_data))
$client->paid_to_date = preg_replace('/[^0-9,.]+/', '', $client_data['client.paid_to_date']);
$client->save();
$this->import_array['clients'][] = $client->id;
}
} }
@ -95,10 +156,46 @@ class CSVImport implements ShouldQueue
} }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
private function buildMaps()
{
$this->maps['currencies'] = Currency::all();
$this->maps['users'] = $this->company->users;
$this->maps['company'] = $this->company;
return $this;
}
private function setUser($record)
{
$user_key_exists = array_search('client.user_id', $this->column_map);
if($user_key_exists)
return $this->findUser($record[$user_key_exists]);
else
return $this->company->owner()->id;
}
private function findUser($user_hash)
{
$user = User::where('company_id', $this->company->id)
->where(\DB::raw('CONCAT_WS(" ", first_name, last_name)'), 'like', '%' . $user_hash . '%')
->first();
if($user)
return $user->id;
else
return $this->company->owner()->id;
}
private function getCsvData() private function getCsvData()
{ {
$base64_encoded_csv = Cache::get($this->hash); $base64_encoded_csv = Cache::get($this->hash);
$csv = base64_decode($base64_encoded_csv); $csv = base64_decode($base64_encoded_csv);
$csv = Reader::createFromString($csv);
$stmt = new Statement(); $stmt = new Statement();
$data = iterator_to_array($stmt->process($csv)); $data = iterator_to_array($stmt->process($csv));
@ -109,7 +206,7 @@ class CSVImport implements ShouldQueue
// Remove Invoice Ninja headers // Remove Invoice Ninja headers
if (count($headers) && count($data) > 4) { if (count($headers) && count($data) > 4) {
$firstCell = $headers[0]; $firstCell = $headers[0];
if (strstr($firstCell, APP_NAME)) { if (strstr($firstCell, config('ninja.app_name'))) {
array_shift($data); // Invoice Ninja... array_shift($data); // Invoice Ninja...
array_shift($data); // <blank line> array_shift($data); // <blank line>
array_shift($data); // Enitty Type Header array_shift($data); // Enitty Type Header

0
public/.htaccess Normal file → Executable file
View File

0
public/assets/AssetManifest.json Normal file → Executable file
View File

0
public/assets/FontManifest.json Normal file → Executable file
View File

0
public/assets/LICENSE Normal file → Executable file
View File

0
public/assets/NOTICES Normal file → Executable file
View File

0
public/assets/assets/images/google-icon.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

0
public/assets/assets/images/logo.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

0
public/assets/assets/images/payment_types/ach.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

0
public/assets/assets/images/payment_types/amex.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

0
public/assets/assets/images/payment_types/discover.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

0
public/assets/assets/images/payment_types/jcb.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

0
public/assets/assets/images/payment_types/laser.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

0
public/assets/assets/images/payment_types/maestro.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

0
public/assets/assets/images/payment_types/other.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

0
public/assets/assets/images/payment_types/paypal.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

0
public/assets/assets/images/payment_types/solo.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

0
public/assets/assets/images/payment_types/switch.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 938 B

After

Width:  |  Height:  |  Size: 938 B

0
public/assets/assets/images/payment_types/unionpay.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

0
public/assets/assets/images/payment_types/visa.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

0
public/assets/fonts/MaterialIcons-Regular.otf Normal file → Executable file
View File

0
public/assets/fonts/MaterialIcons-Regular.ttf Normal file → Executable file
View File

0
public/assets/fonts/Roboto-Regular.ttf Normal file → Executable file
View File

View File

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 881 B

After

Width:  |  Height:  |  Size: 881 B

View File

Before

Width:  |  Height:  |  Size: 704 B

After

Width:  |  Height:  |  Size: 704 B

View File

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

Before

Width:  |  Height:  |  Size: 162 B

After

Width:  |  Height:  |  Size: 162 B

View File

0
public/assets/web/assets/fonts/Roboto-Regular.ttf Normal file → Executable file
View File

0
public/css/app.css vendored Normal file → Executable file
View File

0
public/css/card-js.min.css vendored Normal file → Executable file
View File

0
public/css/ninja.css vendored Normal file → Executable file
View File

0
public/css/ninja.min.css vendored Normal file → Executable file
View File

0
public/css/tailwind-1.2.0.css vendored Normal file → Executable file
View File

0
public/css/tailwindcss@1.4.6.css vendored Normal file → Executable file
View File

0
public/favicon.ico Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

0
public/favicon.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

0
public/flutter_service_worker.js vendored Normal file → Executable file
View File

0
public/icons/Icon-192.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

0
public/icons/Icon-512.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

0
public/images/american-express.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

0
public/images/created-by-invoiceninja-new.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

0
public/images/created-by-invoiceninja.jpg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

0
public/images/diners-club.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

0
public/images/discover.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

0
public/images/invoiceninja-black-logo-2.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

0
public/images/invoiceninja-white-logo.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

0
public/images/logo.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

0
public/images/mastercard.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

0
public/images/paypal.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

0
public/images/svg/activity.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 277 B

After

Width:  |  Height:  |  Size: 277 B

0
public/images/svg/align-left.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 388 B

After

Width:  |  Height:  |  Size: 388 B

0
public/images/svg/clock.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 299 B

After

Width:  |  Height:  |  Size: 299 B

0
public/images/svg/credit-card.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 324 B

After

Width:  |  Height:  |  Size: 324 B

0
public/images/svg/download.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 365 B

After

Width:  |  Height:  |  Size: 365 B

0
public/images/svg/file-text.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 468 B

After

Width:  |  Height:  |  Size: 468 B

0
public/images/svg/file.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 332 B

After

Width:  |  Height:  |  Size: 332 B

0
public/images/svg/shield.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 274 B

After

Width:  |  Height:  |  Size: 274 B

0
public/images/svg/user.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 308 B

After

Width:  |  Height:  |  Size: 308 B

0
public/images/visa.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

0
public/index.php Normal file → Executable file
View File

0
public/js/app.js vendored Normal file → Executable file
View File

0
public/js/client_create.js vendored Normal file → Executable file
View File

0
public/js/client_create.min.js vendored Normal file → Executable file
View File

0
public/js/client_edit.js vendored Normal file → Executable file
View File

0
public/js/client_edit.min.js vendored Normal file → Executable file
View File

0
public/js/client_list.js vendored Normal file → Executable file
View File

0
public/js/client_list.min.js vendored Normal file → Executable file
View File

0
public/js/client_settings.js vendored Normal file → Executable file
View File

0
public/js/client_settings.min.js vendored Normal file → Executable file
View File

0
public/js/client_show.js vendored Normal file → Executable file
View File

0
public/js/client_show.min.js vendored Normal file → Executable file
View File

0
public/js/clients/invoices/action-selectors.js vendored Normal file → Executable file
View File

View File

0
public/js/clients/invoices/payment.js vendored Normal file → Executable file
View File

0
public/js/clients/invoices/payment.js.LICENSE.txt Normal file → Executable file
View File

0
public/js/clients/payment_methods/authorize-ach.js vendored Normal file → Executable file
View File

View File

0
public/js/clients/payment_methods/authorize-authorize-card.js vendored Normal file → Executable file
View File

0
public/js/clients/payment_methods/authorize-stripe-card.js vendored Normal file → Executable file
View File

View File

0
public/js/clients/payment_methods/stripe-ach.js vendored Normal file → Executable file
View File

0
public/js/clients/payments/alipay.js vendored Normal file → Executable file
View File

0
public/js/clients/payments/alipay.js.LICENSE.txt Normal file → Executable file
View File

0
public/js/clients/payments/authorize-credit-card-payment.js vendored Normal file → Executable file
View File

0
public/js/clients/payments/card-js.min.js vendored Normal file → Executable file
View File

0
public/js/clients/payments/checkout.com.js vendored Normal file → Executable file
View File

0
public/js/clients/payments/checkout.com.js.LICENSE.txt Normal file → Executable file
View File

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