├── public
├── favicon.ico
├── robots.txt
├── img
│ ├── invextry-ss1.png
│ ├── invextry-ss2.png
│ ├── invextry-ss3.png
│ ├── placeholder.png
│ ├── invextry-logo.png
│ └── invextry-social.png
├── .htaccess
└── index.php
├── A2ZTRACK
├── problems-solutions.txt
├── modules.txt
└── module-checklist.txt
├── database
├── .gitignore
├── seeders
│ ├── CreateApp.php
│ ├── TaxSeeder.php
│ ├── WarehouseSeeder.php
│ ├── SuperAdminSeeder.php
│ ├── AccountSeeder.php
│ ├── UnitSeeder.php
│ ├── BrandSeeder.php
│ └── ProductCategorySeeder.php
├── migrations
│ ├── 2023_07_1_141608_create_invextry_meta_table.php
│ ├── 2023_08_05_182000_create_payment_methods_table.php
│ ├── 2023_07_28_152756_create_brands_table.php
│ ├── 2023_07_26_124157_create_taxes_table.php
│ ├── 2014_10_12_100000_create_password_reset_tokens_table.php
│ ├── 2023_07_31_124517_create_product_categories_table.php
│ ├── 2023_07_19_141527_create_currencies_table.php
│ ├── 2023_08_05_136533_create_account_adjustments_table.php
│ ├── 2023_07_26_182430_create_warehouses_table.php
│ ├── 2019_08_19_000000_create_failed_jobs_table.php
│ ├── 2023_08_05_136435_create_accounts_table.php
│ ├── 2014_10_12_000000_create_users_table.php
│ ├── 2023_07_23_134907_create_units_table.php
│ ├── 2019_12_14_000001_create_personal_access_tokens_table.php
│ ├── 2023_08_02_155740_create_product_stocks_table.php
│ ├── 2023_08_05_181011_create_invoice_items_table.php
│ ├── 2023_08_05_183542_create_payments_table.php
│ ├── 2020_10_12_000000_add_variants_to_media.php
│ └── 2023_08_05_135214_create_parties_table.php
└── factories
│ └── UserFactory.php
├── bootstrap
├── cache
│ └── .gitignore
└── app.php
├── storage
├── logs
│ └── .gitignore
├── app
│ ├── public
│ │ └── .gitignore
│ └── .gitignore
├── debugbar
│ └── .gitignore
├── framework
│ ├── testing
│ │ └── .gitignore
│ ├── views
│ │ └── .gitignore
│ ├── cache
│ │ ├── data
│ │ │ └── .gitignore
│ │ └── .gitignore
│ ├── sessions
│ │ └── .gitignore
│ └── .gitignore
└── demo
│ ├── brands
│ ├── hp.jpg
│ ├── mi.jpg
│ ├── rfl.jpg
│ ├── ssg.png
│ ├── arong.jpg
│ ├── asus.jpg
│ ├── bata.jpg
│ ├── casio.jpg
│ ├── dano.jpg
│ ├── dell.jpg
│ ├── eset.jpg
│ ├── fresh.jpg
│ ├── lotto.jpg
│ ├── nido.jpg
│ ├── panda.jpg
│ ├── pran.jpg
│ ├── regal.jpg
│ ├── titan.jpg
│ ├── yamah.jpg
│ ├── oriant.jpg
│ ├── philip.jpg
│ ├── samsung.png
│ ├── vision.jpg
│ ├── walton.jpg
│ └── pepsodent.jpg
│ ├── products
│ ├── Jeans.jpg
│ ├── dates.jpg
│ ├── fanta.jpg
│ ├── iphone.jpg
│ ├── kitkat.jpg
│ ├── mango.webp
│ ├── mi-tv.jpg
│ ├── mojo.webp
│ ├── oreo.jpg
│ ├── pepsi.jpg
│ ├── pepsi.webp
│ ├── polo.png
│ ├── sauce.webp
│ ├── shirt.jpg
│ ├── toy.webp
│ ├── chicken.webp
│ ├── coconut.webp
│ ├── dettol.webp
│ ├── hand-beg.jpg
│ ├── heater.webp
│ ├── hilsha.webp
│ ├── noodles.webp
│ ├── sony-tv.jpg
│ ├── asus-laptop.jpg
│ ├── casual-shoe.jpg
│ ├── cloth-beg.jpg
│ ├── dairy-milk.jpg
│ ├── handwash.webp
│ ├── loafer-shoe.jpg
│ ├── rupchanda.webp
│ ├── vision-tv.jpg
│ ├── vivo-phone.jpg
│ ├── apex-slipper.jpg
│ ├── cc-tv-camera.jpg
│ ├── infinix-phone.jpg
│ ├── leather-shoe.jpg
│ ├── nikkon-camera.jpg
│ ├── sneakers-shoe.jpg
│ ├── sports-camera.jpg
│ ├── step-out-beg.png
│ ├── macbook-laptop.jpg
│ └── bangladesh-jersey.webp
│ └── product-categories
│ ├── beg.jpg
│ ├── oil.png
│ ├── toy.jpg
│ ├── tv.jpg
│ ├── camera.jpg
│ ├── drinks.jpg
│ ├── glass.jpg
│ ├── laptop.png
│ ├── shoe.jpg
│ ├── tablet.jpg
│ ├── watch.jpg
│ ├── fruits.webp
│ ├── t-shirt.jpg
│ ├── chocolate.jpg
│ ├── furniture.jpg
│ ├── headphone.jpg
│ ├── milk-powder.jpg
│ └── smart-phone.jpg
├── resources
├── admin-resources
│ ├── modules
│ │ └── user
│ │ │ └── userStore.js
│ ├── assets
│ │ ├── css
│ │ │ └── main.css
│ │ ├── img
│ │ │ └── invextry-logo.png
│ │ └── icons
│ │ │ ├── menu-svg-icon.vue
│ │ │ ├── filter-svg-icon.vue
│ │ │ ├── square-svg-icon.vue
│ │ │ ├── booklet-svg-icon.vue
│ │ │ ├── box-svg-icon.vue
│ │ │ ├── cross-svg-icon.vue
│ │ │ ├── bin-svg-icon.vue
│ │ │ ├── qrcode-svg-icon.vue
│ │ │ ├── edit-svg-icon.vue
│ │ │ ├── plus-svg-icon.vue
│ │ │ ├── wallet-svg-icon.vue
│ │ │ ├── logout-svg-icon.vue
│ │ │ ├── more-svg-icon.vue
│ │ │ ├── customer-svg-icon.vue
│ │ │ ├── supplier-svg-icon.vue
│ │ │ ├── sort-svg-icon.vue
│ │ │ ├── beg-svg-icon.vue
│ │ │ ├── cart-svg-icon.vue
│ │ │ ├── view-svg-icon.vue
│ │ │ ├── twentyfour-svg-icon.vue
│ │ │ ├── user-svg-icon.vue
│ │ │ ├── coin-1-svg-icon.vue
│ │ │ ├── dashboard-svg-icon.vue
│ │ │ ├── globe-svg-icon.vue
│ │ │ ├── setting-svg-icon.vue
│ │ │ └── hand-love-svg-icon.vue
│ ├── views
│ │ ├── App.vue
│ │ └── Admin.vue
│ ├── utils
│ │ ├── format-validation-errors.js
│ │ └── file.js
│ ├── components
│ │ ├── buttons
│ │ │ ├── AddNewButton.vue
│ │ │ ├── FilterButton.vue
│ │ │ └── BulkDeleteButton.vue
│ │ ├── img
│ │ │ └── ImagesBox.vue
│ │ └── shared
│ │ │ ├── notification
│ │ │ ├── notificationStore.js
│ │ │ ├── notications-container.vue
│ │ │ └── notification.vue
│ │ │ ├── confirm-alert
│ │ │ ├── confirmStore.js
│ │ │ └── confirm-box.vue
│ │ │ └── loader
│ │ │ └── Loader.vue
│ ├── stores
│ │ ├── sidebar.js
│ │ └── authStore.js
│ ├── main.js
│ └── plugins
│ │ └── axios-settings.js
└── views
│ └── admin
│ └── app.blade.php
├── routes
├── api.php
├── channels.php
└── console.php
├── tests
├── TestCase.php
├── Unit
│ └── ExampleTest.php
├── Feature
│ └── ExampleTest.php
└── CreatesApplication.php
├── .gitattributes
├── app
├── Models
│ ├── Invoice
│ │ ├── InvoiceItem.php
│ │ └── Invoice.php
│ ├── Setting
│ │ ├── Tax.php
│ │ ├── Currency.php
│ │ └── Warehouse.php
│ ├── Product
│ │ ├── Brand.php
│ │ ├── ProductCategory.php
│ │ ├── Unit.php
│ │ └── Product.php
│ ├── Party.php
│ ├── Accounting
│ │ ├── Account.php
│ │ └── AccountAdjustment.php
│ ├── Payment.php
│ └── User.php
├── Http
│ ├── Controllers
│ │ ├── Controller.php
│ │ ├── Api
│ │ │ ├── User
│ │ │ │ └── UserController.php
│ │ │ ├── Payment
│ │ │ │ └── PaymentController.php
│ │ │ ├── Dashboard
│ │ │ │ └── DashboardController.php
│ │ │ ├── Invoice
│ │ │ │ ├── SaleInvoiceController.php
│ │ │ │ └── PurchaseInvoiceController.php
│ │ │ └── Upload
│ │ │ │ └── UploadController.php
│ │ └── Auth
│ │ │ ├── RegisterController.php
│ │ │ └── LoginController.php
│ ├── Middleware
│ │ ├── EncryptCookies.php
│ │ ├── VerifyCsrfToken.php
│ │ ├── PreventRequestsDuringMaintenance.php
│ │ ├── TrimStrings.php
│ │ ├── TrustHosts.php
│ │ ├── Authenticate.php
│ │ ├── ValidateSignature.php
│ │ ├── ViewOnly.php
│ │ ├── PreventXSS.php
│ │ ├── TrustProxies.php
│ │ └── RedirectIfAuthenticated.php
│ ├── Resources
│ │ ├── Tax
│ │ │ ├── TaxCollection.php
│ │ │ └── TaxResource.php
│ │ ├── Unit
│ │ │ ├── UnitCollection.php
│ │ │ └── UnitResource.php
│ │ ├── Brand
│ │ │ ├── BrandCollection.php
│ │ │ └── BrandResource.php
│ │ ├── Party
│ │ │ ├── CustomerListCollection.php
│ │ │ ├── SupplierListCollection.php
│ │ │ ├── CustomerListResource.php
│ │ │ ├── SupplierListResource.php
│ │ │ ├── CustomerDetailsRerource.php
│ │ │ └── SupplierDetailsRerource.php
│ │ ├── Product
│ │ │ ├── ProductListCollection.php
│ │ │ ├── ProductCategoryCollection.php
│ │ │ ├── ProductCategoryResource.php
│ │ │ ├── ProductListResource.php
│ │ │ └── SingleProductResource.php
│ │ ├── Warehouse
│ │ │ ├── WarehouseCollection.php
│ │ │ └── WarehouseResource.php
│ │ ├── Currency
│ │ │ ├── CurrencyCollection.php
│ │ │ └── CurrencyResource.php
│ │ ├── Accounting
│ │ │ ├── AdjustmentResource.php
│ │ │ └── AccountResource.php
│ │ └── Invoice
│ │ │ ├── SaleListResource.php
│ │ │ └── PurchaseListResource.php
│ └── Requests
│ │ ├── Tax
│ │ ├── CreateTaxRequest.php
│ │ └── UpdateTaxRequest.php
│ │ ├── Currency
│ │ ├── CreateCurrencyRequest.php
│ │ └── UpdateCurrencyRequest.php
│ │ ├── Warehouse
│ │ ├── CreateWarehouseRequest.php
│ │ └── UpdateWarehouseRequest.php
│ │ ├── Brand
│ │ ├── CreateBrandRequest.php
│ │ └── UpdateBrandRequest.php
│ │ ├── Product
│ │ ├── CreateProductCategoryRequest.php
│ │ ├── UpdateProductCategoryRequest.php
│ │ ├── CreateProductRequest.php
│ │ └── UpdateProductRequest.php
│ │ ├── Unit
│ │ ├── CreateUnitRequest.php
│ │ └── UpdateUnitRequest.php
│ │ ├── Accounting
│ │ ├── CreateAdjustmentRequest.php
│ │ ├── UpdateAdjustmentRequest.php
│ │ ├── CreateAccountRequest.php
│ │ └── UpdateAccountRequest.php
│ │ ├── Payment
│ │ └── CreatePaymentRequest.php
│ │ └── Party
│ │ ├── CreateCustomerRequest.php
│ │ ├── CreateSupplierRequest.php
│ │ ├── UpdateCustomerRequest.php
│ │ └── UpdateSupplierRequest.php
├── Providers
│ ├── BroadcastServiceProvider.php
│ ├── AppServiceProvider.php
│ ├── AuthServiceProvider.php
│ ├── EventServiceProvider.php
│ └── RouteServiceProvider.php
├── Console
│ └── Kernel.php
├── Services
│ ├── AccountAdjustmentService.php
│ └── StockService.php
└── Exceptions
│ └── Handler.php
├── .editorconfig
├── .gitignore
├── vite.config.js
├── package.json
├── config
├── cors.php
├── services.php
├── view.php
└── hashing.php
├── phpunit.xml
├── .env.example
├── License.txt
└── artisan
/public/favicon.ico:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/A2ZTRACK/problems-solutions.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/database/.gitignore:
--------------------------------------------------------------------------------
1 | *.sqlite*
2 |
--------------------------------------------------------------------------------
/bootstrap/cache/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/logs/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow:
3 |
--------------------------------------------------------------------------------
/resources/admin-resources/modules/user/userStore.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/storage/app/public/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/debugbar/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/app/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !public/
3 | !.gitignore
4 |
--------------------------------------------------------------------------------
/storage/framework/testing/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/framework/views/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/framework/cache/data/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/framework/sessions/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/framework/cache/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !data/
3 | !.gitignore
4 |
--------------------------------------------------------------------------------
/resources/admin-resources/assets/css/main.css:
--------------------------------------------------------------------------------
1 | @import './bootstrap.css';
2 | @import './app.css';
--------------------------------------------------------------------------------
/public/img/invextry-ss1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/public/img/invextry-ss1.png
--------------------------------------------------------------------------------
/public/img/invextry-ss2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/public/img/invextry-ss2.png
--------------------------------------------------------------------------------
/public/img/invextry-ss3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/public/img/invextry-ss3.png
--------------------------------------------------------------------------------
/public/img/placeholder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/public/img/placeholder.png
--------------------------------------------------------------------------------
/storage/demo/brands/hp.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/brands/hp.jpg
--------------------------------------------------------------------------------
/storage/demo/brands/mi.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/brands/mi.jpg
--------------------------------------------------------------------------------
/storage/demo/brands/rfl.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/brands/rfl.jpg
--------------------------------------------------------------------------------
/storage/demo/brands/ssg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/brands/ssg.png
--------------------------------------------------------------------------------
/public/img/invextry-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/public/img/invextry-logo.png
--------------------------------------------------------------------------------
/storage/demo/brands/arong.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/brands/arong.jpg
--------------------------------------------------------------------------------
/storage/demo/brands/asus.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/brands/asus.jpg
--------------------------------------------------------------------------------
/storage/demo/brands/bata.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/brands/bata.jpg
--------------------------------------------------------------------------------
/storage/demo/brands/casio.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/brands/casio.jpg
--------------------------------------------------------------------------------
/storage/demo/brands/dano.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/brands/dano.jpg
--------------------------------------------------------------------------------
/storage/demo/brands/dell.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/brands/dell.jpg
--------------------------------------------------------------------------------
/storage/demo/brands/eset.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/brands/eset.jpg
--------------------------------------------------------------------------------
/storage/demo/brands/fresh.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/brands/fresh.jpg
--------------------------------------------------------------------------------
/storage/demo/brands/lotto.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/brands/lotto.jpg
--------------------------------------------------------------------------------
/storage/demo/brands/nido.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/brands/nido.jpg
--------------------------------------------------------------------------------
/storage/demo/brands/panda.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/brands/panda.jpg
--------------------------------------------------------------------------------
/storage/demo/brands/pran.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/brands/pran.jpg
--------------------------------------------------------------------------------
/storage/demo/brands/regal.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/brands/regal.jpg
--------------------------------------------------------------------------------
/storage/demo/brands/titan.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/brands/titan.jpg
--------------------------------------------------------------------------------
/storage/demo/brands/yamah.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/brands/yamah.jpg
--------------------------------------------------------------------------------
/public/img/invextry-social.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/public/img/invextry-social.png
--------------------------------------------------------------------------------
/storage/demo/brands/oriant.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/brands/oriant.jpg
--------------------------------------------------------------------------------
/storage/demo/brands/philip.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/brands/philip.jpg
--------------------------------------------------------------------------------
/storage/demo/brands/samsung.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/brands/samsung.png
--------------------------------------------------------------------------------
/storage/demo/brands/vision.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/brands/vision.jpg
--------------------------------------------------------------------------------
/storage/demo/brands/walton.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/brands/walton.jpg
--------------------------------------------------------------------------------
/storage/demo/products/Jeans.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/Jeans.jpg
--------------------------------------------------------------------------------
/storage/demo/products/dates.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/dates.jpg
--------------------------------------------------------------------------------
/storage/demo/products/fanta.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/fanta.jpg
--------------------------------------------------------------------------------
/storage/demo/products/iphone.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/iphone.jpg
--------------------------------------------------------------------------------
/storage/demo/products/kitkat.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/kitkat.jpg
--------------------------------------------------------------------------------
/storage/demo/products/mango.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/mango.webp
--------------------------------------------------------------------------------
/storage/demo/products/mi-tv.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/mi-tv.jpg
--------------------------------------------------------------------------------
/storage/demo/products/mojo.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/mojo.webp
--------------------------------------------------------------------------------
/storage/demo/products/oreo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/oreo.jpg
--------------------------------------------------------------------------------
/storage/demo/products/pepsi.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/pepsi.jpg
--------------------------------------------------------------------------------
/storage/demo/products/pepsi.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/pepsi.webp
--------------------------------------------------------------------------------
/storage/demo/products/polo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/polo.png
--------------------------------------------------------------------------------
/storage/demo/products/sauce.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/sauce.webp
--------------------------------------------------------------------------------
/storage/demo/products/shirt.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/shirt.jpg
--------------------------------------------------------------------------------
/storage/demo/products/toy.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/toy.webp
--------------------------------------------------------------------------------
/storage/demo/brands/pepsodent.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/brands/pepsodent.jpg
--------------------------------------------------------------------------------
/storage/demo/products/chicken.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/chicken.webp
--------------------------------------------------------------------------------
/storage/demo/products/coconut.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/coconut.webp
--------------------------------------------------------------------------------
/storage/demo/products/dettol.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/dettol.webp
--------------------------------------------------------------------------------
/storage/demo/products/hand-beg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/hand-beg.jpg
--------------------------------------------------------------------------------
/storage/demo/products/heater.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/heater.webp
--------------------------------------------------------------------------------
/storage/demo/products/hilsha.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/hilsha.webp
--------------------------------------------------------------------------------
/storage/demo/products/noodles.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/noodles.webp
--------------------------------------------------------------------------------
/storage/demo/products/sony-tv.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/sony-tv.jpg
--------------------------------------------------------------------------------
/resources/admin-resources/views/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/storage/demo/products/asus-laptop.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/asus-laptop.jpg
--------------------------------------------------------------------------------
/storage/demo/products/casual-shoe.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/casual-shoe.jpg
--------------------------------------------------------------------------------
/storage/demo/products/cloth-beg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/cloth-beg.jpg
--------------------------------------------------------------------------------
/storage/demo/products/dairy-milk.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/dairy-milk.jpg
--------------------------------------------------------------------------------
/storage/demo/products/handwash.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/handwash.webp
--------------------------------------------------------------------------------
/storage/demo/products/loafer-shoe.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/loafer-shoe.jpg
--------------------------------------------------------------------------------
/storage/demo/products/rupchanda.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/rupchanda.webp
--------------------------------------------------------------------------------
/storage/demo/products/vision-tv.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/vision-tv.jpg
--------------------------------------------------------------------------------
/storage/demo/products/vivo-phone.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/vivo-phone.jpg
--------------------------------------------------------------------------------
/storage/demo/product-categories/beg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/product-categories/beg.jpg
--------------------------------------------------------------------------------
/storage/demo/product-categories/oil.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/product-categories/oil.png
--------------------------------------------------------------------------------
/storage/demo/product-categories/toy.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/product-categories/toy.jpg
--------------------------------------------------------------------------------
/storage/demo/product-categories/tv.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/product-categories/tv.jpg
--------------------------------------------------------------------------------
/storage/demo/products/apex-slipper.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/apex-slipper.jpg
--------------------------------------------------------------------------------
/storage/demo/products/cc-tv-camera.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/cc-tv-camera.jpg
--------------------------------------------------------------------------------
/storage/demo/products/infinix-phone.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/infinix-phone.jpg
--------------------------------------------------------------------------------
/storage/demo/products/leather-shoe.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/leather-shoe.jpg
--------------------------------------------------------------------------------
/storage/demo/products/nikkon-camera.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/nikkon-camera.jpg
--------------------------------------------------------------------------------
/storage/demo/products/sneakers-shoe.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/sneakers-shoe.jpg
--------------------------------------------------------------------------------
/storage/demo/products/sports-camera.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/sports-camera.jpg
--------------------------------------------------------------------------------
/storage/demo/products/step-out-beg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/step-out-beg.png
--------------------------------------------------------------------------------
/storage/demo/product-categories/camera.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/product-categories/camera.jpg
--------------------------------------------------------------------------------
/storage/demo/product-categories/drinks.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/product-categories/drinks.jpg
--------------------------------------------------------------------------------
/storage/demo/product-categories/glass.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/product-categories/glass.jpg
--------------------------------------------------------------------------------
/storage/demo/product-categories/laptop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/product-categories/laptop.png
--------------------------------------------------------------------------------
/storage/demo/product-categories/shoe.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/product-categories/shoe.jpg
--------------------------------------------------------------------------------
/storage/demo/product-categories/tablet.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/product-categories/tablet.jpg
--------------------------------------------------------------------------------
/storage/demo/product-categories/watch.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/product-categories/watch.jpg
--------------------------------------------------------------------------------
/storage/demo/products/macbook-laptop.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/macbook-laptop.jpg
--------------------------------------------------------------------------------
/storage/demo/product-categories/fruits.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/product-categories/fruits.webp
--------------------------------------------------------------------------------
/storage/demo/product-categories/t-shirt.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/product-categories/t-shirt.jpg
--------------------------------------------------------------------------------
/storage/demo/products/bangladesh-jersey.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/products/bangladesh-jersey.webp
--------------------------------------------------------------------------------
/storage/demo/product-categories/chocolate.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/product-categories/chocolate.jpg
--------------------------------------------------------------------------------
/storage/demo/product-categories/furniture.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/product-categories/furniture.jpg
--------------------------------------------------------------------------------
/storage/demo/product-categories/headphone.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/product-categories/headphone.jpg
--------------------------------------------------------------------------------
/storage/demo/product-categories/milk-powder.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/product-categories/milk-powder.jpg
--------------------------------------------------------------------------------
/storage/demo/product-categories/smart-phone.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/storage/demo/product-categories/smart-phone.jpg
--------------------------------------------------------------------------------
/resources/admin-resources/assets/img/invextry-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/efthakhar/invextry/HEAD/resources/admin-resources/assets/img/invextry-logo.png
--------------------------------------------------------------------------------
/storage/framework/.gitignore:
--------------------------------------------------------------------------------
1 | compiled.php
2 | config.php
3 | down
4 | events.scanned.php
5 | maintenance.php
6 | routes.php
7 | routes.scanned.php
8 | schedule-*
9 | services.json
10 |
--------------------------------------------------------------------------------
/routes/api.php:
--------------------------------------------------------------------------------
1 | get('/user', function (Request $request) {
7 | return $request->user();
8 | });
9 |
--------------------------------------------------------------------------------
/tests/TestCase.php:
--------------------------------------------------------------------------------
1 | {
3 | erros[key] = erros[key].toString();
4 | });
5 |
6 | return erros;
7 | }
8 |
--------------------------------------------------------------------------------
/app/Models/Invoice/InvoiceItem.php:
--------------------------------------------------------------------------------
1 | assertTrue(true);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/Models/Setting/Tax.php:
--------------------------------------------------------------------------------
1 |
2 | import PlusSvg from "../../assets/icons/plus-svg-icon.vue";
3 |
4 |
5 |
9 |
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /.phpunit.cache
2 | /node_modules
3 | /public/build
4 | /public/media
5 | /public/uploads
6 | /public/hot
7 | /public/storage
8 | /storage/*.key
9 | /vendor
10 | .env
11 | .env.backup
12 | .env.production
13 | .phpunit.result.cache
14 | Homestead.json
15 | Homestead.yaml
16 | auth.json
17 | npm-debug.log
18 | yarn-error.log
19 | /.fleet
20 | /.idea
21 | /.vscode
--------------------------------------------------------------------------------
/resources/admin-resources/components/buttons/FilterButton.vue:
--------------------------------------------------------------------------------
1 |
4 |
5 |
9 |
10 |
--------------------------------------------------------------------------------
/resources/admin-resources/components/buttons/BulkDeleteButton.vue:
--------------------------------------------------------------------------------
1 |
4 |
5 |
9 |
10 |
--------------------------------------------------------------------------------
/app/Models/Setting/Currency.php:
--------------------------------------------------------------------------------
1 | Customers/Suppliers/Users -- users_meta_table
12 | 10. Purchases
13 | 11. Sales
14 | 12. Payment methods
15 | 13. Payment
16 | 14. POS SYSTEM
17 | 15. Account
18 | 16. Deposit
19 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Controller.php:
--------------------------------------------------------------------------------
1 | Create migration file
5 |
6 | > Create Model file
7 |
8 | > Create Seeder file and define permissions
9 |
10 | > Create Requests file
11 |
12 | > Create Resource and Collections file
13 |
14 | > Create necessary routes and controllers methods
15 |
16 | > Create pinia store file
17 |
18 | > Create vuejs others files
19 |
--------------------------------------------------------------------------------
/app/Models/Product/Brand.php:
--------------------------------------------------------------------------------
1 |
13 | */
14 | protected $except = [
15 | //
16 | ];
17 | }
18 |
--------------------------------------------------------------------------------
/app/Http/Resources/Tax/TaxCollection.php:
--------------------------------------------------------------------------------
1 | $this->collection,
14 | ];
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/resources/admin-resources/stores/sidebar.js:
--------------------------------------------------------------------------------
1 | import { defineStore } from "pinia";
2 |
3 | export const useSidebar = defineStore("sidebar", {
4 | state: () => ({
5 | open: true,
6 | }),
7 |
8 | getters: {
9 | getSidebarStatus: (state) => state.open,
10 | },
11 |
12 | actions: {
13 | toggle() {
14 | this.open = !this.open;
15 | },
16 | },
17 | });
18 |
--------------------------------------------------------------------------------
/app/Http/Resources/Unit/UnitCollection.php:
--------------------------------------------------------------------------------
1 | $this->collection,
14 | ];
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/Models/Product/ProductCategory.php:
--------------------------------------------------------------------------------
1 | $this->collection,
14 | ];
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/database/seeders/CreateApp.php:
--------------------------------------------------------------------------------
1 | call([
16 | RolePermissionSeeder::class,
17 | SuperAdminSeeder::class,
18 | ]);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/Http/Middleware/VerifyCsrfToken.php:
--------------------------------------------------------------------------------
1 |
13 | */
14 | protected $except = [
15 | //
16 | ];
17 | }
18 |
--------------------------------------------------------------------------------
/app/Models/Party.php:
--------------------------------------------------------------------------------
1 | 0,
14 | 'sale_return_due' => 0,
15 | 'purchase_due' => 0,
16 | 'purchase_return_due' => 0,
17 | ];
18 | }
19 |
--------------------------------------------------------------------------------
/app/Models/Product/Unit.php:
--------------------------------------------------------------------------------
1 | $this->collection,
14 | ];
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/Http/Resources/Party/SupplierListCollection.php:
--------------------------------------------------------------------------------
1 | $this->collection,
14 | ];
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/Http/Resources/Product/ProductListCollection.php:
--------------------------------------------------------------------------------
1 | $this->collection,
14 | ];
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/Http/Resources/Warehouse/WarehouseCollection.php:
--------------------------------------------------------------------------------
1 | $this->collection,
14 | ];
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/Http/Resources/Product/ProductCategoryCollection.php:
--------------------------------------------------------------------------------
1 | $this->collection,
14 | ];
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/resources/admin-resources/utils/file.js:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 |
3 | export default async function deleteUploadedFile(fileIDs) {
4 | return new Promise((resolve, reject) => {
5 | axios
6 | .delete(`/api/upload/${fileIDs}`)
7 | .then((response) => {
8 | resolve(fileIDs);
9 | })
10 | .catch((error) => {
11 | reject(error);
12 | });
13 | });
14 | }
15 |
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 | import laravel from "laravel-vite-plugin";
3 | import vue from "@vitejs/plugin-vue";
4 |
5 | export default defineConfig({
6 | plugins: [
7 | vue(),
8 | laravel({
9 | input: [
10 | // invextry backend admin assets
11 | "resources/admin-resources/main.js",
12 | ],
13 | refresh: true,
14 | }),
15 | ],
16 | });
17 |
--------------------------------------------------------------------------------
/tests/Feature/ExampleTest.php:
--------------------------------------------------------------------------------
1 | get('/');
16 |
17 | $response->assertStatus(200);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/app/Http/Resources/Tax/TaxResource.php:
--------------------------------------------------------------------------------
1 | $this->id,
15 | 'name' => $this->name,
16 | 'rate' => $this->rate,
17 | ];
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/app/Providers/BroadcastServiceProvider.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Invextry
9 |
10 |
11 |
12 | @vite('resources/admin-resources/main.js')
13 |
14 |
--------------------------------------------------------------------------------
/app/Http/Middleware/PreventRequestsDuringMaintenance.php:
--------------------------------------------------------------------------------
1 |
13 | */
14 | protected $except = [
15 | //
16 | ];
17 | }
18 |
--------------------------------------------------------------------------------
/app/Models/Accounting/Account.php:
--------------------------------------------------------------------------------
1 |
13 | */
14 | protected $except = [
15 | 'current_password',
16 | 'password',
17 | 'password_confirmation',
18 | ];
19 | }
20 |
--------------------------------------------------------------------------------
/resources/admin-resources/main.js:
--------------------------------------------------------------------------------
1 | import { createApp } from "vue";
2 | import { createPinia } from "pinia";
3 | import "./plugins/axios-settings.js";
4 | import router from "./router";
5 | import "./assets/css/main.css";
6 |
7 | import App from "./views/App.vue";
8 |
9 | const app = createApp(App);
10 | const store = createPinia();
11 |
12 | app.use(store);
13 | app.use(router);
14 |
15 | app.config.globalProperties.$demoIMG = '/img/placeholder.png'
16 |
17 | app.mount("#invextry-admin");
18 |
--------------------------------------------------------------------------------
/tests/CreatesApplication.php:
--------------------------------------------------------------------------------
1 | make(Kernel::class)->bootstrap();
18 |
19 | return $app;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/Http/Middleware/TrustHosts.php:
--------------------------------------------------------------------------------
1 |
13 | */
14 | public function hosts(): array
15 | {
16 | return [
17 | $this->allSubdomainsOfApplicationUrl(),
18 | ];
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/Providers/AppServiceProvider.php:
--------------------------------------------------------------------------------
1 | expectsJson() ? null : route('login');
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/resources/admin-resources/assets/icons/menu-svg-icon.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
20 |
21 |
--------------------------------------------------------------------------------
/app/Models/Accounting/AccountAdjustment.php:
--------------------------------------------------------------------------------
1 | belongsTo(Account::class, 'account_id');
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/resources/admin-resources/assets/icons/filter-svg-icon.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
20 |
21 |
--------------------------------------------------------------------------------
/app/Http/Resources/Currency/CurrencyCollection.php:
--------------------------------------------------------------------------------
1 |
14 | */
15 | public function toArray(Request $request): array
16 | {
17 | return [
18 | 'data' => $this->collection,
19 | ];
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/Http/Resources/Warehouse/WarehouseResource.php:
--------------------------------------------------------------------------------
1 | $this->id,
15 | 'name' => $this->name,
16 | 'email' => $this->email,
17 | 'phone' => $this->phone,
18 | 'address' => $this->address,
19 | ];
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/Http/Middleware/ValidateSignature.php:
--------------------------------------------------------------------------------
1 |
13 | */
14 | protected $except = [
15 | // 'fbclid',
16 | // 'utm_campaign',
17 | // 'utm_content',
18 | // 'utm_medium',
19 | // 'utm_source',
20 | // 'utm_term',
21 | ];
22 | }
23 |
--------------------------------------------------------------------------------
/resources/admin-resources/components/img/ImagesBox.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
![]()
13 |
14 |
15 |
16 |
17 |
18 |
28 |
--------------------------------------------------------------------------------
/app/Http/Requests/Tax/CreateTaxRequest.php:
--------------------------------------------------------------------------------
1 | ['required', 'string', Rule::unique('taxes')],
20 | 'rate' => ['required', 'numeric'],
21 | ];
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "type": "module",
4 | "scripts": {
5 | "dev": "vite",
6 | "build": "vite build"
7 | },
8 | "devDependencies": {
9 | "axios": "^1.4.0",
10 | "laravel-vite-plugin": "^0.7.5",
11 | "vite": "^4.0.0"
12 | },
13 | "dependencies": {
14 | "@vitejs/plugin-vue": "^4.2.3",
15 | "apexcharts": "^3.41.1",
16 | "pinia": "^2.1.4",
17 | "vue": "^3.2.36",
18 | "vue-apexcharts": "^1.6.2",
19 | "vue-loader": "^17.0.1",
20 | "vue-router": "^4.2.4",
21 | "vue3-apexcharts": "^1.4.4"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/routes/channels.php:
--------------------------------------------------------------------------------
1 | id === (int) $id;
18 | });
19 |
--------------------------------------------------------------------------------
/app/Http/Resources/Unit/UnitResource.php:
--------------------------------------------------------------------------------
1 | $this->id,
15 | 'name' => $this->name,
16 | 'short_name' => $this->short_name,
17 | 'base_unit_id' => $this->base_unit_id,
18 | 'operator' => $this->operator,
19 | 'operation_value' => $this->operation_value,
20 | ];
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/app/Http/Requests/Currency/CreateCurrencyRequest.php:
--------------------------------------------------------------------------------
1 | 'required|max:30|unique:currencies',
19 | 'code' => 'required|max:10|unique:currencies',
20 | 'symbol' => 'required|max:5',
21 | ];
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/Http/Resources/Currency/CurrencyResource.php:
--------------------------------------------------------------------------------
1 |
14 | */
15 | public function toArray(Request $request): array
16 | {
17 |
18 | return [
19 | 'id' => $this->id,
20 | 'name' => $this->name,
21 | 'code' => $this->code,
22 | 'symbol' => $this->symbol,
23 | ];
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/Providers/AuthServiceProvider.php:
--------------------------------------------------------------------------------
1 |
14 | */
15 | protected $policies = [
16 | //
17 | ];
18 |
19 | /**
20 | * Register any authentication / authorization services.
21 | */
22 | public function boot(): void
23 | {
24 | //
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/resources/admin-resources/assets/icons/square-svg-icon.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
20 |
21 |
--------------------------------------------------------------------------------
/app/Http/Middleware/ViewOnly.php:
--------------------------------------------------------------------------------
1 | method();
14 |
15 | if ($http_method == 'POST' || $http_method == 'PUT' || $http_method == 'DELETE') {
16 | return response()->json([
17 | 'message' => 'no permision to create, update and delete',
18 | ], 403);
19 | }
20 |
21 | return $next($request);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/Http/Resources/Accounting/AdjustmentResource.php:
--------------------------------------------------------------------------------
1 | $this->id,
14 | 'account_id' => $this->account_id,
15 | 'account' => $this->account,
16 | 'amount' => $this->amount,
17 | 'type' => $this->type,
18 | 'date' => $this->date,
19 | 'note' => $this->note,
20 | ];
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/resources/admin-resources/assets/icons/booklet-svg-icon.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
20 |
21 |
--------------------------------------------------------------------------------
/resources/admin-resources/assets/icons/box-svg-icon.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
20 |
21 |
--------------------------------------------------------------------------------
/routes/console.php:
--------------------------------------------------------------------------------
1 | comment(Inspiring::quote());
19 | })->purpose('Display an inspiring quote');
20 |
--------------------------------------------------------------------------------
/app/Http/Resources/Party/CustomerListResource.php:
--------------------------------------------------------------------------------
1 | $this->id,
15 | 'name' => $this->name,
16 | 'phone' => $this->phone,
17 | 'email' => $this->email,
18 | 'status' => $this->status,
19 | 'sale_due' => $this->sale_due,
20 | 'sale_return_due' => $this->sale_return_due,
21 | ];
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/database/migrations/2023_07_1_141608_create_invextry_meta_table.php:
--------------------------------------------------------------------------------
1 | id();
13 | $table->string('meta_key');
14 | $table->text('meta_value');
15 | $table->timestamps();
16 | });
17 | }
18 |
19 | public function down(): void
20 | {
21 | Schema::dropIfExists('invextry_meta');
22 | }
23 | };
24 |
--------------------------------------------------------------------------------
/public/.htaccess:
--------------------------------------------------------------------------------
1 |
2 |
3 | Options -MultiViews -Indexes
4 |
5 |
6 | RewriteEngine On
7 |
8 | # Handle Authorization Header
9 | RewriteCond %{HTTP:Authorization} .
10 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
11 |
12 | # Redirect Trailing Slashes If Not A Folder...
13 | RewriteCond %{REQUEST_FILENAME} !-d
14 | RewriteCond %{REQUEST_URI} (.+)/$
15 | RewriteRule ^ %1 [L,R=301]
16 |
17 | # Send Requests To Front Controller...
18 | RewriteCond %{REQUEST_FILENAME} !-d
19 | RewriteCond %{REQUEST_FILENAME} !-f
20 | RewriteRule ^ index.php [L]
21 |
22 |
--------------------------------------------------------------------------------
/app/Console/Kernel.php:
--------------------------------------------------------------------------------
1 | command('inspire')->hourly();
16 | }
17 |
18 | /**
19 | * Register the commands for the application.
20 | */
21 | protected function commands(): void
22 | {
23 | $this->load(__DIR__.'/Commands');
24 |
25 | require base_path('routes/console.php');
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/Http/Requests/Tax/UpdateTaxRequest.php:
--------------------------------------------------------------------------------
1 | route('id');
22 |
23 | return [
24 | 'name' => ['required', 'string', Rule::unique('taxes')->ignore($tax_id)],
25 | 'rate' => ['required', 'numeric'],
26 | ];
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/app/Http/Resources/Party/SupplierListResource.php:
--------------------------------------------------------------------------------
1 | $this->id,
15 | 'name' => $this->name,
16 | 'phone' => $this->phone,
17 | 'email' => $this->email,
18 | 'status' => $this->status,
19 | 'purchase_due' => $this->purchase_due,
20 | 'purchase_return_due' => $this->purchase_return_due,
21 | ];
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/database/seeders/TaxSeeder.php:
--------------------------------------------------------------------------------
1 | 1, 'name' => '1%vat', 'rate' => '1'],
12 | ['id' => 2, 'name' => '2.55%tax', 'rate' => '2.55'],
13 | ['id' => 3, 'name' => '14.5%localTax', 'rate' => '14.5'],
14 | ['id' => 4, 'name' => 'vat@5%', 'rate' => '5'],
15 | ['id' => 5, 'name' => '4% transit tax', 'rate' => '4.00'],
16 | ];
17 |
18 | public function run(): void
19 | {
20 | foreach ($this->taxes as $tax) {
21 | Tax::create($tax);
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/Http/Resources/Accounting/AccountResource.php:
--------------------------------------------------------------------------------
1 | $this->id,
14 | 'name' => $this->name,
15 | 'bank_name' => $this->bank_name,
16 | 'branch_name' => $this->branch_name,
17 | 'account_number' => $this->account_number,
18 | 'balance' => $this->balance,
19 | 'details' => $this->details,
20 | 'status' => $this->status,
21 | ];
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/Http/Middleware/PreventXSS.php:
--------------------------------------------------------------------------------
1 | all();
19 |
20 | array_walk_recursive($input, function (&$input) {
21 | $input = strip_tags($input);
22 | });
23 | $request->merge($input);
24 |
25 | return $next($request);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/resources/admin-resources/assets/icons/cross-svg-icon.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
22 |
23 |
--------------------------------------------------------------------------------
/database/seeders/WarehouseSeeder.php:
--------------------------------------------------------------------------------
1 | 1, 'name' => 'warehouse 1', 'email' => 'warehouse1@invextry.com', 'phone' => '01900000000', 'address' => 'Road no 10, sector 5, F block'],
12 | ['id' => 2, 'name' => 'warehouse 2', 'email' => 'warehouse2@invextry.com', 'phone' => '01800000000', 'address' => 'Road no 40, sector 10, K block'],
13 | ];
14 |
15 | public function run(): void
16 | {
17 | foreach ($this->warehouses as $warehouse) {
18 | Warehouse::create($warehouse);
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/resources/admin-resources/assets/icons/bin-svg-icon.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
22 |
23 |
--------------------------------------------------------------------------------
/app/Services/AccountAdjustmentService.php:
--------------------------------------------------------------------------------
1 | increment('balance', $adjustment['amount']);
22 | } elseif ($adjustment['type'] == 'subtract') {
23 | $account->decrement('balance', $adjustment['amount']);
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/database/migrations/2023_08_05_182000_create_payment_methods_table.php:
--------------------------------------------------------------------------------
1 | id();
16 | $table->string('name', 100)->unique();
17 | $table->timestamps();
18 | });
19 | }
20 |
21 | /**
22 | * Reverse the migrations.
23 | */
24 | public function down(): void
25 | {
26 | Schema::dropIfExists('payment_methods');
27 | }
28 | };
29 |
--------------------------------------------------------------------------------
/app/Exceptions/Handler.php:
--------------------------------------------------------------------------------
1 |
14 | */
15 | protected $dontFlash = [
16 | 'current_password',
17 | 'password',
18 | 'password_confirmation',
19 | ];
20 |
21 | /**
22 | * Register the exception handling callbacks for the application.
23 | */
24 | public function register(): void
25 | {
26 | $this->reportable(function (Throwable $e) {
27 | //
28 | });
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app/Http/Middleware/TrustProxies.php:
--------------------------------------------------------------------------------
1 | |string|null
14 | */
15 | protected $proxies;
16 |
17 | /**
18 | * The headers that should be used to detect proxies.
19 | *
20 | * @var int
21 | */
22 | protected $headers =
23 | Request::HEADER_X_FORWARDED_FOR |
24 | Request::HEADER_X_FORWARDED_HOST |
25 | Request::HEADER_X_FORWARDED_PORT |
26 | Request::HEADER_X_FORWARDED_PROTO |
27 | Request::HEADER_X_FORWARDED_AWS_ELB;
28 | }
29 |
--------------------------------------------------------------------------------
/database/migrations/2023_07_28_152756_create_brands_table.php:
--------------------------------------------------------------------------------
1 | id();
16 | $table->string('name')->unique();
17 | $table->string('slug')->unique();
18 | $table->timestamps();
19 | });
20 | }
21 |
22 | /**
23 | * Reverse the migrations.
24 | */
25 | public function down(): void
26 | {
27 | Schema::dropIfExists('brands');
28 | }
29 | };
30 |
--------------------------------------------------------------------------------
/resources/admin-resources/assets/icons/qrcode-svg-icon.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
22 |
23 |
--------------------------------------------------------------------------------
/resources/admin-resources/components/shared/notification/notificationStore.js:
--------------------------------------------------------------------------------
1 | import { defineStore } from "pinia";
2 |
3 | export const useNotificationStore = defineStore("notification", {
4 | state: () => ({
5 | notifications: [],
6 | }),
7 |
8 | getters: {
9 | getNotifications: (state) => state.notifications,
10 | },
11 |
12 | actions: {
13 | async pushNotification(data) {
14 | data.id = data.id || Date.now() + Math.random(1, 9);
15 | data.time = data.time || 3000;
16 | this.notifications.push(data);
17 | },
18 |
19 | async hideNotification(data) {
20 | let index = this.notifications.indexOf(data);
21 | this.notifications.splice(index, 1);
22 | },
23 | },
24 | });
25 |
--------------------------------------------------------------------------------
/app/Http/Resources/Brand/BrandResource.php:
--------------------------------------------------------------------------------
1 | media) {
16 | foreach ($this->media as $m) {
17 | $logo[] = [
18 | 'id' => $m->id,
19 | 'url' => $m->getUrl(),
20 | ];
21 | }
22 | }
23 |
24 | return [
25 | 'id' => $this->id,
26 | 'name' => $this->name,
27 | 'slug' => $this->slug,
28 | 'logo' => $logo,
29 | ];
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/database/migrations/2023_07_26_124157_create_taxes_table.php:
--------------------------------------------------------------------------------
1 | id();
16 | $table->string('name')->unique();
17 | $table->unsignedDouble('rate', 6, 3);
18 | $table->timestamps();
19 | });
20 | }
21 |
22 | /**
23 | * Reverse the migrations.
24 | */
25 | public function down(): void
26 | {
27 | Schema::dropIfExists('taxes');
28 | }
29 | };
30 |
--------------------------------------------------------------------------------
/app/Http/Requests/Warehouse/CreateWarehouseRequest.php:
--------------------------------------------------------------------------------
1 | ['required', 'string', Rule::unique('warehouses')],
20 | 'email' => ['required', 'email', Rule::unique('warehouses')],
21 | 'phone' => ['required', 'string', Rule::unique('warehouses')],
22 | 'address' => ['nullable', 'string'],
23 | ];
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/resources/admin-resources/assets/icons/edit-svg-icon.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
22 |
23 |
--------------------------------------------------------------------------------
/app/Http/Requests/Currency/UpdateCurrencyRequest.php:
--------------------------------------------------------------------------------
1 | route('id');
19 |
20 | return [
21 | 'name' => ['required', 'max:30', Rule::unique('currencies')->ignore($currency_id)],
22 | 'code' => ['required', 'max:10', Rule::unique('currencies')->ignore($currency_id)],
23 | 'symbol' => ['required', 'max:5'],
24 | ];
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/resources/admin-resources/assets/icons/plus-svg-icon.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
22 |
23 |
--------------------------------------------------------------------------------
/database/migrations/2014_10_12_100000_create_password_reset_tokens_table.php:
--------------------------------------------------------------------------------
1 | string('email')->primary();
16 | $table->string('token');
17 | $table->timestamp('created_at')->nullable();
18 | });
19 | }
20 |
21 | /**
22 | * Reverse the migrations.
23 | */
24 | public function down(): void
25 | {
26 | Schema::dropIfExists('password_reset_tokens');
27 | }
28 | };
29 |
--------------------------------------------------------------------------------
/resources/admin-resources/assets/icons/wallet-svg-icon.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
22 |
23 |
--------------------------------------------------------------------------------
/app/Http/Requests/Brand/CreateBrandRequest.php:
--------------------------------------------------------------------------------
1 | ['required', 'string', Rule::unique('brands')],
21 | 'slug' => ['required', 'string', Rule::unique('brands')],
22 | ];
23 | }
24 |
25 | protected function prepareForValidation(): void
26 | {
27 | $this->merge([
28 | 'slug' => str()->slug($this->slug),
29 | ]);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/database/migrations/2023_07_31_124517_create_product_categories_table.php:
--------------------------------------------------------------------------------
1 | id();
16 | $table->string('name')->unique();
17 | $table->string('slug')->unique();
18 | $table->timestamps();
19 | });
20 | }
21 |
22 | /**
23 | * Reverse the migrations.
24 | */
25 | public function down(): void
26 | {
27 | Schema::dropIfExists('product_categories');
28 | }
29 | };
30 |
--------------------------------------------------------------------------------
/resources/admin-resources/assets/icons/logout-svg-icon.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
22 |
23 |
--------------------------------------------------------------------------------
/resources/admin-resources/assets/icons/more-svg-icon.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
23 |
24 |
--------------------------------------------------------------------------------
/database/migrations/2023_07_19_141527_create_currencies_table.php:
--------------------------------------------------------------------------------
1 | id();
16 | $table->string('name', 50)->unique();
17 | $table->string('code', 10)->unique();
18 | $table->string('symbol', 10);
19 | $table->timestamps();
20 | });
21 | }
22 |
23 | /**
24 | * Reverse the migrations.
25 | */
26 | public function down(): void
27 | {
28 | Schema::dropIfExists('currencies');
29 | }
30 | };
31 |
--------------------------------------------------------------------------------
/app/Http/Resources/Product/ProductCategoryResource.php:
--------------------------------------------------------------------------------
1 | getMedia('thumbnail')) {
16 | foreach ($this->getMedia('thumbnail') as $m) {
17 | $thumbnail[] = [
18 | 'id' => $m->id,
19 | 'url' => $m->getUrl(),
20 | ];
21 | }
22 | }
23 |
24 | return [
25 | 'id' => $this->id,
26 | 'name' => $this->name,
27 | 'slug' => $this->slug,
28 | 'thumbnail' => $thumbnail,
29 | ];
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/database/migrations/2023_08_05_136533_create_account_adjustments_table.php:
--------------------------------------------------------------------------------
1 | id();
13 | $table->unsignedBigInteger('account_id');
14 | $table->unsignedDouble('amount', 20, 4);
15 | $table->string('type', 20); // add/remove
16 | $table->date('date');
17 | $table->text('note')->nullable();
18 | $table->timestamps();
19 | });
20 | }
21 |
22 | public function down(): void
23 | {
24 | Schema::dropIfExists('account_adjustments');
25 | }
26 | };
27 |
--------------------------------------------------------------------------------
/app/Http/Requests/Product/CreateProductCategoryRequest.php:
--------------------------------------------------------------------------------
1 | ['required', 'string', Rule::unique('product_categories')],
21 | 'slug' => ['required', 'string', Rule::unique('product_categories')],
22 | ];
23 | }
24 |
25 | protected function prepareForValidation(): void
26 | {
27 | $this->merge([
28 | 'slug' => str()->slug($this->slug),
29 | ]);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/database/migrations/2023_07_26_182430_create_warehouses_table.php:
--------------------------------------------------------------------------------
1 | id();
16 | $table->string('name')->unique();
17 | $table->string('email')->unique();
18 | $table->string('phone')->unique();
19 | $table->text('address')->nullable();
20 | $table->timestamps();
21 | });
22 | }
23 |
24 | /**
25 | * Reverse the migrations.
26 | */
27 | public function down(): void
28 | {
29 | Schema::dropIfExists('warehouses');
30 | }
31 | };
32 |
--------------------------------------------------------------------------------
/app/Http/Middleware/RedirectIfAuthenticated.php:
--------------------------------------------------------------------------------
1 | check()) {
24 | return redirect(RouteServiceProvider::HOME);
25 | }
26 | }
27 |
28 | return $next($request);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/resources/admin-resources/assets/icons/customer-svg-icon.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
22 |
23 |
--------------------------------------------------------------------------------
/resources/admin-resources/assets/icons/supplier-svg-icon.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
22 |
23 |
--------------------------------------------------------------------------------
/app/Http/Requests/Unit/CreateUnitRequest.php:
--------------------------------------------------------------------------------
1 | 'required|max:30|unique:units',
21 | 'short_name' => 'required|max:10|unique:units',
22 | 'base_unit_id' => ['nullable', 'numeric', 'required_with_all:operator,operation_value'],
23 | 'operator' => ['nullable', Rule::in(['divide', 'multiply']), 'required_with:base_unit_id'],
24 | 'operation_value' => ['nullable', 'numeric', 'required_with:base_unit_id'],
25 | ];
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/Http/Requests/Warehouse/UpdateWarehouseRequest.php:
--------------------------------------------------------------------------------
1 | route('id');
19 |
20 | return [
21 | 'name' => ['required', 'string', Rule::unique('warehouses')->ignore($warehouse_id)],
22 | 'email' => ['required', 'email', Rule::unique('warehouses')->ignore($warehouse_id)],
23 | 'phone' => ['required', 'string', Rule::unique('warehouses')->ignore($warehouse_id)],
24 | 'address' => ['nullable', 'string'],
25 | ];
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Api/User/UserController.php:
--------------------------------------------------------------------------------
1 | getRoleNames();
16 | $permissions = $user->getAllPermissions();
17 |
18 | return response()->json([
19 | 'id' => $user_id,
20 | 'user' => [
21 | 'id' => $user->id,
22 | 'name' => $user->name,
23 | 'user_name' => $user->user_name,
24 | 'email' => $user->email,
25 | ],
26 | 'roles' => $roles,
27 | 'permissions' => $permissions->pluck('name'),
28 | ]);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app/Http/Requests/Accounting/CreateAdjustmentRequest.php:
--------------------------------------------------------------------------------
1 | ['required'],
20 | 'amount' => ['numeric', 'required'],
21 | 'type' => ['required', 'in:add,subtract'],
22 | 'date' => ['required', 'date'],
23 | 'note' => ['nullable', 'string'],
24 | ];
25 | }
26 |
27 | public function messages()
28 | {
29 | return [
30 | 'account_id.required' => 'The Account field is required',
31 | ];
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/Http/Requests/Accounting/UpdateAdjustmentRequest.php:
--------------------------------------------------------------------------------
1 | ['required'],
20 | 'amount' => ['numeric', 'required'],
21 | 'type' => ['required', 'in:add,subtract'],
22 | 'date' => ['required', 'date'],
23 | 'note' => ['nullable', 'string'],
24 | ];
25 | }
26 |
27 | public function messages()
28 | {
29 | return [
30 | 'account_id.required' => 'The Account field is required',
31 | ];
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/Http/Requests/Brand/UpdateBrandRequest.php:
--------------------------------------------------------------------------------
1 | route('id');
22 |
23 | return [
24 | 'name' => ['required', 'string', Rule::unique('brands')->ignore($brand_id)],
25 | 'slug' => ['required', 'string', Rule::unique('brands')->ignore($brand_id)],
26 | ];
27 | }
28 |
29 | protected function prepareForValidation(): void
30 | {
31 | $this->merge([
32 | 'slug' => str()->slug($this->slug),
33 | ]);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/Models/Payment.php:
--------------------------------------------------------------------------------
1 | belongsTo(Invoice::class, 'invoice_id');
28 | }
29 |
30 | public function party()
31 | {
32 | return $this->belongsTo(Party::class, 'party_id');
33 | }
34 |
35 | public function account()
36 | {
37 | return $this->belongsTo(Account::class, 'account_id');
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/app/Http/Requests/Accounting/CreateAccountRequest.php:
--------------------------------------------------------------------------------
1 | ['required', 'string', Rule::unique('accounts')],
21 | 'bank_name' => ['string', 'required_with:branch_name'],
22 | 'branch_name' => ['string', 'nullable'],
23 | 'account_number' => ['required', 'string'],
24 | 'balance' => ['numeric'],
25 | 'details' => ['nullable', 'string'],
26 | 'status' => ['required', 'in:active,disabled'],
27 | ];
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/resources/admin-resources/stores/authStore.js:
--------------------------------------------------------------------------------
1 | import { defineStore } from "pinia";
2 | import { ref } from "vue";
3 | import axios from "axios";
4 |
5 | export const useAuthStore = defineStore("auth", {
6 | state: () => ({
7 | fetched: false,
8 | user: {},
9 | role: {},
10 | permissions: [],
11 | }),
12 |
13 | getters: {},
14 |
15 | actions: {
16 | async getAuthUser() {
17 | await axios
18 | .get(`/api/users/authenticated-user`)
19 | .then((response) => {
20 | this.user = response.data.user;
21 | this.role = response.data.role;
22 | this.permissions = response.data.permissions;
23 | })
24 | .catch((errors) => {});
25 | },
26 |
27 | userCan(ability) {
28 | return this.permissions.includes(ability);
29 | },
30 | },
31 | });
32 |
--------------------------------------------------------------------------------
/database/migrations/2019_08_19_000000_create_failed_jobs_table.php:
--------------------------------------------------------------------------------
1 | id();
16 | $table->string('uuid')->unique();
17 | $table->text('connection');
18 | $table->text('queue');
19 | $table->longText('payload');
20 | $table->longText('exception');
21 | $table->timestamp('failed_at')->useCurrent();
22 | });
23 | }
24 |
25 | /**
26 | * Reverse the migrations.
27 | */
28 | public function down(): void
29 | {
30 | Schema::dropIfExists('failed_jobs');
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/database/migrations/2023_08_05_136435_create_accounts_table.php:
--------------------------------------------------------------------------------
1 | id();
13 | $table->string('name');
14 | $table->string('bank_name')->nullable();
15 | $table->string('branch_name')->nullable();
16 | $table->string('account_number');
17 | $table->unsignedDouble('balance', 20, 4)->nullable();
18 | $table->text('details')->nullable();
19 | $table->string('status', 20);
20 | $table->timestamps();
21 | });
22 | }
23 |
24 | public function down(): void
25 | {
26 | Schema::dropIfExists('accounts');
27 | }
28 | };
29 |
--------------------------------------------------------------------------------
/app/Http/Requests/Accounting/UpdateAccountRequest.php:
--------------------------------------------------------------------------------
1 | route('id');
19 |
20 | return [
21 | 'name' => ['required', 'string', Rule::unique('accounts')->ignore($account_id)],
22 | 'bank_name' => ['string', 'required_with:branch_name'],
23 | 'branch_name' => ['string', 'nullable'],
24 | 'account_number' => ['required', 'string'],
25 | 'details' => ['nullable', 'string'],
26 | 'status' => ['required', 'in:active,disabled'],
27 | ];
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/resources/admin-resources/components/shared/notification/notications-container.vue:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
14 |
20 |
21 |
22 |
23 |
31 |
--------------------------------------------------------------------------------
/app/Models/Invoice/Invoice.php:
--------------------------------------------------------------------------------
1 | hasMany(InvoiceItem::class);
19 | }
20 |
21 | public function payments()
22 | {
23 | return $this->hasMany(Payment::class);
24 | }
25 |
26 | public function party()
27 | {
28 | return $this->belongsTo(Party::class, 'party_id');
29 | }
30 |
31 | public function warehouse()
32 | {
33 | return $this->belongsTo(Warehouse::class, 'warehouse_id');
34 | }
35 |
36 | public function creator()
37 | {
38 | return $this->belongsTo(User::class, 'created_by');
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/config/cors.php:
--------------------------------------------------------------------------------
1 | ['api/*', 'sanctum/csrf-cookie'],
19 |
20 | 'allowed_methods' => ['*'],
21 |
22 | 'allowed_origins' => ['*'],
23 |
24 | 'allowed_origins_patterns' => [],
25 |
26 | 'allowed_headers' => ['*'],
27 |
28 | 'exposed_headers' => [],
29 |
30 | 'max_age' => 0,
31 |
32 | 'supports_credentials' => false,
33 |
34 | ];
35 |
--------------------------------------------------------------------------------
/database/migrations/2014_10_12_000000_create_users_table.php:
--------------------------------------------------------------------------------
1 | id();
16 | $table->string('name');
17 | $table->string('user_name')->nullable();
18 | $table->string('email')->unique();
19 | $table->timestamp('email_verified_at')->nullable();
20 | $table->string('password');
21 | $table->rememberToken();
22 | $table->timestamps();
23 | });
24 | }
25 |
26 | /**
27 | * Reverse the migrations.
28 | */
29 | public function down(): void
30 | {
31 | Schema::dropIfExists('users');
32 | }
33 | };
34 |
--------------------------------------------------------------------------------
/app/Http/Requests/Product/UpdateProductCategoryRequest.php:
--------------------------------------------------------------------------------
1 | route('id');
22 |
23 | return [
24 | 'name' => ['required', 'string', Rule::unique('product_categories')->ignore($product_cat_id)],
25 | 'slug' => ['required', 'string', Rule::unique('product_categories')->ignore($product_cat_id)],
26 | ];
27 | }
28 |
29 | protected function prepareForValidation(): void
30 | {
31 | $this->merge([
32 | 'slug' => str()->slug($this->slug),
33 | ]);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/database/migrations/2023_07_23_134907_create_units_table.php:
--------------------------------------------------------------------------------
1 | id();
16 | $table->string('name', 30)->unique();
17 | $table->string('short_name', 10)->unique();
18 | $table->unsignedBigInteger('base_unit_id')->nullable();
19 | $table->string('operator', 15)->nullable(); // multiply or divide
20 | $table->unsignedDouble('operation_value')->nullable();
21 | $table->timestamps();
22 | });
23 | }
24 |
25 | /**
26 | * Reverse the migrations.
27 | */
28 | public function down(): void
29 | {
30 | Schema::dropIfExists('units');
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/database/seeders/SuperAdminSeeder.php:
--------------------------------------------------------------------------------
1 | 'super admin',
17 | 'user_name' => 'superadmin',
18 | 'email' => 'superadmin@invextry.com',
19 | 'password' => Hash::make('**invextry**'),
20 | ]);
21 |
22 | // assing this super admin to super-admin role
23 | $super_admin_user->assignRole('super-admin');
24 |
25 | // make super admin logged in
26 | Auth::attempt([
27 | 'email' => 'superadmin@invextry.com',
28 | 'password' => '**invextry**',
29 | ], 100);
30 | }
31 | }
32 |
33 | // email: superadmin@invextry.com
34 | // password: **invextry**
35 |
--------------------------------------------------------------------------------
/resources/admin-resources/assets/icons/sort-svg-icon.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
23 |
24 |
--------------------------------------------------------------------------------
/app/Http/Requests/Unit/UpdateUnitRequest.php:
--------------------------------------------------------------------------------
1 | route('id');
19 |
20 | return [
21 | 'name' => ['required', 'max:30', Rule::unique('units')->ignore($unit_id)],
22 | 'short_name' => ['required', 'max:10', Rule::unique('units')->ignore($unit_id)],
23 | 'base_unit_id' => ['nullable', 'numeric', 'required_with_all:operator,operation_value'],
24 | 'operator' => ['nullable', Rule::in(['divide', 'multiply']), 'required_with:base_unit_id'],
25 | 'operation_value' => ['nullable', 'numeric', 'required_with:base_unit_id'],
26 | ];
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/app/Providers/EventServiceProvider.php:
--------------------------------------------------------------------------------
1 | >
15 | */
16 | protected $listen = [
17 | Registered::class => [
18 | SendEmailVerificationNotification::class,
19 | ],
20 | ];
21 |
22 | /**
23 | * Register any events for your application.
24 | */
25 | public function boot(): void
26 | {
27 | //
28 | }
29 |
30 | /**
31 | * Determine if events and listeners should be automatically discovered.
32 | */
33 | public function shouldDiscoverEvents(): bool
34 | {
35 | return false;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/Http/Resources/Party/CustomerDetailsRerource.php:
--------------------------------------------------------------------------------
1 | $this->id,
14 | 'name' => $this->name,
15 | 'status' => $this->status,
16 | 'phone' => $this->phone,
17 | 'email' => $this->email,
18 | 'address' => $this->address,
19 | 'billing_address' => $this->billing_address,
20 | 'shipping_address' => $this->shipping_address,
21 | 'tax_number' => $this->tax_number,
22 | 'country' => $this->country,
23 | 'city' => $this->city,
24 | 'postal_code' => $this->postal_code,
25 | 'sale_due' => $this->sale_due,
26 | 'sale_return_due' => $this->sale_return_due,
27 | ];
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/app/Http/Resources/Party/SupplierDetailsRerource.php:
--------------------------------------------------------------------------------
1 | $this->id,
14 | 'status' => $this->status,
15 | 'name' => $this->name,
16 | 'phone' => $this->phone,
17 | 'email' => $this->email,
18 | 'address' => $this->address,
19 | 'billing_address' => $this->billing_address,
20 | 'shipping_address' => $this->shipping_address,
21 | 'tax_number' => $this->tax_number,
22 | 'country' => $this->country,
23 | 'city' => $this->city,
24 | 'postal_code' => $this->postal_code,
25 | 'purchase_due' => $this->purchase_due,
26 | 'purchase_return_due' => $this->purchase_return_due,
27 | ];
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/app/Http/Resources/Invoice/SaleListResource.php:
--------------------------------------------------------------------------------
1 | $this->id,
15 | 'invoice_ref' => $this->invoice_ref,
16 | 'invoice_date' => $this->invoice_date,
17 | 'biller' => $this->creator->name,
18 | 'customer' => $this->party->name,
19 | 'warehouse' => $this->warehouse->name,
20 | 'paid_amount' => $this->paid_amount,
21 | 'due_amount' => $this->due_amount,
22 | 'returned_amount' => $this->returned_amount,
23 | 'total_amount' => $this->total_amount,
24 | 'shipping_cost' => $this->shipping_cost,
25 | 'invoice_status' => $this->invoice_status,
26 | 'payment_status' => $this->payment_status,
27 | ];
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php:
--------------------------------------------------------------------------------
1 | id();
16 | $table->morphs('tokenable');
17 | $table->string('name');
18 | $table->string('token', 64)->unique();
19 | $table->text('abilities')->nullable();
20 | $table->timestamp('last_used_at')->nullable();
21 | $table->timestamp('expires_at')->nullable();
22 | $table->timestamps();
23 | });
24 | }
25 |
26 | /**
27 | * Reverse the migrations.
28 | */
29 | public function down(): void
30 | {
31 | Schema::dropIfExists('personal_access_tokens');
32 | }
33 | };
34 |
--------------------------------------------------------------------------------
/app/Http/Resources/Invoice/PurchaseListResource.php:
--------------------------------------------------------------------------------
1 | $this->id,
15 | 'invoice_ref' => $this->invoice_ref,
16 | 'invoice_date' => $this->invoice_date,
17 | 'biller' => $this->creator->name,
18 | 'supplier' => $this->party->name,
19 | 'warehouse' => $this->warehouse->name,
20 | 'paid_amount' => $this->paid_amount,
21 | 'due_amount' => $this->due_amount,
22 | 'returned_amount' => $this->returned_amount,
23 | 'total_amount' => $this->total_amount,
24 | 'shipping_cost' => $this->shipping_cost,
25 | 'invoice_status' => $this->invoice_status,
26 | 'payment_status' => $this->payment_status,
27 | ];
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Api/Payment/PaymentController.php:
--------------------------------------------------------------------------------
1 | paymentService = new PaymentService();
18 | }
19 |
20 | public function store(CreatePaymentRequest $request)
21 | {
22 | try {
23 |
24 | $this->paymentService->createPayment($request->validated());
25 |
26 | } catch (Exception $e) {
27 |
28 | return response()->json([
29 | 'status' => 'error',
30 | 'message' => 'failed to create payment'.$e,
31 | ], 500);
32 | }
33 |
34 | return response()->json([
35 | 'status' => 'success',
36 | 'message' => 'payment created succesfully',
37 | ], 201);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/resources/admin-resources/assets/icons/beg-svg-icon.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
20 |
21 |
--------------------------------------------------------------------------------
/resources/admin-resources/assets/icons/cart-svg-icon.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
20 |
21 |
--------------------------------------------------------------------------------
/config/services.php:
--------------------------------------------------------------------------------
1 | [
18 | 'domain' => env('MAILGUN_DOMAIN'),
19 | 'secret' => env('MAILGUN_SECRET'),
20 | 'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'),
21 | 'scheme' => 'https',
22 | ],
23 |
24 | 'postmark' => [
25 | 'token' => env('POSTMARK_TOKEN'),
26 | ],
27 |
28 | 'ses' => [
29 | 'key' => env('AWS_ACCESS_KEY_ID'),
30 | 'secret' => env('AWS_SECRET_ACCESS_KEY'),
31 | 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
32 | ],
33 |
34 | ];
35 |
--------------------------------------------------------------------------------
/database/factories/UserFactory.php:
--------------------------------------------------------------------------------
1 |
10 | */
11 | class UserFactory extends Factory
12 | {
13 | /**
14 | * Define the model's default state.
15 | *
16 | * @return array
17 | */
18 | public function definition(): array
19 | {
20 | return [
21 | 'name' => fake()->name(),
22 | 'email' => fake()->unique()->safeEmail(),
23 | 'email_verified_at' => now(),
24 | 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
25 | 'remember_token' => Str::random(10),
26 | ];
27 | }
28 |
29 | /**
30 | * Indicate that the model's email address should be unverified.
31 | */
32 | public function unverified(): static
33 | {
34 | return $this->state(fn (array $attributes) => [
35 | 'email_verified_at' => null,
36 | ]);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/database/migrations/2023_08_02_155740_create_product_stocks_table.php:
--------------------------------------------------------------------------------
1 | unsignedBigInteger('product_id');
17 | $table->unsignedBigInteger('warehouse_id');
18 | $table->unsignedDouble('stock_quantity', 20, 4)->nullable();
19 |
20 | $table->foreign('product_id')->references('id')->on('products')
21 | ->cascadeOnUpdate()->restrictOnDelete();
22 | $table->foreign('warehouse_id')->references('id')->on('warehouses')
23 | ->cascadeOnUpdate()->restrictOnDelete();
24 | });
25 | }
26 |
27 | /**
28 | * Reverse the migrations.
29 | */
30 | public function down(): void
31 | {
32 | Schema::dropIfExists('product_stocks');
33 | }
34 | };
35 |
--------------------------------------------------------------------------------
/resources/admin-resources/plugins/axios-settings.js:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 | import { useNotificationStore } from "../components/shared/notification/notificationStore";
3 |
4 | // Add a request interceptor
5 | // axios.interceptors.request.use(
6 | // function (config)
7 | // {
8 |
9 | // //console.log(config.headers);
10 |
11 | // if(config.method == "post"||config.method == "put"||config.method == "delete"){
12 | // const notifcationStore = useNotificationStore()
13 | // notifcationStore.pushNotification({
14 | // 'message':"Demo version doesn't allow to do this",
15 | // 'type' :'error',
16 | // 'time':3000
17 | // })
18 | // throw new axios.Cancel('Operation canceled by the user.');
19 | // }
20 |
21 | // return config;
22 | // },
23 | // function (error) {
24 | // return Promise.reject(error);
25 | // }
26 | // );
27 |
28 | //
29 | axios.defaults.headers.common = {
30 | "X-Requested-With": "XMLHttpRequest",
31 | "X-CSRF-TOKEN": document
32 | .querySelector('meta[name="csrf-token"]')
33 | .getAttribute("content"),
34 | };
35 |
--------------------------------------------------------------------------------
/config/view.php:
--------------------------------------------------------------------------------
1 | [
17 | resource_path('views'),
18 | ],
19 |
20 | /*
21 | |--------------------------------------------------------------------------
22 | | Compiled View Path
23 | |--------------------------------------------------------------------------
24 | |
25 | | This option determines where all the compiled Blade templates will be
26 | | stored for your application. Typically, this is within the storage
27 | | directory. However, as usual, you are free to change this value.
28 | |
29 | */
30 |
31 | 'compiled' => env(
32 | 'VIEW_COMPILED_PATH',
33 | realpath(storage_path('framework/views'))
34 | ),
35 |
36 | ];
37 |
--------------------------------------------------------------------------------
/resources/admin-resources/assets/icons/view-svg-icon.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
22 |
23 |
--------------------------------------------------------------------------------
/app/Http/Requests/Payment/CreatePaymentRequest.php:
--------------------------------------------------------------------------------
1 | ['required'],
27 | 'account_id' => ['required'],
28 | 'payment_method' => ['required'],
29 | 'amount' => ['required', 'numeric'],
30 | 'date' => ['required', 'date'],
31 | 'note' => ['nullable'],
32 | ];
33 | }
34 |
35 | public function messages()
36 | {
37 | return [
38 | 'invoice_id.required' => 'The invoice field is required',
39 | 'account_id.required' => 'The account field is required',
40 | 'payment_method.required' => 'The payment method field is required',
41 | ];
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/resources/admin-resources/components/shared/confirm-alert/confirmStore.js:
--------------------------------------------------------------------------------
1 | import { defineStore } from "pinia";
2 |
3 | export const useConfirmStore = defineStore("confirm", {
4 | state: () => ({
5 | message: "Are you sure to do this action???",
6 | do_action: false,
7 | show_confirm_box: false,
8 | resolve: null,
9 | }),
10 |
11 | getters: {
12 | getActionState: (state) => state.do_action,
13 | },
14 |
15 | actions: {
16 | async confirm_action() {
17 | this.do_action = true;
18 | this.hide_box();
19 | },
20 |
21 | async cancel_action() {
22 | this.do_action = false;
23 | this.hide_box();
24 | },
25 |
26 | hide_box() {
27 | this.resolve();
28 | this.show_confirm_box = false;
29 | },
30 |
31 | async show_box(data = {}) {
32 | this.message = data.message ? data.message : this.message;
33 | this.show_confirm_box = true;
34 | this.do_action = false;
35 | return new Promise((resolve, reject) => {
36 | this.resolve = resolve;
37 | });
38 | },
39 | },
40 | });
41 |
--------------------------------------------------------------------------------
/app/Models/User.php:
--------------------------------------------------------------------------------
1 |
20 | */
21 | protected $fillable = [
22 | 'name',
23 | 'user_name',
24 | 'email',
25 | 'password',
26 | ];
27 |
28 | /**
29 | * The attributes that should be hidden for serialization.
30 | *
31 | * @var array
32 | */
33 | protected $hidden = [
34 | 'password',
35 | 'remember_token',
36 | ];
37 |
38 | /**
39 | * The attributes that should be cast.
40 | *
41 | * @var array
42 | */
43 | protected $casts = [
44 | 'email_verified_at' => 'datetime',
45 | 'password' => 'hashed',
46 | ];
47 | }
48 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 | ./tests/Unit
10 |
11 |
12 | ./tests/Feature
13 |
14 |
15 |
16 |
17 | ./app
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/resources/admin-resources/components/shared/loader/Loader.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
58 |
--------------------------------------------------------------------------------
/app/Providers/RouteServiceProvider.php:
--------------------------------------------------------------------------------
1 | by($request->user()?->id ?: $request->ip());
29 | });
30 |
31 | $this->routes(function () {
32 | Route::middleware('api')
33 | ->prefix('api')
34 | ->group(base_path('routes/api.php'));
35 |
36 | Route::middleware('web')
37 | ->group(base_path('routes/web.php'));
38 | });
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------
1 | APP_NAME=Laravel
2 | APP_ENV=local
3 | APP_KEY=
4 | APP_DEBUG=true
5 | APP_URL=http://localhost
6 |
7 | LOG_CHANNEL=stack
8 | LOG_DEPRECATIONS_CHANNEL=null
9 | LOG_LEVEL=debug
10 |
11 | DB_CONNECTION=mysql
12 | DB_HOST=127.0.0.1
13 | DB_PORT=3306
14 | DB_DATABASE=laravel
15 | DB_USERNAME=root
16 | DB_PASSWORD=
17 |
18 | BROADCAST_DRIVER=log
19 | CACHE_DRIVER=file
20 | FILESYSTEM_DISK=local
21 | QUEUE_CONNECTION=sync
22 | SESSION_DRIVER=file
23 | SESSION_LIFETIME=120
24 |
25 | MEMCACHED_HOST=127.0.0.1
26 |
27 | REDIS_HOST=127.0.0.1
28 | REDIS_PASSWORD=null
29 | REDIS_PORT=6379
30 |
31 | MAIL_MAILER=smtp
32 | MAIL_HOST=mailpit
33 | MAIL_PORT=1025
34 | MAIL_USERNAME=null
35 | MAIL_PASSWORD=null
36 | MAIL_ENCRYPTION=null
37 | MAIL_FROM_ADDRESS="hello@example.com"
38 | MAIL_FROM_NAME="${APP_NAME}"
39 |
40 | AWS_ACCESS_KEY_ID=
41 | AWS_SECRET_ACCESS_KEY=
42 | AWS_DEFAULT_REGION=us-east-1
43 | AWS_BUCKET=
44 | AWS_USE_PATH_STYLE_ENDPOINT=false
45 |
46 | PUSHER_APP_ID=
47 | PUSHER_APP_KEY=
48 | PUSHER_APP_SECRET=
49 | PUSHER_HOST=
50 | PUSHER_PORT=443
51 | PUSHER_SCHEME=https
52 | PUSHER_APP_CLUSTER=mt1
53 |
54 | VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
55 | VITE_PUSHER_HOST="${PUSHER_HOST}"
56 | VITE_PUSHER_PORT="${PUSHER_PORT}"
57 | VITE_PUSHER_SCHEME="${PUSHER_SCHEME}"
58 | VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
59 |
--------------------------------------------------------------------------------
/resources/admin-resources/assets/icons/twentyfour-svg-icon.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
22 |
--------------------------------------------------------------------------------
/app/Http/Requests/Party/CreateCustomerRequest.php:
--------------------------------------------------------------------------------
1 | ['required', 'string', Rule::unique('parties')],
21 | 'phone' => ['required', 'string', Rule::unique('parties')],
22 | 'status' => ['required', 'in:active,disabled'],
23 |
24 | 'email' => ['nullable', 'string', Rule::unique('parties')],
25 | 'tax_number' => ['nullable', 'string', Rule::unique('parties')],
26 |
27 | 'company_name' => ['nullable', 'string'],
28 | 'country' => ['nullable', 'string'],
29 | 'city' => ['nullable', 'string'],
30 | 'postal_code' => ['nullable', 'string'],
31 | 'address' => ['nullable', 'string'],
32 | 'billing_address' => ['nullable', 'string'],
33 | 'shipping_address' => ['nullable', 'string'],
34 |
35 | 'sale_due' => ['nullable', 'numeric'],
36 | 'sale_return_due' => ['nullable', 'numeric'],
37 |
38 | ];
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Api/Dashboard/DashboardController.php:
--------------------------------------------------------------------------------
1 | reportService = $reportService;
15 | }
16 |
17 | public function getDashboardOverview()
18 | {
19 | $this->authorize('view_dashboard_overview');
20 |
21 | return response()->json([
22 | 'total_purchase_amount' => $this->reportService->getTotalPurchaseAmount(),
23 | 'total_purchase_due' => $this->reportService->getTotalPurchaseDueAmount(),
24 | 'total_sale_amount' => $this->reportService->getTotalSaleAmount(),
25 | 'total_sale_due' => $this->reportService->getTotalSaleDueAmount(),
26 |
27 | 'payment_send_current_week' => $this->reportService->getPaymentsSentCurrentWeek(),
28 | 'payment_received_current_week' => $this->reportService->getPaymentsReceivedCurrentWeek(),
29 |
30 | 'top_selling_products' => $this->reportService->getTopSellingProducts(),
31 |
32 | 'current_week_sales' => $this->reportService->getCurrentWeekSales(),
33 | 'current_week_purchases' => $this->reportService->getCurrentWeekPurchases(),
34 | ]);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/Http/Requests/Party/CreateSupplierRequest.php:
--------------------------------------------------------------------------------
1 | ['required', 'string', Rule::unique('parties')],
21 | 'phone' => ['required', 'string', Rule::unique('parties')],
22 | 'status' => ['required', 'in:active,disabled'],
23 |
24 | 'email' => ['nullable', 'string', Rule::unique('parties')],
25 | 'tax_number' => ['nullable', 'string', Rule::unique('parties')],
26 |
27 | 'company_name' => ['nullable', 'string'],
28 | 'country' => ['nullable', 'string'],
29 | 'city' => ['nullable', 'string'],
30 | 'postal_code' => ['nullable', 'string'],
31 | 'address' => ['nullable', 'string'],
32 | 'billing_address' => ['nullable', 'string'],
33 | 'shipping_address' => ['nullable', 'string'],
34 |
35 | 'purchase_due' => ['nullable', 'numeric'],
36 | 'purchase_return_due' => ['nullable', 'numeric'],
37 |
38 | ];
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/License.txt:
--------------------------------------------------------------------------------
1 | Project License:
2 | ===================
3 | MIT License
4 |
5 | Copyright (c) 2023 Invextry: Inventory Management Solution
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy
8 | of this software and associated documentation files (the "Software"), to deal
9 | in the Software without restriction, including without limitation the rights
10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | copies of the Software, and to permit persons to whom the Software is
12 | furnished to do so, subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included in all
15 | copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | SOFTWARE.
24 |
25 |
26 |
27 |
28 |
29 |
30 | Admin Template:
31 | ====================
32 | This project uses Voler Admin Template
33 | Link Of the Admin Template Repo: https://github.com/zuramai/voler
34 | License Link Of this Admin Template: https://github.com/zuramai/voler/blob/main/LICENSE
--------------------------------------------------------------------------------
/resources/admin-resources/assets/icons/user-svg-icon.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
22 |
23 |
--------------------------------------------------------------------------------
/app/Http/Requests/Party/UpdateCustomerRequest.php:
--------------------------------------------------------------------------------
1 | route('id');
19 |
20 | return [
21 |
22 | 'name' => ['required', 'string', Rule::unique('parties')->ignore($customer_id)],
23 | 'phone' => ['required', 'string', Rule::unique('parties')->ignore($customer_id)],
24 | 'status' => ['required', 'in:active,disabled'],
25 |
26 | 'email' => ['nullable', 'string', Rule::unique('parties')->ignore($customer_id)],
27 | 'tax_number' => ['nullable', 'string', Rule::unique('parties')->ignore($customer_id)],
28 |
29 | 'company_name' => ['nullable', 'string'],
30 | 'country' => ['nullable', 'string'],
31 | 'city' => ['nullable', 'string'],
32 | 'postal_code' => ['nullable', 'string'],
33 | 'address' => ['nullable', 'string'],
34 | 'billing_address' => ['nullable', 'string'],
35 | 'shipping_address' => ['nullable', 'string'],
36 |
37 | 'sale_due' => ['nullable', 'numeric'],
38 | 'sale_return_due' => ['nullable', 'numeric'],
39 |
40 | ];
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/app/Http/Requests/Party/UpdateSupplierRequest.php:
--------------------------------------------------------------------------------
1 | route('id');
19 |
20 | return [
21 |
22 | 'name' => ['required', 'string', Rule::unique('parties')->ignore($supplier_id)],
23 | 'phone' => ['required', 'string', Rule::unique('parties')->ignore($supplier_id)],
24 | 'status' => ['required', 'in:active,disabled'],
25 |
26 | 'email' => ['nullable', 'string', Rule::unique('parties')->ignore($supplier_id)],
27 | 'tax_number' => ['nullable', 'string', Rule::unique('parties')->ignore($supplier_id)],
28 |
29 | 'company_name' => ['nullable', 'string'],
30 | 'country' => ['nullable', 'string'],
31 | 'city' => ['nullable', 'string'],
32 | 'postal_code' => ['nullable', 'string'],
33 | 'address' => ['nullable', 'string'],
34 | 'billing_address' => ['nullable', 'string'],
35 | 'shipping_address' => ['nullable', 'string'],
36 |
37 | 'purchase_due' => ['nullable', 'numeric'],
38 | 'purchase_return_due' => ['nullable', 'numeric'],
39 |
40 | ];
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/resources/admin-resources/assets/icons/coin-1-svg-icon.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
20 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Auth/RegisterController.php:
--------------------------------------------------------------------------------
1 | validate([
27 | 'name' => ['required', 'string', 'max:255'],
28 | 'user_name' => ['required', 'string', 'max:25'],
29 | 'email' => ['required', 'email', 'max:255', 'unique:users'],
30 | 'password' => ['required', Password::defaults()],
31 | ]);
32 |
33 | $user = User::create([
34 | 'name' => $request->name,
35 | 'user_name' => $request->user_name,
36 | 'email' => $request->email,
37 | 'password' => Hash::make($request->password),
38 | ]);
39 |
40 | // assing created user to subscriber role
41 | $user->assignRole('subscriber');
42 |
43 | if ($user) {
44 | //return redirect('/login');
45 | return back()->with('registration-success', 'Account Created Successfully');
46 | } else {
47 | return back();
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Auth/LoginController.php:
--------------------------------------------------------------------------------
1 | run();
27 |
28 | $credentials = $request->validate([
29 | 'email' => 'required|email',
30 | 'password' => 'required',
31 | ]);
32 |
33 | if (Auth::attempt($credentials, 100)) {
34 | $request->session()->regenerate();
35 | if (User::find(Auth::id())->can('manage_dashboard')) {
36 |
37 | redirect()->route('admin');
38 | }
39 |
40 | redirect()->route('home');
41 | }
42 |
43 | return back()->with('login-error', 'Incorrect Credentials Provided')->onlyInput('email', 'password');
44 | }
45 |
46 | public function logout(Request $request)
47 | {
48 |
49 | Auth::logout();
50 | $request->session()->invalidate();
51 | $request->session()->regenerateToken();
52 |
53 | return redirect()->route('loginForm');
54 |
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/database/seeders/AccountSeeder.php:
--------------------------------------------------------------------------------
1 | 1,
13 | 'name' => 'General Account',
14 | 'bank_name' => 'HSBC Bank',
15 | 'branch_name' => 'Dhaka Branch',
16 | 'account_number' => '984932489384298',
17 | 'balance' => 0,
18 | 'status' => 'active',
19 | 'details' => 'This Account is used for all general transaction of inventory',
20 | ],
21 | [
22 | 'id' => 2,
23 | 'name' => 'Income Expense Handler Account',
24 | 'bank_name' => 'Asian Bank',
25 | 'branch_name' => 'Chittagong Branch',
26 | 'account_number' => '36493200334294',
27 | 'balance' => 0,
28 | 'status' => 'active',
29 | 'details' => 'This Account is used for all general transaction of inventory',
30 | ],
31 | [
32 | 'id' => 3,
33 | 'name' => "Local Supplier's Paying Account",
34 | 'bank_name' => 'Jamuna Bank',
35 | 'branch_name' => 'Sylet Branch',
36 | 'account_number' => '33458220330244',
37 | 'balance' => 0,
38 | 'status' => 'disabled',
39 | 'details' => '',
40 | ],
41 | ];
42 |
43 | public function run(): void
44 | {
45 | foreach ($this->accounts as $account) {
46 | Account::create($account);
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/app/Services/StockService.php:
--------------------------------------------------------------------------------
1 | where(['product_id' => $product_id, 'warehouse_id' => $warehouse_id])->count() > 0) {
17 | DB::table('product_stocks')->where(['product_id' => $product_id, 'warehouse_id' => $warehouse_id])->increment('stock_quantity', $product_quantity);
18 | DB::table('products')->where('id', $product_id)->increment('stock_quantity', $product_quantity);
19 | } else {
20 | DB::table('product_stocks')->insert(['product_id' => $product_id, 'warehouse_id' => $warehouse_id, 'stock_quantity' => $product_quantity]);
21 | DB::table('products')->where('id', $product_id)->increment('stock_quantity', $product_quantity);
22 | }
23 | }
24 |
25 | public function removeStock($warehouse_id, $product_id, $product_quantity)
26 | {
27 | if (DB::table('product_stocks')->where(['product_id' => $product_id, 'warehouse_id' => $warehouse_id])->sum('stock_quantity') > 0) {
28 | DB::table('product_stocks')->where(['product_id' => $product_id, 'warehouse_id' => $warehouse_id])->decrement('stock_quantity', $product_quantity);
29 | DB::table('products')->where('id', $product_id)->decrement('stock_quantity', $product_quantity);
30 | } else {
31 | new Error('Insufficient Stock Qunatity');
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/resources/admin-resources/assets/icons/dashboard-svg-icon.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
22 |
23 |
--------------------------------------------------------------------------------
/resources/admin-resources/assets/icons/globe-svg-icon.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
23 |
24 |
--------------------------------------------------------------------------------
/app/Http/Resources/Product/ProductListResource.php:
--------------------------------------------------------------------------------
1 | getMedia('gallery')) {
16 | foreach ($this->getMedia('gallery') as $m) {
17 | $gallery[] = [
18 | 'id' => $m->id,
19 | 'url' => $m->getUrl(),
20 | ];
21 | }
22 | }
23 |
24 | return [
25 |
26 | 'id' => $this->id,
27 | // 'code' => $this->code,
28 | 'name' => $this->name,
29 | // 'slug' => $this->slug,
30 | // 'product_type' => $this->product_type,
31 | // 'barcode_symbology' => $this->barcode_symbology,
32 | 'stock_quantity' => $this->stock_quantity,
33 | // 'stock_alert_quantity' => $this->stock_alert_quantity,
34 | 'purchase_price' => $this->purchase_price,
35 | 'sale_price' => $this->sale_price,
36 | // 'parent_id' => $this->parent_id,
37 | 'brand' => $this->brand->name,
38 | 'category' => $this->category->name,
39 | 'unit' => $this->unit->short_name,
40 | // 'purchase_unit' => $this->purchase_unit,
41 | // 'sale_unit' => $this->sale_unit,
42 | // 'tax' => $this->tax,
43 | // 'tax_type' => $this->tax_type,
44 | // 'description' => $this->description,
45 |
46 | 'gallery' => $gallery,
47 | ];
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/resources/admin-resources/assets/icons/setting-svg-icon.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
22 |
23 |
--------------------------------------------------------------------------------
/database/seeders/UnitSeeder.php:
--------------------------------------------------------------------------------
1 | 1, 'name' => 'Kilogram', 'short_name' => 'kg', 'base_unit_id' => null, 'operator' => null, 'operation_value' => null],
12 | ['id' => 2, 'name' => 'Grams', 'short_name' => 'g', 'base_unit_id' => 1, 'operator' => 'divide', 'operation_value' => 1000],
13 | ['id' => 3, 'name' => 'Meter', 'short_name' => 'm', 'base_unit_id' => null, 'operator' => null, 'operation_value' => null],
14 | ['id' => 4, 'name' => 'Centimeter', 'short_name' => 'cm', 'base_unit_id' => 3, 'operator' => 'divide', 'operation_value' => 100],
15 | ['id' => 5, 'name' => 'Liter', 'short_name' => 'l', 'base_unit_id' => null, 'operator' => null, 'operation_value' => null],
16 | ['id' => 6, 'name' => 'Mili Liter', 'short_name' => 'ml', 'base_unit_id' => 5, 'operator' => 'divide', 'operation_value' => 1000],
17 | ['id' => 7, 'name' => 'Piece', 'short_name' => 'pc', 'base_unit_id' => null, 'operator' => null, 'operation_value' => null],
18 | ['id' => 8, 'name' => 'Box', 'short_name' => 'box', 'base_unit_id' => null, 'operator' => null, 'operation_value' => null],
19 | ];
20 |
21 | public function run(): void
22 | {
23 | foreach ($this->units as $unit) {
24 | Unit::create([
25 | 'name' => $unit['name'],
26 | 'short_name' => $unit['short_name'],
27 | 'base_unit_id' => $unit['base_unit_id'],
28 | 'operator' => $unit['operator'],
29 | 'operation_value' => $unit['operation_value'],
30 | ]);
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/config/hashing.php:
--------------------------------------------------------------------------------
1 | 'bcrypt',
19 |
20 | /*
21 | |--------------------------------------------------------------------------
22 | | Bcrypt Options
23 | |--------------------------------------------------------------------------
24 | |
25 | | Here you may specify the configuration options that should be used when
26 | | passwords are hashed using the Bcrypt algorithm. This will allow you
27 | | to control the amount of time it takes to hash the given password.
28 | |
29 | */
30 |
31 | 'bcrypt' => [
32 | 'rounds' => env('BCRYPT_ROUNDS', 10),
33 | ],
34 |
35 | /*
36 | |--------------------------------------------------------------------------
37 | | Argon Options
38 | |--------------------------------------------------------------------------
39 | |
40 | | Here you may specify the configuration options that should be used when
41 | | passwords are hashed using the Argon algorithm. These will allow you
42 | | to control the amount of time it takes to hash the given password.
43 | |
44 | */
45 |
46 | 'argon' => [
47 | 'memory' => 65536,
48 | 'threads' => 1,
49 | 'time' => 4,
50 | ],
51 |
52 | ];
53 |
--------------------------------------------------------------------------------
/database/migrations/2023_08_05_181011_create_invoice_items_table.php:
--------------------------------------------------------------------------------
1 | id();
17 | $table->unsignedBigInteger('invoice_id');
18 | $table->unsignedBigInteger('product_id');
19 |
20 | $table->unsignedDouble('unit_price', 20, 4);
21 | $table->unsignedDouble('product_quantity', 20, 4);
22 | $table->unsignedBigInteger('unit_id')->nullable();
23 | $table->unsignedBigInteger('tax_rate')->nullable();
24 | $table->string('tax_type', 20);
25 | $table->string('discount_type')->nullable(); // flat/percentage
26 | $table->unsignedDouble('discount', 20, 4)->nullable();
27 | //$table->unsignedDouble('item_total', 20, 4)->nullable();
28 |
29 | $table->timestamps();
30 |
31 | $table->foreign('invoice_id')->references('id')->on('invoices')
32 | ->cascadeOnUpdate()->restrictOnDelete();
33 | $table->foreign('product_id')->references('id')->on('products')
34 | ->cascadeOnUpdate()->restrictOnDelete();
35 | $table->foreign('unit_id')->references('id')->on('units')
36 | ->cascadeOnUpdate()->restrictOnDelete();
37 | });
38 | }
39 |
40 | /**
41 | * Reverse the migrations.
42 | */
43 | public function down(): void
44 | {
45 | Schema::dropIfExists('invoice_items');
46 | }
47 | };
48 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Api/Invoice/SaleInvoiceController.php:
--------------------------------------------------------------------------------
1 | saleService = $saleService;
21 | }
22 |
23 | public function store(CreateSaleRequest $request)
24 | {
25 | try {
26 | DB::beginTransaction();
27 | $this->saleService->create($request->input());
28 | DB::commit();
29 |
30 | } catch (Exception $e) {
31 |
32 | DB::rollback();
33 |
34 | return response()->json([
35 | 'status' => 'error',
36 | 'message' => $e,
37 | ], 500);
38 | }
39 |
40 | }
41 |
42 | public function index(Request $request)
43 | {
44 | $this->authorize('view_sale');
45 |
46 | $page = $request->query('page');
47 | $per_page = $request->query('per_page') && $request->query('per_page') < 100 ? $request->query('per_page') : 10;
48 | $search = $request->query('search');
49 |
50 | $sales = Invoice::whereType('sale');
51 |
52 | $sales->when($search, function ($query, $search) {
53 | $query->where('invoice_ref', 'LIKE', '%'.$search.'%');
54 | });
55 |
56 | $sales = $sales->latest()->paginate($per_page);
57 |
58 | return SaleListResource::collection($sales);
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/resources/admin-resources/views/Admin.vue:
--------------------------------------------------------------------------------
1 |
27 |
28 |
29 |
30 |
31 |
32 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/bootstrap/app.php:
--------------------------------------------------------------------------------
1 | singleton(
30 | Illuminate\Contracts\Http\Kernel::class,
31 | App\Http\Kernel::class
32 | );
33 |
34 | $app->singleton(
35 | Illuminate\Contracts\Console\Kernel::class,
36 | App\Console\Kernel::class
37 | );
38 |
39 | $app->singleton(
40 | Illuminate\Contracts\Debug\ExceptionHandler::class,
41 | App\Exceptions\Handler::class
42 | );
43 |
44 | /*
45 | |--------------------------------------------------------------------------
46 | | Return The Application
47 | |--------------------------------------------------------------------------
48 | |
49 | | This script returns the application instance. The instance is given to
50 | | the calling script so we can separate the building of the instances
51 | | from the actual running of the application and sending responses.
52 | |
53 | */
54 |
55 | return $app;
56 |
--------------------------------------------------------------------------------
/database/migrations/2023_08_05_183542_create_payments_table.php:
--------------------------------------------------------------------------------
1 | id();
17 | $table->unsignedBigInteger('party_id');
18 | $table->unsignedBigInteger('account_id')->nullable();
19 | $table->unsignedBigInteger('invoice_id')->nullable();
20 | $table->string('invoice_type', 50)->nullable(); // sales/purchase/sales_return/purchase_return
21 | //$table->unsignedBigInteger('payment_method_id');
22 | $table->string('payment_method', 50);
23 | $table->unsignedDouble('amount', 20, 4);
24 | $table->date('date');
25 | $table->text('note')->nullable();
26 | $table->timestamps();
27 |
28 | $table->foreign('party_id')->references('id')->on('parties')
29 | ->cascadeOnUpdate()->restrictOnDelete();
30 | $table->foreign('account_id')->references('id')->on('accounts')
31 | ->cascadeOnUpdate()->restrictOnDelete();
32 | $table->foreign('invoice_id')->references('id')->on('invoices')
33 | ->cascadeOnUpdate()->restrictOnDelete();
34 | // $table->foreign('payment_method_id')->references('id')->on('payment_methods')
35 | // ->cascadeOnUpdate()->restrictOnDelete();
36 | });
37 | }
38 |
39 | /**
40 | * Reverse the migrations.
41 | */
42 | public function down(): void
43 | {
44 | Schema::dropIfExists('payments');
45 | }
46 | };
47 |
--------------------------------------------------------------------------------
/resources/admin-resources/components/shared/confirm-alert/confirm-box.vue:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 |
13 |
{{ confirmStore.message }}
14 |
26 |
27 |
28 |
29 |
30 |
31 |
61 |
--------------------------------------------------------------------------------
/app/Models/Product/Product.php:
--------------------------------------------------------------------------------
1 | 'single', // variable/digital/single
37 | 'barcode_symbology' => 'CODE128', // CODE128,CODE39,EAN8,EAN13,UPC
38 | 'tax_type' => 'exclusive',
39 | 'stock_quantity' => 0,
40 | ];
41 |
42 | public function category()
43 | {
44 | return $this->belongsTo(ProductCategory::class);
45 | }
46 |
47 | public function brand()
48 | {
49 | return $this->belongsTo(Brand::class, 'brand_id');
50 | }
51 |
52 | public function unit()
53 | {
54 | return $this->belongsTo(Unit::class, 'unit_id');
55 | }
56 |
57 | public function purchase_unit()
58 | {
59 | return $this->belongsTo(Unit::class, 'purchase_unit_id');
60 | }
61 |
62 | public function sale_unit()
63 | {
64 | return $this->belongsTo(Unit::class, 'sale_unit_id');
65 | }
66 |
67 | public function tax()
68 | {
69 | return $this->belongsTo(\App\Models\Setting\Tax::class, 'tax_id');
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/artisan:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | make(Illuminate\Contracts\Console\Kernel::class);
34 |
35 | $status = $kernel->handle(
36 | $input = new Symfony\Component\Console\Input\ArgvInput,
37 | new Symfony\Component\Console\Output\ConsoleOutput
38 | );
39 |
40 | /*
41 | |--------------------------------------------------------------------------
42 | | Shutdown The Application
43 | |--------------------------------------------------------------------------
44 | |
45 | | Once Artisan has finished running, we will fire off the shutdown events
46 | | so that any final work may be done by the application before we shut
47 | | down the process. This is the last thing to happen to the request.
48 | |
49 | */
50 |
51 | $kernel->terminate($input, $status);
52 |
53 | exit($status);
54 |
--------------------------------------------------------------------------------
/public/index.php:
--------------------------------------------------------------------------------
1 | make(Kernel::class);
50 |
51 | $response = $kernel->handle(
52 | $request = Request::capture()
53 | )->send();
54 |
55 | $kernel->terminate($request, $response);
56 |
--------------------------------------------------------------------------------
/database/migrations/2020_10_12_000000_add_variants_to_media.php:
--------------------------------------------------------------------------------
1 | string('variant_name', 255)
21 | ->after('size')
22 | ->nullable();
23 | $table->integer('original_media_id')
24 | ->unsigned()
25 | ->after('variant_name')
26 | ->nullable();
27 |
28 | $table->foreign('original_media_id', 'original_media_id')
29 | ->references('id')->on('media')
30 | ->nullOnDelete();
31 | }
32 | );
33 | }
34 |
35 | /**
36 | * Reverse the migrations.
37 | *
38 | * @return void
39 | */
40 | public function down()
41 | {
42 | Schema::table(
43 | 'media',
44 | function (Blueprint $table) {
45 | if (DB::getDriverName() !== 'sqlite') {
46 | $table->dropForeign('original_media_id');
47 | }
48 | $table->dropColumn('original_media_id');
49 | }
50 | );
51 | Schema::table(
52 | 'media',
53 | function (Blueprint $table) {
54 | $table->dropColumn('variant_name');
55 | }
56 | );
57 | }
58 |
59 | /**
60 | * {@inheritdoc}
61 | */
62 | public function getConnection()
63 | {
64 | return config('mediable.connection_name', parent::getConnection());
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Api/Invoice/PurchaseInvoiceController.php:
--------------------------------------------------------------------------------
1 | purchaseService = $purchaseService;
21 | }
22 |
23 | public function store(CreatePurchaseRequest $request)
24 | {
25 | try {
26 | DB::beginTransaction();
27 | $this->purchaseService->create($request->input());
28 | DB::commit();
29 |
30 | } catch (Exception $e) {
31 |
32 | DB::rollback();
33 |
34 | return response()->json([
35 | 'status' => 'error',
36 | 'message' => $e,
37 | ], 500);
38 | }
39 |
40 | }
41 |
42 | public function index(Request $request)
43 | {
44 | $this->authorize('view_purchase');
45 |
46 | $page = $request->query('page');
47 | $per_page = $request->query('per_page') && $request->query('per_page') < 100 ? $request->query('per_page') : 10;
48 | $search = $request->query('search');
49 |
50 | $purchases = Invoice::where('type', 'purchase');
51 |
52 | $purchases->when($search, function ($query, $search) {
53 | $query->where('invoice_ref', 'LIKE', '%'.$search.'%');
54 | });
55 |
56 | $purchases = $page ? $purchases->orderBy('id', 'desc')->paginate($per_page)
57 | : $purchases->orderBy('id', 'desc')->get();
58 |
59 | return PurchaseListResource::collection($purchases);
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/app/Http/Resources/Product/SingleProductResource.php:
--------------------------------------------------------------------------------
1 | getMedia('gallery')) {
16 | foreach ($this->getMedia('gallery') as $m) {
17 | $gallery[] = [
18 | 'id' => $m->id,
19 | 'url' => $m->getUrl(),
20 | ];
21 | }
22 | }
23 |
24 | return [
25 |
26 | 'id' => $this->id,
27 | 'code' => $this->code,
28 | 'name' => $this->name,
29 | 'slug' => $this->slug,
30 | 'product_type' => $this->product_type,
31 | 'barcode_symbology' => $this->barcode_symbology,
32 | 'stock_alert_quantity' => $this->stock_alert_quantity,
33 | 'stock_quantity' => $this->stock_quantity,
34 | 'purchase_price' => $this->purchase_price,
35 | 'sale_price' => $this->sale_price,
36 | 'parent_id' => $this->parent_id,
37 | 'brand_id' => $this->brand_id,
38 | 'brand' => $this->brand,
39 | 'category_id' => $this->category_id,
40 | 'category' => $this->category,
41 | 'unit_id' => $this->unit_id,
42 | 'unit' => $this->unit,
43 | 'purchase_unit_id' => $this->purchase_unit_id,
44 | 'purchase_unit' => $this->purchase_unit,
45 | 'sale_unit_id' => $this->sale_unit_id,
46 | 'sale_unit' => $this->sale_unit,
47 | 'tax_id' => $this->tax_id,
48 | 'tax' => $this->tax,
49 | 'tax_type' => $this->tax_type,
50 | 'description' => $this->description,
51 |
52 | 'gallery' => $gallery,
53 | ];
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/resources/admin-resources/components/shared/notification/notification.vue:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
29 |
30 |
31 |
32 |
33 |
{{ data.message }}
34 |
35 |
36 |
37 |
66 |
--------------------------------------------------------------------------------
/database/migrations/2023_08_05_135214_create_parties_table.php:
--------------------------------------------------------------------------------
1 | id();
17 | $table->unsignedBigInteger('user_id')->nullable();
18 |
19 | $table->string('name');
20 | $table->string('phone')->unique();
21 | $table->string('email')->unique()->nullable();
22 |
23 | $table->string('company_name')->nullable();
24 | $table->string('tax_number')->unique()->nullable();
25 |
26 | $table->string('country', 50)->nullable();
27 | $table->string('city', 50)->nullable();
28 | $table->string('postal_code', 50)->nullable();
29 | $table->text('address')->nullable();
30 | $table->text('billing_address')->nullable();
31 | $table->text('shipping_address')->nullable();
32 |
33 | $table->string('status', 20);
34 | $table->boolean('isCustomer')->nullable();
35 | $table->boolean('isSupplier')->nullable();
36 |
37 | $table->unsignedDouble('purchase_due', 20, 4)->nullable();
38 | $table->unsignedDouble('purchase_return_due', 20, 4)->nullable();
39 | $table->unsignedDouble('sale_due', 20, 4)->nullable();
40 | $table->unsignedDouble('sale_return_due', 20, 4)->nullable();
41 |
42 | $table->timestamps();
43 |
44 | $table->foreign('user_id')->references('id')->on('users')->cascadeOnUpdate()->restrictOnDelete();
45 | });
46 | }
47 |
48 | /**
49 | * Reverse the migrations.
50 | */
51 | public function down(): void
52 | {
53 | Schema::dropIfExists('parties');
54 | }
55 | };
56 |
--------------------------------------------------------------------------------
/database/seeders/BrandSeeder.php:
--------------------------------------------------------------------------------
1 | 1, 'name' => 'walton', 'slug' => 'walton', 'logo' => 1],
12 | ['id' => 2, 'name' => 'bata', 'slug' => 'bata', 'logo' => 2],
13 | ['id' => 3, 'name' => 'pran', 'slug' => 'pran', 'logo' => 3],
14 | ['id' => 4, 'name' => 'regal', 'slug' => 'regal', 'logo' => 4],
15 | ['id' => 5, 'name' => 'arong', 'slug' => 'arong', 'logo' => 5],
16 | ['id' => 6, 'name' => 'philip', 'slug' => 'philip', 'logo' => 6],
17 | ['id' => 7, 'name' => 'mi', 'slug' => 'mi', 'logo' => 7],
18 | ['id' => 8, 'name' => 'panda', 'slug' => 'panda', 'logo' => 8],
19 | ['id' => 9, 'name' => 'samsung', 'slug' => 'samsung', 'logo' => 9],
20 | ['id' => 10, 'name' => 'vision', 'slug' => 'vision', 'logo' => 10],
21 | ['id' => 11, 'name' => 'hp', 'slug' => 'hp', 'logo' => 11],
22 | ['id' => 12, 'name' => 'fresh', 'slug' => 'fresh', 'logo' => 12],
23 | ['id' => 13, 'name' => 'nido', 'slug' => 'nido', 'logo' => 13],
24 | ['id' => 14, 'name' => 'pepsodent', 'slug' => 'pepsodent', 'logo' => 14],
25 | ['id' => 15, 'name' => 'rfl', 'slug' => 'rfl', 'logo' => 15],
26 | ['id' => 16, 'name' => 'dell', 'slug' => 'dell', 'logo' => 16],
27 | ['id' => 17, 'name' => 'asus', 'slug' => 'asus', 'logo' => 17],
28 | ['id' => 18, 'name' => 'dano', 'slug' => 'dano', 'logo' => 18],
29 | ['id' => 19, 'name' => 'casio', 'slug' => 'casio', 'logo' => 19],
30 | ['id' => 20, 'name' => 'yamah', 'slug' => 'yamah', 'logo' => 20],
31 | ];
32 |
33 | public function run(): void
34 | {
35 | foreach ($this->brands as $brand) {
36 | Brand::create([
37 | 'name' => $brand['name'],
38 | 'slug' => $brand['slug'],
39 | ])->attachMedia($brand['logo'], 'logo');
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/app/Http/Requests/Product/CreateProductRequest.php:
--------------------------------------------------------------------------------
1 | ['required', 'string', Rule::unique('products')],
22 | 'name' => ['required', 'string', Rule::unique('products')],
23 | 'slug' => ['required', 'string', Rule::unique('products')],
24 |
25 | 'product_type' => ['required', 'string', Rule::in(['single', 'variable', 'digital'])],
26 | 'barcode_symbology' => ['required', 'string', Rule::in(['CODE128', 'CODE39', 'EAN8', 'EAN13', 'UPC'])],
27 |
28 | 'stock_alert_quantity' => ['nullable', 'numeric'],
29 | 'purchase_price' => ['required', 'numeric'],
30 | 'sale_price' => ['required', 'numeric'],
31 |
32 | 'parent_id' => ['nullable', 'numeric'],
33 |
34 | 'brand_id' => ['nullable', 'numeric'],
35 |
36 | 'category_id' => ['required', 'numeric'],
37 |
38 | 'unit_id' => ['required', 'numeric'],
39 | // 'purchase_unit_id' => ['required', 'numeric'],
40 | // 'sale_unit_id' => ['required', 'numeric'],
41 |
42 | 'tax_id' => ['nullable', 'numeric'],
43 | 'tax_type' => ['required', 'string', Rule::in(['inclusive', 'exclusive'])],
44 |
45 | 'description' => ['nullable', 'string'],
46 |
47 | ];
48 | }
49 |
50 | protected function prepareForValidation(): void
51 | {
52 | $this->merge([
53 | 'slug' => str()->slug($this->slug),
54 | // temporary configuration till our system is just for single type product
55 | 'product_type' => 'single',
56 | 'parent_id' => null,
57 | ]);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/resources/admin-resources/assets/icons/hand-love-svg-icon.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
22 |
--------------------------------------------------------------------------------
/app/Http/Requests/Product/UpdateProductRequest.php:
--------------------------------------------------------------------------------
1 | route('id');
19 |
20 | return [
21 |
22 | 'code' => ['required', 'string', Rule::unique('products')->ignore($product_id)],
23 | 'name' => ['required', 'string', Rule::unique('products')->ignore($product_id)],
24 | 'slug' => ['required', 'string', Rule::unique('products')->ignore($product_id)],
25 |
26 | 'barcode_symbology' => ['required', 'string', Rule::in(['CODE128', 'CODE39', 'EAN8', 'EAN13', 'UPC'])],
27 |
28 | 'stock_alert_quantity' => ['nullable', 'numeric'],
29 | 'purchase_price' => ['required', 'numeric'],
30 | 'sale_price' => ['required', 'numeric'],
31 |
32 | 'brand_id' => ['nullable', 'numeric'],
33 |
34 | 'category_id' => ['required', 'numeric'],
35 |
36 | 'unit_id' => ['required', 'numeric'],
37 | // 'purchase_unit_id' => ['required', 'numeric'],
38 | // 'sale_unit_id' => ['required', 'numeric'],
39 |
40 | 'tax_id' => ['nullable', 'numeric'],
41 | 'tax_type' => ['required', 'string', Rule::in(['inclusive', 'exclusive'])],
42 |
43 | 'description' => ['nullable', 'string'],
44 |
45 | ];
46 | }
47 |
48 | protected function prepareForValidation(): void
49 | {
50 | // remove product_type and parent_id so that user can not update product type and
51 | // parent of a product variation. This will help to preserve consistancy of records
52 | $this->offsetUnset('product_type');
53 | $this->offsetUnset('parent_id');
54 |
55 | $this->merge([
56 | 'slug' => str()->slug($this->slug),
57 | ]);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Api/Upload/UploadController.php:
--------------------------------------------------------------------------------
1 | authorize('upload_file');
16 | try {
17 | $files = $request->file('files');
18 | $uploadedFiles = [];
19 |
20 | foreach ($files as $file) {
21 | $uploaded_media = MediaUploader::fromSource($file)
22 | ->setAllowedMimeTypes(['image/webp', 'image/png', 'image/jpg', 'image/jpeg'])
23 | ->setAllowedExtensions(['jpg', 'jpeg', 'png', 'webp'])
24 | ->toDestination('uploads', date('Y-m-d'))
25 | ->upload();
26 |
27 | $uploadedFiles[] = [
28 | 'id' => $uploaded_media->id,
29 | 'url' => $uploaded_media->getUrl(),
30 | ];
31 | }
32 | } catch (Exception $e) {
33 | return response()->json([
34 | 'status' => 'failed',
35 | 'message' => 'media upload failed'.$e->getMessage(),
36 | ], 500);
37 | }
38 |
39 | return response()->json([
40 | 'status' => 'success',
41 | 'message' => 'media uploaded successfully',
42 | 'files' => $uploadedFiles,
43 | ], 200);
44 | }
45 |
46 | public function delete($id)
47 | {
48 | $this->authorize('delete_file');
49 | try {
50 | $id = explode(',', $id);
51 | media::destroy($id);
52 | } catch (Exception $e) {
53 | return response()->json([
54 | 'status' => 'failed',
55 | 'message' => 'failed to delete media',
56 |
57 | ], 500);
58 | }
59 |
60 | return response()->json([
61 | 'status' => 'success',
62 | 'message' => 'media deleted successfully',
63 | ], 200);
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/database/seeders/ProductCategorySeeder.php:
--------------------------------------------------------------------------------
1 | 1, 'name' => 'beg', 'slug' => 'beg', 'category_img' => 21],
12 | ['id' => 2, 'name' => 'camera', 'slug' => 'camera', 'category_img' => 22],
13 | ['id' => 3, 'name' => 'chocolate', 'slug' => 'chocolate', 'category_img' => 23],
14 | ['id' => 4, 'name' => 'drinks', 'slug' => 'drinks', 'category_img' => 24],
15 | ['id' => 5, 'name' => 'fruits', 'slug' => 'fruits', 'category_img' => 25],
16 | ['id' => 6, 'name' => 'furniture', 'slug' => 'furniture', 'category_img' => 26],
17 | ['id' => 7, 'name' => 'glass', 'slug' => 'glass', 'category_img' => 27],
18 | ['id' => 8, 'name' => 'headphone', 'slug' => 'headphone', 'category_img' => 28],
19 | ['id' => 9, 'name' => 'laptop', 'slug' => 'laptop', 'category_img' => 29],
20 | ['id' => 10, 'name' => 'milk powder', 'slug' => 'milk-powder', 'category_img' => 30],
21 | ['id' => 11, 'name' => 'oil', 'slug' => 'oil', 'category_img' => 31],
22 | ['id' => 12, 'name' => 'shoe', 'slug' => 'shoe', 'category_img' => 32],
23 | ['id' => 13, 'name' => 'smart phone', 'slug' => 'smart-phone', 'category_img' => 33],
24 | ['id' => 14, 'name' => 't shirt', 'slug' => 't-shirt', 'category_img' => 34],
25 | ['id' => 15, 'name' => 'tablet', 'slug' => 'tablet', 'category_img' => 35],
26 | ['id' => 16, 'name' => 'toy', 'slug' => 'toy', 'category_img' => 36],
27 | ['id' => 17, 'name' => 'tv', 'slug' => 'tv', 'category_img' => 37],
28 | ['id' => 18, 'name' => 'watch', 'slug' => 'watch', 'category_img' => 38],
29 |
30 | ];
31 |
32 | public function run(): void
33 | {
34 | foreach ($this->product_cats as $product_cat) {
35 | ProductCategory::create([
36 | 'name' => $product_cat['name'],
37 | 'slug' => $product_cat['slug'],
38 | ])->attachMedia($product_cat['category_img'], 'thumbnail');
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------