Resoloved conflicts

This commit is contained in:
jitendra 2019-10-09 17:12:57 +05:30
commit 5e754cbdfe
148 changed files with 4995 additions and 1706 deletions

View File

@ -1,6 +1,6 @@
APP_NAME=Bagisto
APP_ENV=local
APP_VERSION=0.1.6
APP_VERSION=0.1.8
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost

View File

@ -1,12 +1,17 @@
---
name: "🐛 Bug Report"
about: 'Report a general library issue.'
---
# Bug report
### Title
**Title is a vital part of bug report for developer and triager to quickly identify a unique issue.**
**Just a quick sentence to brief your trouble with Bagisto or something associated with it.**
A well written title should contain a clear, brief explanation of the issue, making emphasis on the most important points.
Please be calm, short and emaphasize on points.
### Issue Description
**Bug description helps the developer to understand the bug.It describes the problem encountered.**
**Description helps the developers to understand the bug. It describes the problem encountered or some after effect of some kind.**
### Preconditions
**Please provide as detailed information about your environment as possible.**

View File

@ -0,0 +1,12 @@
---
name: "💡 Feature Request"
about: 'For ideas or feature requests, please make a pull request, or open an issue'
---
This repository is only for reporting bugs or issues. If you need support, please use the forums:
- https://forums.bagisto.com/
Alternatively, you may use Facebook (https://www.facebook.com/groups/bagisto/).
We promise that more channels are coming soon!!!

View File

@ -0,0 +1,15 @@
---
name: "🧐 Support Question"
about: 'This repository is only for reporting bugs or problems. If you need help, see:
https://github.com/bagisto/bagisto#documentation'
---
This repository is only for reporting bugs or issues. If you need support, please use:
1. Write an email - mailto:support@bagisto.com
2. Create support ticket on https://bagisto.uvdesk.com
3. Visit forums to get support from our community (https://forums.bagisto.com)
Thanks!

View File

@ -0,0 +1,9 @@
---
name: "🔒 Security Vulnerabilities"
about: 'For reporting security-related issues, see: https://github.com/bagito/bagisto#security-vulnerabilities'
---
PLEASE DON'T DISCLOSE SECURITY-RELATED ISSUES PUBLICLY, SEE BELOW.
If you have security vulnerability to address related to Bagisto then please write a mail to us:
**support@bagisto.com**

13
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,13 @@
**BUGS:**
Please describe the issue that you solved if its not filed. Otherwise please mention issue #id and use comma
if your PR is having multiple fixes.
**Core development ideas or discussion:**
Describe the feature in very short lines word usage limit is 200. Otherwise use **issue #id** if the issue was
filed as **feature** request.
**Which branch you should target?**
You should fork the Bagisto repository and push your local changes to your own **development** branch. And after you are done then generate from your **development** branch to Bagisto's **master** branch. Use branches other than **master** if you are fixing any backward compatible issue.

View File

@ -2,6 +2,144 @@
#### This changelog consists the bug & security fixes and new features being included in the releases listed below.
## **v0.1.8 (4th of October, 2019)** - *Release*
* [feature] - Refund is added for orders.
* #1338 [fixed] - Fixed the complete header ,header should not scroll on scrolling the page.
* #1442 [fixed] - Customer should get an email after registration.
* #1490 [fixed] - Getting Incorrect paid amount and due amount if order contains more than one product.
* #1492 [fixed] - Not showing orderid with prefix and suffix in Refund section.
* #1504 [fixed] - Getting Exception when applying filter in Invoices grid through Invoice Date.
* #1489 [fixed] - Quantity of Product doesn't get updated after creating a refund.
* #1486 [fixed] - Getting incorrect Total Due Amount if discount is applied.
* #1484 [fixed] - Unable to edit data of Refund Shipping field.
* #1483 [fixed] - Refund option should not be available if refund is already created.
* #1461 [fixed] - Invoice number length should be number of zeros that appears before invoice id.
* #1447 [fixed] - Order ID is not matching after printing invoice.
* #1460 [fixed] - Getting error on deleting Newsletter.
* #1172 [fixed] - Default shipping and payment should be selected, currently no shipping method and payment method is selected by default.
## **v0.1.7 (17th of September, 2019)** - *Release*
* [feature] - Fiterable attributes according to category.
* [feature] - New module CMS added for adding static pages.
* [feature] - Dyanamic event firing in datagrid while adding columns, actions and mass actions as well.
* [enhancement] - Customer gets an email after registration.
* [enhancement] - Customer receives cancellation mail if his/her order is cancelled by admin.
* [enhancement] - SEO is now available for home page.
* [enhancement] - If account is created for customer by admin then customer should received an email that his/her account is created with create password link.
* [enhancement] - product_flat will is now scalable according to choice of attributes to be used in it.
* #1258 [fixed] - If payment is done through paypal then invoice should generate automatically and status of Order should be processing.
* #1320 [fixed] - Catalog rule is not working according to selected attributes, if category is not selected.
* #1260 [fixed] - Getting broken image link in email.
* #1434 [fixed] - Incorrect discount amount in case of multicurrency.
* #1288 [fixed] - Getting exception while creating cart rules if any of the dropdown field left blank.
* #1381 [fixed] - Filter is not working properly for action type column in cart rule.
* #1348 [fixed] - Showing incorrect grandtotal in invoice section of admin, if order is placed in currency other than base currency.
* #1259 [fixed] - Getting exception if using same sku for variants..
* #1380 [fixed] - Getting error after refreshing the page.
* #1256 [fixed] - Discounted amount is not displaying in invoice and invoice pdf at both customer end and admin end.
* #1411 [fixed] - Getting exception on updating cart rule.
* #1284 [fixed] - Updated price for variant is not reflected on store.
* #1286 [fixed] - Incorrect discount is showing in cart.
* #1382 [fixed] - In case of "Adjust whole cart to percent" discount amount is getting calculated according to price of one product.
* #1415 [fixed] - Wrong discount applies if Action "Adjust whole cart to percent" is selected.
* #1417 [fixed] - Discount amount is showing in "Quantity" column.
* #973 [fixed] - Edit Slider, get wrong with: An invalid form control with name='image[image_0]' is not focusable.
* #1263 [fixed] - For forgot password Submit button should get disabled if user has already clicked on submit button.
* #1379 [fixed] - Cart rule not working in case of non-coupon if any condition is given.
* #1239 [fixed] - Filterable attributes should not display in layered navigation if there are no product in that particular category.
* #1351 [fixed] - Getting exception when assigning the root category to another category.
* #1372 [fixed] - Getting exception if while updating cart rule , if any option is selected from "How to Choose Products?".
* #1375 [fixed] - Wrong discount applied on cart in case of fixed discount.
* #1226 [fixed] - Product variation that has been ordered should display in customer order section in case of configurable product.
* #1391 [fixed] - By default attribute condition gets saved as 1 in db, because of which cart rule not getting applied.
* #1277 [fixed] - Getting exception on creating cart rules.
* #1334 [fixed] - On editing catalog rule data gets removed from Discount Amount field.
* #778 [fixed] - Error when add item to cart.
* #1253 [fixed] - Selected Channel for products get deselected after saving the product.
* #1319 [fixed] - Getting exception when click on Apply rules if conditions are left empty while creating catalog rule.
* #1295 [fixed] - Getting exception on changing the locale from cms page.
* #1233 [fixed] - Got exception on front-end when first time changes the locale ,the changed locale have rtl direction.
* #1235 [fixed] - Attributes are not visible in category page to select as filterable attribute if attributes name are not provided in particular locales.
* #1177 [fixed] - Getting exception when trying to recover password.
* #1228 [fixed] - Getting issue when entering direct url for customer account profile.
* #1229 [fixed] - Issue with currency in customer order section, currency code doesn't get converted at orders page of customer.
* #1234 [fixed] - After selecting direction to filter locale acc to direction no other field appears to select format.
* #1015 [fixed] - Adjust Paginator Number of Elements.
* #968 [fixed] - sorting is not working (price).
* #1190 [fixed] - After printing invoice at customer end, price is not getting change according to currency in invoice.
* #1209 [fixed] - There is an image issue while ordering any variant of configurable product.
* #1217 [fixed] - Layered navigation for price is not working, when click on bar it shifts to rightmost end.Getting this issue in case of configurable product only.
* #1216 [fixed] - Price filter of layered navigation not working properly in case of Multi Currency.
* #1130 [fixed] - If "does not contain" is used in case of Shipping method, then discount amount get implemented before selecting any shipping method.
* #1129 [fixed] - Discount not getting applied if "does not contain" condition is used from Actions for Payment Methods.
## **v0.1.6(28th of June, 2019)** - *Release*
* [feature] - Cart rules for providing discount with coupons and without coupons.

61
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,61 @@
# Bagisto Contribution Guide
**BUGS:**
To encourage active collaboration, Bagisto encourages pull requests, not just bug reports. "Bug reports" may also be sent in the form of a pull request containing negative test.
However, when filing a bug report, your issue should contain a title and a clear description of the issue. You should also include as much relevant information as possible and a code sample that demonstrates the issue. The goal of a bug report is to make it easy for yourself - and others - to replicate the bug and develop a fix.
Remember, bug reports are created in the hope that others with the same problem will be able to collaborate with you on solving it. Creating a bug report serves to help yourself and others start on the path of fixing the problem.
**Projects that you can contribute in:**
1. Bagisto
2. Bagisto docs
3. Laravel-aliexpress-dropship
4. Laravel-aliexpress-dropship-chrome-extension
5. Bagisto-custom-style-extension
**Core development ideas or discussion:**
If you propose a new feature, please be willing to implement at least some of the code that would be needed to complete the feature.
Informal discussion regarding bugs, new features, and implementation of existing features takes place in the comments of the issues filed using feature template.
**Which branch you should target?**
All bug fixes should be sent to the latest staging branch i.e development branch. Bug fixes should never be sent to the master branch unless they fix features that exist only in the upcoming release.
Minor features that are fully backwards compatible with the current Laravel release may be sent to the latest stable branch.
Major new features should always be sent to the master branch, which contains the upcoming Bagisto release.
**Compiling assets:**
If you are submitting a change that will affect a compiled file, such as most of the files in admin/resources/assets/sass or admin/resources/assets/js of the Bagisto repository, do not commit the compiled files. Due to their large size, they cannot realistically be reviewed by a maintainer. This could be exploited as a way to inject malicious code into Bagisto. In order to defensively prevent this, all compiled files will be generated and committed by Bagisto maintainers.
**Code style:**
Bagisto follow PSR-2 for coding standard and PSR-4 as of Laravel for autoloading standards.
**PHPDoc:**
Below is an example of a valid Bagisto doc block. Note that the @param attribute is followed by two spaces, the argument type, two more spaces, and finally the variable name:
/**
* Register a service with CoreServiceProvider.
*
* @param string|array $loader
* @param \Closure|string|null $concrete
* @param bool $shared
* @return void
* @throws \Exception
*/
protected function registerFacades($loader, $concrete = null, $shared = false)
{
//
}

View File

@ -1,66 +0,0 @@
<html>
<head>
<title>Feature</title>
<style>
.bagisto
{
color: blue;
}
</style>
</head>
<body>
<div>
<h3>Title</h3>
<hr>
<p class="bagisto">
A well written title should contain a clear, brief explanation of the Feature, making emphasis on the most important points.
</p>
</div>
<div>
<h3>Preconditions</h3>
<hr>
<p class="bagisto">Please provide as detailed information about your environment as possible.</p>
<ul>
<li> framework Version:</li>
<li>Commit id:</li>
</ul>
</div>
<div>
<h3>Description</h3>
<hr>
<p class="bagisto">Description helps the developer to understand the Feature.
</p>
</div>
<div>
<h3>Steps to reproduce</h3>
<hr>
<p class="bagisto">It is important to provide a set of clear steps to that location where feature need to be added. If relevant please include code samples.</p>
<ol>
<li> step1</li>
<li> step2</li>
</ol>
</div>

View File

@ -16,7 +16,8 @@
3. [Requirements](#requirements)
4. [Installation & Configuration](#installation-and-configuration)
5. [License](#license)
6. [Miscellaneous](#miscellaneous)
6. [Security Vulnerabilities](#security-vulnerabilities)
7. [Miscellaneous](#miscellaneous)
### Introduction
@ -176,6 +177,8 @@ password:admin123
### License
Bagisto is a truly opensource E-Commerce framework which will always be free under the [MIT License](https://github.com/bagisto/bagisto/blob/master/LICENSE).
### Security Vulnerabilities
Please don't disclose security vulnerabilities publicly. If you find any security vulnerability in Bagisto then please write us mail: mailto:support@bagisto.com.
### Miscellaneous

View File

@ -1,48 +0,0 @@
<html>
<head>
<title>Support</title>
<style>
.bagisto
{
color: blue;
}
</style>
</head>
<body>
<div>
<h3>Title</h3>
<hr>
<p class="bagisto">
Title is a vital part of bug report for developer and triager to quickly identify a unique issue.
<br>
A well written title should contain a clear, brief explanation of the issue, making emphasis on the most important points.
</p>
</div>
<div>
<h3>Preconditions</h3>
<hr>
<p class="bagisto">Please provide as detailed information about your environment as possible.</p>
<ul>
<li> framework Version:</li>
<li>Commit id:</li>
</ul>
</div>
<div>
<h3>Description</h3>
<hr>
<p class="bagisto">Description helps the developer to understand the exact scenario.It describes the problem encountered.</p>
</div>
<div>
<h3>Steps to reproduce</h3>
<hr>
<p class="bagisto">It is important to provide a set of clear steps to reproduce that scenario. If relevant please include code samples.</p>
<ol>
<li> step1</li>
<li> step2</li>
</ol>
</div>

View File

@ -1,181 +0,0 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class BagistoInstall extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'bagisto:install';
/**
* The console command description.
*
* @var string
*/
protected $description = 'This command will try to configure and install new Bagisto instance';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$path = base_path('.env');
$uname = strtolower(\php_uname());
if (str_contains($uname, 'win'))
shell_exec('copy .env.example .env');
else
shell_exec('cp .env.example .env');
$this->line('Hello and welcome to Bagisto command line installer.');
$APP_NAME = $this->ask('[KEY = "APP_NAME"] Please enter name of application instance?');
$this->comment($APP_NAME ?? 'Bagisto');
$this->changeEnvironmentVariable('APP_NAME', $APP_NAME);
$APP_ENV = $this->choice('[KEY = "APP_ENV"] Choose environment for this instance of Bagisto?', ['development', 'production'], 0);
$this->comment($APP_ENV);
$this->changeEnvironmentVariable('APP_ENV', $APP_ENV);
// $APP_DEBUG = $this->ask('Choose APP_DEBUG?', ['true', 'false'], 0);
// $this->comment($APP_DEBUG);
// $this->changeEnvironmentVariable('APP_DEBUG', $APP_DEBUG);
$APP_URL = $this->ask('[KEY = "APP_URL"] Please enter application URL (Optional, default = localhost)?');
$this->comment($APP_URL ?? 'localhost');
$this->changeEnvironmentVariable('APP_URL', $APP_URL);
$DB_CONNECTION = $this->ask('[KEY = "DB_CONNECTION"] Enter database connection (Optional, default = mysql)?');
$this->comment($DB_CONNECTION ?? 'mysql');
$this->changeEnvironmentVariable('DB_CONNECTION', $DB_CONNECTION);
$DB_HOST = $this->ask('[KEY = "DB_HOST"] Enter database host (Optional, default = 127.0.0.1)?');
$this->comment($DB_HOST ?? '127.0.0.1');
$this->changeEnvironmentVariable('DB_HOST', $DB_HOST);
$DB_PORT = $this->ask('[KEY = "DB_PORT"] Enter database port (Optional, default = 3306)?');
$this->comment($DB_PORT ?? '3306');
$this->changeEnvironmentVariable('DB_PORT', $DB_PORT);
$DB_DATABASE = null;
while(! isset($DB_DATABASE)) {
$DB_DATABASE = $this->ask('[KEY = "DB_DATABASE"] Enter name of database?');
$this->comment($DB_DATABASE ?? 'forge');
}
$this->changeEnvironmentVariable('DB_DATABASE', $DB_DATABASE);
$DB_USERNAME = null;
while(! isset($DB_USERNAME)) {
$DB_USERNAME = $this->ask('Enter database username?');
$this->comment($DB_USERNAME ?? 'root');
}
$this->changeEnvironmentVariable('[KEY = "DB_USERNAME"] DB_USERNAME', $DB_USERNAME);
$DB_PASSWORD = $this->ask('Please enter database password?');
$this->comment($DB_PASSWORD);
$this->changeEnvironmentVariable('[KEY = "DB_PASSWORD"] DB_PASSWORD', $DB_PASSWORD);
$this->info('We are done with application and database params, good job!');
$this->info('Do you want me to be mail ready, i am loaded with notifications!');
$MAIL_DRIVER = $this->ask('[KEY = "MAIL_DRIVER"] Enter MAIL_DRIVER (Optional, default = smtp)?');
$this->comment($MAIL_DRIVER ?? 'smtp');
$this->changeEnvironmentVariable('MAIL_DRIVER', $MAIL_DRIVER ?? 'smtp');
$MAIL_HOST = $this->ask('[KEY = "MAIL_HOST"] Enter MAIL_HOST (Optional, default = smtp.mailtrap.io)?');
$this->comment($MAIL_HOST ?? 'smtp.mailtrap.io');
$this->changeEnvironmentVariable('MAIL_HOST', $MAIL_HOST ?? 'smtp.mailtrap.io');
$MAIL_PORT = $this->ask('[KEY = "MAIL_PORT"] Enter MAIL_PORT (Optional, default = 2525)?');
$this->comment($MAIL_PORT ?? '2525');
$this->changeEnvironmentVariable('MAIL_PORT', $MAIL_PORT ?? '2525');
$MAIL_USERNAME = $this->ask('[KEY = "MAIL_USERNAME"] Enter MAIL_USERNAME?');
$this->comment($MAIL_USERNAME ?? null);
$this->changeEnvironmentVariable('MAIL_USERNAME', $MAIL_USERNAME);
$MAIL_PASSWORD = $this->ask('[KEY = "MAIL_PASSWORD"] Enter MAIL_PASSWORD?');
$this->comment($MAIL_PASSWORD ?? null);
$this->changeEnvironmentVariable('MAIL_PASSWORD', $MAIL_PASSWORD);
$MAIL_ENCRYPTION = $this->ask('[KEY = "MAIL_ENCRYPTION"] Enter MAIL_ENCRYPTION (default = tls)?');
$this->comment($MAIL_ENCRYPTION ?? 'tls');
$this->changeEnvironmentVariable('MAIL_ENCRYPTION', $MAIL_ENCRYPTION ?? 'tls');
$SHOP_MAIL_FROM = $this->ask('[KEY = "SHOP_MAIL_FROM"] Enter SHOP_MAIL_FROM?');
$this->comment($SHOP_MAIL_FROM ?? null);
$this->changeEnvironmentVariable('SHOP_MAIL_FROM', $SHOP_MAIL_FROM);
$ADMIN_MAIL_TO = $this->ask('[KEY = "ADMIN_MAIL_TO"] Enter ADMIN_MAIL_TO?');
$this->comment($ADMIN_MAIL_TO ?? null);
$this->changeEnvironmentVariable('ADMIN_MAIL_TO', $ADMIN_MAIL_TO);
$this->info('We are done setting all the configuration in the env file, now we will proceed by running the commands necessary for Bagisto');
\Artisan::call('config:cache');
$this->info('Running migrations...');
\Artisan::call('migrate');
$this->info('Migration completed.');
$this->info('Running seeders...');
\Artisan::call('db:seed', ['--force' => true]);
$this->info('Seeders finished.');
\Artisan::call('storage:link');
$this->info('Storage link created...');
\Artisan::call('vendor:publish', [0]);
$this->info('All provider tags are published...');
$this->info('Installation completed.');
$this->info('Please write us: SUPPORT@BAGISTO.COM');
$this->info('Thank you!!!');
}
public static function changeEnvironmentVariable($key, $value)
{
$path = base_path('.env');
if (file_exists($path)) {
file_put_contents($path, str_replace(
$key . '=' . env($key),
$key . '=' . $value,
file_get_contents($path)
));
}
}
}

View File

@ -4,6 +4,7 @@ namespace App\Console\Commands;
use Illuminate\Console\Command;
use Webkul\Product\Repositories\ProductRepository as Product;
use Webkul\Product\Helpers\GenerateProduct;
class GenerateProducts extends Command
{
@ -12,7 +13,7 @@ class GenerateProducts extends Command
*
* @var string
*/
protected $signature = 'bagisto:generate {value}';
protected $signature = 'bagisto:generate {value} {quantity}';
/**
* The console command description.
@ -21,6 +22,11 @@ class GenerateProducts extends Command
*/
protected $description = 'Generates product with random attribute values.';
/**
* GenerateProduct instance
*/
protected $generateProduct;
/**
* ProductRepository instance
*/
@ -31,11 +37,11 @@ class GenerateProducts extends Command
*
* @return void
*/
public function __construct(Product $product)
public function __construct(GenerateProduct $generateProduct)
{
parent::__construct();
$this->product = $product;
$this->generateProduct = $generateProduct;
}
/**
@ -45,10 +51,29 @@ class GenerateProducts extends Command
*/
public function handle()
{
if ($this->argument('value') == 'products') {
$this->comment('Under development.');
if (! is_string($this->argument('value')) || ! is_numeric($this->argument('quantity'))) {
$this->info('Illegal parameters or value of parameters are passed');
} else {
$this->line('Sorry, generate option is either invalid or does not exist.');
if (strtolower($this->argument('value')) == 'product' || strtolower($this->argument('value')) == 'products') {
$quantity = intval($this->argument('quantity'));
while ($quantity > 0) {
try {
$result = $this->generateProduct->create();
} catch (\Exception $e) {
continue;
}
$quantity--;
}
if ($result)
$this->info('Product(s) created successfully.');
else
$this->info('Product(s) cannot be created successfully.');
} else {
$this->line('Sorry, this generate option is invalid.');
}
}
}
}

View File

@ -8,30 +8,30 @@
"license": "MIT",
"type": "project",
"require": {
"php": "^7.1.3",
"ext-curl": "*",
"ext-intl": "*",
"ext-mbstring": "*",
"ext-openssl": "*",
"ext-pdo": "*",
"ext-pdo_mysql": "*",
"ext-tokenizer": "*",
"barryvdh/laravel-dompdf": "0.8.3",
"dimsav/laravel-translatable": "^9.0",
"doctrine/dbal": "2.9.2",
"fideloper/proxy": "^4.0",
"flynsarmy/db-blade-compiler": "*",
"guzzlehttp/guzzle": "~6.0",
"intervention/image": "^2.4",
"intervention/imagecache": "^2.3",
"kalnoy/nestedset": "^4.3",
"konekt/concord": "^1.2",
"laravel/framework": "5.6.*",
"laravel/tinker": "^1.0",
"maatwebsite/excel": "3.1.11",
"nwidart/laravel-modules": "^3.2",
"prettus/l5-repository": "2.6.32",
"tymon/jwt-auth": "1.0.0-rc.4"
"php": "^7.1.3",
"ext-curl": "*",
"ext-intl": "*",
"ext-mbstring": "*",
"ext-openssl": "*",
"ext-pdo": "*",
"ext-pdo_mysql": "*",
"ext-tokenizer": "*",
"astrotomic/laravel-translatable": "^11.0.0",
"barryvdh/laravel-dompdf": "0.8.3",
"doctrine/dbal": "2.9.2",
"fideloper/proxy": "^4.0",
"flynsarmy/db-blade-compiler": "*",
"guzzlehttp/guzzle": "~6.0",
"intervention/image": "^2.4",
"intervention/imagecache": "^2.3",
"kalnoy/nestedset": "^4.3",
"konekt/concord": "^1.2",
"laravel/framework": "5.6.*",
"laravel/tinker": "^1.0",
"maatwebsite/excel": "3.1.11",
"nwidart/laravel-modules": "^3.2",
"prettus/l5-repository": "2.6.32",
"tymon/jwt-auth": "1.0.0-rc.4"
},
"require-dev": {
"barryvdh/laravel-debugbar": "^3.1",

View File

@ -202,7 +202,7 @@ return [
* Package Service Providers...
*/
Dimsav\Translatable\TranslatableServiceProvider::class,
Astrotomic\Translatable\TranslatableServiceProvider::class,
/*
* Application Service Providers...

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
{
"/js/admin.js": "/js/admin.js?id=7f0b8f49bcf11cef838f",
"/css/admin.css": "/css/admin.css?id=672b2fe2c997f5899dff"
"/js/admin.js": "/js/admin.js?id=d6734b45d4aa9b6502d9",
"/css/admin.css": "/css/admin.css?id=15ccc108fec211bb2af2"
}

View File

@ -31,8 +31,13 @@ return [
'route' => 'admin.sales.invoices.index',
'sort' => 3,
'icon-class' => ''
],
[
], [
'key' => 'sales.refunds',
'name' => 'admin::app.layouts.refunds',
'route' => 'admin.sales.refunds.index',
'sort' => 4,
'icon-class' => ''
], [
'key' => 'catalog',
'name' => 'admin::app.layouts.catalog',
'route' => 'admin.catalog.products.index',

View File

@ -108,7 +108,7 @@ return [
'channel_based' => true,
]
]
],[
], [
'key' => 'general.content',
'name' => 'admin::app.admin.system.content',
'sort' => 2,
@ -123,6 +123,21 @@ return [
'type' => 'text',
'channel_based' => true,
'locale_based' => true
], [
'name' => 'footer_toggle',
'title' => 'admin::app.admin.system.footer-toggle',
'type' => 'select',
'options' => [
[
'title' => 'True',
'value' => 1
], [
'title' => 'False',
'value' => 0
]
],
'locale_based' => true,
'channel_based' => true,
]
]
], [

View File

@ -28,13 +28,13 @@ class OrderDataGrid extends DataGrid
$leftJoin->on('order_address_billing.order_id', '=', 'orders.id')
->where('order_address_billing.address_type', 'billing');
})
->addSelect('orders.id', 'orders.base_sub_total', 'orders.base_grand_total', 'orders.created_at', 'channel_name', 'status')
->addSelect('orders.id','orders.increment_id', 'orders.base_sub_total', 'orders.base_grand_total', 'orders.created_at', 'channel_name', 'status')
->addSelect(DB::raw('CONCAT(order_address_billing.first_name, " ", order_address_billing.last_name) as billed_to'))
->addSelect(DB::raw('CONCAT(order_address_shipping.first_name, " ", order_address_shipping.last_name) as shipped_to'));
$this->addFilter('billed_to', DB::raw('CONCAT(order_address_billing.first_name, " ", order_address_billing.last_name)'));
$this->addFilter('shipped_to', DB::raw('CONCAT(order_address_shipping.first_name, " ", order_address_shipping.last_name)'));
$this->addFilter('id', 'orders.id');
$this->addFilter('increment_id', 'orders.increment_id');
$this->addFilter('created_at', 'orders.created_at');
$this->setQueryBuilder($queryBuilder);
@ -43,9 +43,9 @@ class OrderDataGrid extends DataGrid
public function addColumns()
{
$this->addColumn([
'index' => 'id',
'index' => 'increment_id',
'label' => trans('admin::app.datagrid.id'),
'type' => 'number',
'type' => 'string',
'searchable' => false,
'sortable' => true,
'filterable' => true

View File

@ -19,7 +19,14 @@ class OrderInvoicesDataGrid extends DataGrid
public function prepareQueryBuilder()
{
$queryBuilder = DB::table('invoices')->select('id', 'order_id', 'state', 'base_grand_total', 'created_at');
$queryBuilder = DB::table('invoices')
->leftJoin('orders as ors', 'invoices.order_id', '=', 'ors.id')
->select('invoices.id as id', 'ors.increment_id as order_id', 'invoices.state as state', 'invoices.base_grand_total as base_grand_total', 'invoices.created_at as created_at');
$this->addFilter('id', 'invoices.id');
$this->addFilter('order_id', 'ors.increment_id');
$this->addFilter('base_grand_total', 'invoices.base_grand_total');
$this->addFilter('created_at', 'invoices.created_at');
$this->setQueryBuilder($queryBuilder);
}
@ -38,7 +45,7 @@ class OrderInvoicesDataGrid extends DataGrid
$this->addColumn([
'index' => 'order_id',
'label' => trans('admin::app.datagrid.order-id'),
'type' => 'number',
'type' => 'string',
'searchable' => true,
'sortable' => true,
'filterable' => true

View File

@ -0,0 +1,97 @@
<?php
namespace Webkul\Admin\DataGrids;
use Webkul\Ui\DataGrid\DataGrid;
use DB;
/**
* OrderRefundDataGrid Class
*
* @author Prashant Singh <jitendra@webkul.com>
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class OrderRefundDataGrid extends DataGrid
{
protected $index = 'id';
protected $sortOrder = 'desc'; //asc or desc
public function prepareQueryBuilder()
{
$queryBuilder = DB::table('refunds')
->select('refunds.id', 'orders.increment_id', 'refunds.state', 'refunds.base_grand_total', 'refunds.created_at')
->leftJoin('orders', 'refunds.order_id', '=', 'orders.id')
->leftJoin('order_address as order_address_billing', function($leftJoin) {
$leftJoin->on('order_address_billing.order_id', '=', 'orders.id')
->where('order_address_billing.address_type', 'billing');
})
->addSelect(DB::raw('CONCAT(order_address_billing.first_name, " ", order_address_billing.last_name) as billed_to'));
$this->addFilter('billed_to', DB::raw('CONCAT(order_address_billing.first_name, " ", order_address_billing.last_name)'));
$this->addFilter('id', 'refunds.id');
$this->addFilter('increment_id', 'orders.increment_id');
$this->addFilter('state', 'refunds.state');
$this->addFilter('base_grand_total', 'refunds.base_grand_total');
$this->addFilter('created_at', 'refunds.created_at');
$this->setQueryBuilder($queryBuilder);
}
public function addColumns()
{
$this->addColumn([
'index' => 'id',
'label' => trans('admin::app.datagrid.id'),
'type' => 'number',
'searchable' => false,
'sortable' => true,
'filterable' => true
]);
$this->addColumn([
'index' => 'increment_id',
'label' => trans('admin::app.datagrid.order-id'),
'type' => 'number',
'searchable' => true,
'sortable' => true,
'filterable' => true
]);
$this->addColumn([
'index' => 'base_grand_total',
'label' => trans('admin::app.datagrid.refunded'),
'type' => 'price',
'searchable' => true,
'sortable' => true,
'filterable' => true
]);
$this->addColumn([
'index' => 'billed_to',
'label' => trans('admin::app.datagrid.billed-to'),
'type' => 'string',
'searchable' => true,
'sortable' => true,
'filterable' => true
]);
$this->addColumn([
'index' => 'created_at',
'label' => trans('admin::app.datagrid.refund-date'),
'type' => 'datetime',
'searchable' => true,
'sortable' => true,
'filterable' => true
]);
}
public function prepareActions() {
$this->addAction([
'title' => 'Order Refund View',
'method' => 'GET', // use GET request only for redirect purposes
'route' => 'admin.sales.refunds.view',
'icon' => 'icon eye-icon'
]);
}
}

View File

@ -26,7 +26,7 @@ class OrderShipmentsDataGrid extends DataGrid
})
->leftJoin('orders as ors', 'shipments.order_id', '=', 'ors.id')
->leftJoin('inventory_sources as is', 'shipments.inventory_source_id', '=', 'is.id')
->select('shipments.id as shipment_id', 'shipments.order_id as shipment_order_id', 'shipments.total_qty as shipment_total_qty', 'is.name as inventory_source_name', 'ors.created_at as order_date', 'shipments.created_at as shipment_created_at')
->select('shipments.id as shipment_id', 'ors.increment_id as shipment_order_id', 'shipments.total_qty as shipment_total_qty', 'is.name as inventory_source_name', 'ors.created_at as order_date', 'shipments.created_at as shipment_created_at')
->addSelect(DB::raw('CONCAT(order_address_shipping.first_name, " ", order_address_shipping.last_name) as shipped_to'));
$this->addFilter('shipment_id', 'shipments.id');
@ -54,7 +54,7 @@ class OrderShipmentsDataGrid extends DataGrid
$this->addColumn([
'index' => 'shipment_order_id',
'label' => trans('admin::app.datagrid.order-id'),
'type' => 'number',
'type' => 'string',
'searchable' => true,
'sortable' => true,
'filterable' => true

View File

@ -102,7 +102,6 @@ class CustomerController extends Controller
public function store()
{
$this->validate(request(), [
'channel_id' => 'required',
'first_name' => 'string|required',
'last_name' => 'string|required',
'gender' => 'required',
@ -157,7 +156,6 @@ class CustomerController extends Controller
public function update($id)
{
$this->validate(request(), [
'channel_id' => 'required',
'first_name' => 'string|required',
'last_name' => 'string|required',
'gender' => 'required',

View File

@ -143,13 +143,13 @@ class DashboardController extends Controller
'progress' => $this->getPercentageChange($previous, $current)
],
'total_sales' => [
'previous' => $previous = $this->previousOrders()->sum('base_grand_total'),
'current' => $current = $this->currentOrders()->sum('base_grand_total'),
'previous' => $previous = $this->previousOrders()->sum('base_grand_total_invoiced') - $this->previousOrders()->sum('base_grand_total_refunded'),
'current' => $current = $this->currentOrders()->sum('base_grand_total_invoiced') - $this->currentOrders()->sum('base_grand_total_refunded'),
'progress' => $this->getPercentageChange($previous, $current)
],
'avg_sales' => [
'previous' => $previous = $this->previousOrders()->avg('base_grand_total'),
'current' => $current = $this->currentOrders()->avg('base_grand_total'),
'previous' => $previous = $this->previousOrders()->avg('base_grand_total_invoiced') - $this->previousOrders()->avg('base_grand_total_refunded'),
'current' => $current = $this->currentOrders()->avg('base_grand_total_invoiced') - $this->currentOrders()->avg('base_grand_total_refunded'),
'progress' => $this->getPercentageChange($previous, $current)
],
'top_selling_categories' => $this->getTopSellingCategories(),
@ -161,7 +161,7 @@ class DashboardController extends Controller
foreach (core()->getTimeInterval($this->startDate, $this->endDate) as $interval) {
$statistics['sale_graph']['label'][] = $interval['start']->format('d M');
$total = $this->getOrdersBetweenDate($interval['start'], $interval['end'])->sum('base_grand_total');
$total = $this->getOrdersBetweenDate($interval['start'], $interval['end'])->sum('base_grand_total_invoiced') - $this->getOrdersBetweenDate($interval['start'], $interval['end'])->sum('base_grand_total_refunded');
$statistics['sale_graph']['total'][] = $total;
$statistics['sale_graph']['formated_total'][] = core()->formatBasePrice($total);
@ -185,12 +185,12 @@ class DashboardController extends Controller
->where('category_translations.locale', app()->getLocale())
->where('order_items.created_at', '>=', $this->startDate)
->where('order_items.created_at', '<=', $this->endDate)
->where('order_items.qty_ordered', '>', 0)
->addSelect(DB::raw('SUM(qty_ordered) as total_qty_ordered'))
->addSelect(DB::raw('SUM(qty_invoiced - qty_refunded) as total_qty_invoiced'))
->addSelect(DB::raw('COUNT(products.id) as total_products'))
->addSelect('order_items.id', 'categories.id as category_id', 'category_translations.name')
->groupBy('categories.id')
->orderBy('total_qty_ordered', 'DESC')
->havingRaw('SUM(qty_invoiced - qty_refunded) > 0')
->orderBy('total_qty_invoiced', 'DESC')
->limit(5)
->get();
}

View File

@ -0,0 +1,169 @@
<?php
namespace Webkul\Admin\Http\Controllers\Sales;
use Webkul\Admin\Http\Controllers\Controller;
use Webkul\Sales\Repositories\OrderRepository;
use Webkul\Sales\Repositories\OrderItemRepository;
use Webkul\Sales\Repositories\RefundRepository;
/**
* Sales Refund controller
*
* @author Jitendra Singh <jitendra@webkul.com>
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class RefundController extends Controller
{
/**
* Display a listing of the resource.
*
* @var array
*/
protected $_config;
/**
* OrderRepository object
*
* @var Object
*/
protected $orderRepository;
/**
* OrderItemRepository object
*
* @var Object
*/
protected $orderItemRepository;
/**
* RefundRepository object
*
* @var Object
*/
protected $refundRepository;
/**
* Create a new controller instance.
*
* @param \Webkul\Sales\Repositories\OrderRepository $orderRepository
* @param \Webkul\Sales\Repositories\OrderItemRepository $orderItemRepository
* @param \Webkul\Sales\Repositories\RefundRepository $refundRepository
* @return void
*/
public function __construct(
OrderRepository $orderRepository,
OrderItemRepository $orderItemRepository,
RefundRepository $refundRepository
)
{
$this->middleware('admin');
$this->_config = request('_config');
$this->orderRepository = $orderRepository;
$this->orderItemRepository = $orderItemRepository;
$this->refundRepository = $refundRepository;
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\View
*/
public function index()
{
return view($this->_config['view']);
}
/**
* Show the form for creating a new resource.
*
* @param int $orderId
* @return \Illuminate\Http\View
*/
public function create($orderId)
{
$order = $this->orderRepository->findOrFail($orderId);
return view($this->_config['view'], compact('order'));
}
/**
* Store a newly created resource in storage.
*
* @param int $orderId
* @return \Illuminate\Http\Response
*/
public function store($orderId)
{
$order = $this->orderRepository->findOrFail($orderId);
if (! $order->canRefund()) {
session()->flash('error', trans('admin::app.sales.refunds.creation-error'));
return redirect()->back();
}
$this->validate(request(), [
'refund.items.*' => 'required|numeric|min:0'
]);
$data = request()->all();
$totals = $this->refundRepository->getOrderItemsRefundSummary($data['refund']['items'], $orderId);
$maxRefundAmount = $totals['grand_total']['price'] - $order->refunds()->sum('base_adjustment_refund');
$refundAmount = $totals['grand_total']['price'] - $totals['shipping']['price'] + $data['refund']['shipping'] + $data['refund']['adjustment_refund'] - $data['refund']['adjustment_fee'];
if (! $refundAmount) {
session()->flash('error', trans('admin::app.sales.refunds.invalid-refund-amount-error'));
return redirect()->back();
}
if ($refundAmount > $maxRefundAmount) {
session()->flash('error', trans('admin::app.sales.refunds.refund-limit-error', ['amount' => core()->formatBasePrice($maxRefundAmount)]));
return redirect()->back();
}
$this->refundRepository->create(array_merge($data, ['order_id' => $orderId]));
session()->flash('success', trans('admin::app.response.create-success', ['name' => 'Refund']));
return redirect()->route($this->_config['redirect'], $orderId);
}
/**
* Store a newly created resource in storage.
*
* @param int $orderId
* @return \Illuminate\Http\JsonResponse
*/
public function updateQty($orderId)
{
$data = $this->refundRepository->getOrderItemsRefundSummary(request()->all(), $orderId);
if (! $data)
return response('');
return response()->json($data);
}
/**
* Show the view for the specified resource.
*
* @param int $id
* @return \Illuminate\Http\View
*/
public function view($id)
{
$refund = $this->refundRepository->findOrFail($id);
return view($this->_config['view'], compact('refund'));
}
}

View File

@ -196,6 +196,28 @@ Route::group(['middleware' => ['web']], function () {
Route::get('/shipments/view/{id}', 'Webkul\Admin\Http\Controllers\Sales\ShipmentController@view')->defaults('_config', [
'view' => 'admin::sales.shipments.view'
])->name('admin.sales.shipments.view');
// Sales Redunds Routes
Route::get('/refunds', 'Webkul\Admin\Http\Controllers\Sales\RefundController@index')->defaults('_config', [
'view' => 'admin::sales.refunds.index'
])->name('admin.sales.refunds.index');
Route::get('/refunds/create/{order_id}', 'Webkul\Admin\Http\Controllers\Sales\RefundController@create')->defaults('_config', [
'view' => 'admin::sales.refunds.create'
])->name('admin.sales.refunds.create');
Route::post('/refunds/create/{order_id}', 'Webkul\Admin\Http\Controllers\Sales\RefundController@store')->defaults('_config', [
'redirect' => 'admin.sales.orders.view'
])->name('admin.sales.refunds.store');
Route::post('/refunds/update-qty/{order_id}', 'Webkul\Admin\Http\Controllers\Sales\RefundController@updateQty')->defaults('_config', [
'redirect' => 'admin.sales.orders.view'
])->name('admin.sales.refunds.update_qty');
Route::get('/refunds/view/{id}', 'Webkul\Admin\Http\Controllers\Sales\RefundController@view')->defaults('_config', [
'view' => 'admin::sales.refunds.view'
])->name('admin.sales.refunds.view');
});
// Catalog Routes

View File

@ -9,6 +9,7 @@ use Webkul\Admin\Mail\NewInvoiceNotification;
use Webkul\Admin\Mail\NewShipmentNotification;
use Webkul\Admin\Mail\NewInventorySourceNotification;
use Webkul\Admin\Mail\CancelOrderNotification;
use Webkul\Admin\Mail\NewRefundNotification;
/**
* Order event handler
*
@ -33,7 +34,6 @@ class Order {
}
}
/**
* @param mixed $invoice
*
@ -51,6 +51,20 @@ class Order {
}
}
/**
* @param mixed $refund
*
* Send new refund mail to the customer
*/
public function sendNewRefundMail($refund)
{
try {
Mail::queue(new NewRefundNotification($refund));
} catch (\Exception $e) {
}
}
/**
* @param mixed $shipment
*

View File

@ -51,7 +51,7 @@ class NewCustomerNotification extends Mailable
public function build()
{
return $this->to($this->customer->email)
->subject(trans('shop::app.mail.customer.subject'))
->subject(trans('shop::app.mail.customer.new.subject'))
->view('shop::emails.customer.new-customer')->with(['customer' => $this->customer, 'password' => $this->password]);
}
}

View File

@ -46,7 +46,7 @@ class NewInventorySourceNotification extends Mailable
$inventory = $this->shipment->inventory_source;
return $this->to($inventory->contact_email, $inventory->name)
->subject(trans('shop::app.mail.shipment.subject', ['order_id' => $order->id]))
->subject(trans('shop::app.mail.shipment.subject', ['order_id' => $order->increment_id]))
->view('shop::emails.sales.new-inventorysource-shipment');
}
}

View File

@ -46,7 +46,7 @@ class NewInvoiceNotification extends Mailable
return $this->to($order->customer_email, $order->customer_full_name)
->from(env('SHOP_MAIL_FROM'))
->subject(trans('shop::app.mail.invoice.subject', ['order_id' => $order->id]))
->subject(trans('shop::app.mail.invoice.subject', ['order_id' => $order->increment_id]))
->view('shop::emails.sales.new-invoice');
}
}

View File

@ -0,0 +1,52 @@
<?php
namespace Webkul\Admin\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
/**
* New Refund Mail class
*
* @author Jitendra Singh <jitendra@webkul.com>
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class NewRefundNotification extends Mailable
{
use Queueable, SerializesModels;
/**
* The refund instance.
*
* @var Refund
*/
public $refund;
/**
* Create a new message instance.
*
* @param mixed $refund
* @return void
*/
public function __construct($refund)
{
$this->refund = $refund;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
$order = $this->refund->order;
return $this->to($order->customer_email, $order->customer_full_name)
->from(env('SHOP_MAIL_FROM'))
->subject(trans('shop::app.mail.refund.subject', ['order_id' => $order->increment_id]))
->view('shop::emails.sales.new-refund');
}
}

View File

@ -46,7 +46,7 @@ class NewShipmentNotification extends Mailable
return $this->to($order->customer_email, $order->customer_full_name)
->from(env('SHOP_MAIL_FROM'))
->subject(trans('shop::app.mail.shipment.subject', ['order_id' => $order->id]))
->subject(trans('shop::app.mail.shipment.subject', ['order_id' => $order->increment_id]))
->view('shop::emails.sales.new-shipment');
}
}

View File

@ -21,5 +21,7 @@ class EventServiceProvider extends ServiceProvider
Event::listen('sales.shipment.save.after', 'Webkul\Admin\Listeners\Order@sendNewShipmentMail');
Event::listen('sales.order.cancel.after','Webkul\Admin\Listeners\Order@sendCancelOrderMail');
Event::listen('sales.refund.save.after','Webkul\Admin\Listeners\Order@sendNewRefundMail');
}
}

View File

@ -0,0 +1,3 @@
$black: #0000;
$brand-color: #0041FF;
$white: #ffffff;

View File

@ -1,9 +1,26 @@
// Body
$brand-color: #0041FF;
$border-color: rgba(162, 162, 162, 0.2);
$body-background: $white;
$background-color: #f8f9fa;
$border-color: rgba(162, 162, 162, 0.2);
$navbar-top-background: $white;
// Accordion
$accordian-header: #fbfbfb;
// Buttons
$btn-primary: $white;
$btn-primary-bg: #0041FF;
// Cards
$card-title: #a2a2a2;
$card-background: $white;
// Dashboard
$dashboard-stats-data: #0041ff;
// Typography
$font-family: 'Montserrat', sans-serif;
$font-size-base: 14px;
$font-color: #3A3A3A;
$link-color: #a2a2a2;
$link-active-color: #a2a2a2;

View File

@ -2,919 +2,15 @@
@import url("https://fonts.googleapis.com/css?family=Montserrat:400,500");
// Variables
@import "colors";
@import "variables";
@import "mixins";
body {
margin: 0;
color: $font-color;
font-family: $font-family;
font-size: $font-size-base;
font-weight: 500;
position: static;
min-height: 100%;
width: 100%;
}
@import "partials/default";
::-webkit-scrollbar {
width: 12px;
}
@import "partials/dashboard";
@import "partials/configuration";
@import "partials/sales";
@import "partials/rtl";
::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 6px rgba(255, 255, 255, 0.3);
border-radius: 10px;
}
::-webkit-scrollbar-thumb {
border-radius: 10px;
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.5);
}
.navbar-top {
height: 60px;
background: #ffffff;
font-size: 0;
@include box-shadow(0 3px 6px 0 rgba(0, 0, 0, 0.05));
border-bottom: 1px solid $border-color;
position: fixed;
left: 0;
right: 0;
z-index: 5;
.navbar-top-left {
width: 50%;
height: 60px;
display: inline-block;
vertical-align: middle;
.brand-logo {
padding: 10px;
}
}
.navbar-top-right {
width: 50%;
height: 60px;
text-align: right;
display: inline-block;
vertical-align: middle;
.profile-info {
display: inline-block;
vertical-align: middle;
text-align: left;
min-width: 50px;
position: relative;
padding: 12px 0px;
margin: 0px 25px 0px 30px;
font-size: 15px;
cursor: pointer;
position: relative;
.dropdown-list {
top: 63px;
}
.name {
color: #000311;
display: block;
text-align: left;
}
.role {
font-size: 14px;
color: #8e8e8e;
display: block;
text-align: left;
}
i.icon {
margin-left: 10px;
}
}
}
}
.navbar-left {
position: fixed;
left: 0;
top: 60px;
width: 90px;
padding-top: 20px;
border-right: 1px solid rgba(162, 162, 162, 0.2);
height: auto;
bottom: 0;
z-index: 2;
ul.menubar {
// padding-bottom: 60px;
li.menu-item {
padding: 10px 5px;
font-size: 11px;
text-align: center;
text-transform: uppercase;
a {
color: #a2a2a2;
}
&.active {
a {
color: #0041ff;
}
}
span {
display: block;
margin: auto;
}
}
}
// .open-nav-aside {
// position: fixed;
// bottom: 0;
// left: 0;
// width: 90px;
// padding: 18px;
// text-align: center;
// border: 1px solid $border-color;
// .icon {
// height: 24px;
// width: 24px;
// }
// }
}
.content-container {
padding-left: 90px;
position: absolute;
margin-top: 60px;
top: 0px;
right: 0;
left: 0;
bottom: 0px;
height: calc(100% - 60px);
width: 100%;
.inner-section {
height: 100%;
}
.aside-nav {
width: 280px;
position: fixed;
top: 60px;
bottom: 0;
border-right: 1px solid $border-color;
background: $background-color;
padding-top: 10px;
padding-bottom: 10px;
z-index: 4;
ul {
overflow-y: auto;
height: 90%;
}
a {
padding: 15px;
display: block;
color: #000311;
}
.active {
a {
background: #ffffff;
border-top: 1px solid $border-color;
border-bottom: 1px solid $border-color;
}
i {
float: right;
}
}
}
.content-wrapper {
padding: 25px 25px 25px 25px;
margin-left: 305px;
}
.content {
margin-top: 25px;
&.full-page {
padding: 25px;
}
.page-header {
display: inline-block;
width: 100%;
padding: 15px 0px 15px 0px;
position: sticky;
top: 60px;
background-color: #ffffff;
z-index: 3;
.page-title {
float: left;
.back-link {
float: left;
margin-right: 10px;
width: 24px;
height: 24px;
cursor: pointer;
margin-top: 5px;
}
h1 {
margin-bottom: 0;
vertical-align: middle;
display: inline-block;
line-height: initial;
}
}
.page-action {
float: right;
* {
display: inline-block;
}
a {
margin-left: 25px;
}
}
.control-group {
width: 180px;
display: inline-block;
margin-bottom: 0;
margin-left: 20px;
}
.control {
width: 100%;
margin: 0;
}
}
.page-content {
width: 100%;
display: inline-block;
}
}
}
.control-container {
display: flex;
flex-direction: row;
align-items: flex-start;
width: 750px;
.control {
background: #fff;
border: 2px solid #c7c7c7;
@include border-radius(3px);
width: 150px;
height: 36px;
display: inline-block;
vertical-align: middle;
transition: 0.2s cubic-bezier(0.4, 0, 0.2, 1);
padding: 0px 10px;
font-size: 15px;
&:focus {
border-color: #0041ff;
}
}
.icon:hover {
cursor: pointer;
}
.control-group::last-child {
margin-right: 0px;
}
}
.boolean-control-container {
display: flex;
flex-direction: row;
justify-content: flex-start;
width: 750px;
.control-group {
width: 200px;
}
}
.control-group {
label {
width: 70%;
.locale {
float: right;
color: #8e8e8e;
}
}
.mce-tinymce {
margin-top: 10px;
margin-bottom: 5px;
}
}
// admin dashboard css
.dashboard {
.page-header {
margin-bottom: 0 !important;
padding-bottom: 15px;
border-bottom: 1px solid $border-color;
}
.page-content {
margin-top: 15px;
}
.card {
height: 445px;
background: #ffffff;
border: 1px solid #e7e7e7;
box-shadow: 0 5px 10px 2px rgba(0, 0, 0, 0.08);
border-radius: 2px;
padding: 20px 0px 0px 20px;
overflow: auto;
.card-title {
font-size: 14px;
color: #a2a2a2;
letter-spacing: -0.26px;
text-transform: uppercase;
}
.card-info {
width: 100%;
display: inline-block;
&.center {
text-align: center;
}
ul {
li {
border-bottom: 1px solid $border-color;
width: 100%;
display: inline-block;
padding: 10px 0;
position: relative;
.image {
height: 60px;
width: 60px;
float: left;
margin-right: 15px;
&.product {
background: #f2f2f2;
}
img {
width: 100%;
}
}
.description {
margin-top: 10px;
.name {
color: #0041ff;
}
.info {
color: #3a3a3a;
margin-top: 5px;
}
}
.icon.angle-right-icon {
position: absolute;
right: 30px;
top: 50%;
margin-top: -8px;
}
&:last-child {
border-bottom: 0;
}
}
}
.no-result-found {
margin-top: 146px;
p {
margin: 0;
color: #a2a2a2;
}
}
}
}
.dashboard-stats {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
grid-auto-rows: auto;
grid-column-gap: 30px;
grid-row-gap: 15px;
.dashboard-card {
height: 100px;
background: #ffffff;
border: 1px solid #e7e7e7;
box-shadow: 0 5px 10px 2px rgba(0, 0, 0, 0.08);
border-radius: 5px;
position: relative;
padding: 15px;
.title {
font-size: 14px;
color: #a2a2a2;
text-transform: uppercase;
}
.data {
padding-top: 13px;
font-size: 32px;
color: #0041ff;
.progress {
font-size: 14px;
color: #8e8e8e;
float: right;
margin-top: -2px;
.icon {
vertical-align: middle;
}
}
}
}
}
.graph-stats {
margin-top: 30px;
width: 100%;
display: inline-block;
.left-card-container {
float: left;
width: 75%;
padding-right: 9px;
}
.right-card-container {
float: left;
width: 25%;
padding-left: 21px;
}
}
.sale-stock {
width: 100%;
display: inline-block;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(435px, 1fr));
grid-auto-rows: auto;
grid-column-gap: 30px;
grid-row-gap: 15px;
margin-top: 30px;
}
}
// admin dashboard css ends here
// customer oder css for admin start here
.sale-container {
.sale-section {
font-size: 16px;
.secton-title {
font-size: 18px;
color: #8e8e8e;
padding: 15px 0;
border-bottom: 1px solid $border-color;
}
.section-content {
display: block;
padding: 20px 0;
.row {
display: block;
padding: 7px 0;
.title {
width: 200px;
color: $font-color;
letter-spacing: -0.26px;
display: inline-block;
}
.value {
color: $font-color;
letter-spacing: -0.26px;
display: inline-block;
}
}
}
}
.table {
.qty-row {
display: block;
margin-bottom: 5px;
&:last-child {
margin-bottom: 0;
}
}
.radio {
margin: 0;
}
}
.sale-summary {
margin-top: 2%;
height: 130px;
float: right;
tr {
td {
padding: 5px 8px;
}
&.bold {
font-weight: 600;
font-size: 15px;
}
&.border {
td {
border-bottom: 1px solid $border-color;
}
}
}
}
}
.stars {
margin-top: 5px;
.icon {
width: 16px;
height: 16px;
}
}
.export-import {
cursor: pointer;
.export-icon,
.import-icon {
position: relative;
top: 10px;
}
span {
margin-left: 2px;
}
}
// customer oder css for admin end here
//configuration css
.configuration-image {
position: relative;
height: 33px;
width: 33px;
top: 15px;
border-radius: 3px;
margin-right: 5px;
}
.download {
position: relative;
height: 24px !important;
width: 24px !important;
top: 12px;
margin-right: 10px;
}
.aside-nav-toggle {
height: 48px;
width: 100%;
padding-top: 15px;
border-top: 1px solid rgba(162, 162, 162, 0.2);
.close-icon,
.open-icon {
position: absolute;
cursor: pointer;
left: 45%;
}
}
.aside-nav-toggle.open {
display: none;
}
.linked-product-search-result {
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.16), 0 0 9px 0 rgba(0, 0, 0, 0.16);
z-index: 10;
text-align: left;
border-radius: 3px;
background-color: #ffffff;
width: 70%;
max-height: 200px;
overflow-y: auto;
li {
padding: 10px;
border-bottom: 1px solid #e8e8e8;
cursor: pointer;
}
}
// css for rtl start here
.rtl {
direction: rtl;
.navbar-top {
.navbar-top-right {
text-align: left;
.profile-info {
margin: 0 30px 0 25px;
i.icon {
margin-left: 0px;
margin-right: 10px;
}
}
}
}
.navbar-left {
border-left: 1px solid rgba(162, 162, 162, 0.2);
border-right: none;
left: calc(100% - 90px);
}
.content-container {
padding-right: 90px;
padding-left: 0px;
.content .page-header {
.page-title {
float: right;
}
.page-action {
float: left;
a {
margin-left: 0px;
}
}
.control-group {
margin-right: 20px;
margin-left: 0px;
}
.control-group.date {
&::after {
margin-top: 6px;
position: absolute;
margin-right: -35px;
}
&:last-child {
margin-left: 0px;
}
}
}
.content-wrapper {
padding: 25px 305px 25px 25px;
margin-left: 0px;
}
.aside-nav .active i {
float: left;
transform: rotate(180deg);
}
}
.dashboard {
.dashboard-stats .dashboard-card .data span {
float: left;
}
.card {
padding: 20px 20px 0px 0px;
.card-info ul li {
.image {
float: right;
margin-right: 0px;
margin-left: 15px;
}
.icon.angle-right-icon {
left: 30px;
right: auto;
transform: rotate(180deg);
}
}
}
.graph-stats {
.left-card-container {
float: right;
padding-right: 0px;
}
.right-card-container {
float: right;
padding-left: 0px;
padding-right: 30px;
}
}
}
.sale-container .sale-summary {
float: left;
}
// ui
.grid-container {
.filter-row-one .search-filter {
border: 2px solid #c7c7c7;
border-radius: 2px;
.control {
border: none;
padding-right: 10px;
}
.icon-wrapper {
border: none;
padding-top: 2px;
padding-right: 5px;
border-right: 2px solid #c7c7c7;
border-radius: 0px;
}
}
.filter-row-two .filter-tag {
.wrapper,
.icon.cross-icon {
margin-right: 10px;
margin-left: 0px;
}
}
.filter-row-one .dropdown-filters {
right: unset;
left: 25px;
}
}
.grid-container
.filter-wrapper
.filter-row-one
.dropdown-filters
.more-filters
.dropdown-toggle
.dropdown-header
span {
padding-right: 5px;
}
.grid-container .table tbody td.action a:first-child {
margin-left: 10px;
margin-right: 0px;
}
.table table {
text-align: right;
.massaction-remove {
margin-right: 5px !important;
margin-left: 10px;
}
.btn.btn-primary {
margin-right: 10px !important;
}
}
.dropdown-list.bottom-right {
left: 0px;
right: auto;
}
.dropdown-list .dropdown-container {
text-align: right;
}
.accordian .accordian-header .icon {
float: left;
}
.tree-container .tree-item {
padding-right: 30px;
.expand-icon,
.folder-icon {
margin-left: 10px;
margin-right: 0px;
}
}
.tree-container > .tree-item {
padding-right: 0px;
}
.radio .radio-view {
margin-left: 5px;
}
.image-wrapper .image-item {
margin-right: 0px;
margin-left: 20px;
.remove-image {
margin-right: 0px;
}
}
.control-group label.required::before {
content: "*";
color: #fc6868;
font-weight: 700;
}
.control-group label.required::after {
content: none;
}
.control-group label .locale {
float: left;
}
.control-group.date {
&::after {
margin-top: 15px;
position: absolute;
margin-right: -35px;
}
}
.pagination .page-item .icon {
transform: rotate(180deg);
}
}
// css for rtl end here
// For fixed and and save button
.fixed-action {
position: fixed;
top: 108px;
right: 32px;
z-index: 20;
}
.fixed-action-slight {
position: fixed;
top: 94px;
right: 32px;
z-index: 20;
}
.pagination {
margin-top: 30px;
}
.item-options {
font-weight: 200;
b {
font-weight: 500;
}
}
@import "partials/ui/components";

View File

@ -0,0 +1,51 @@
.configuration-image {
position: relative;
height: 33px;
width: 33px;
top: 15px;
border-radius: 3px;
margin-right: 5px;
}
.download {
position: relative;
height: 24px !important;
width: 24px !important;
top: 12px;
margin-right: 10px;
}
.aside-nav-toggle {
height: 48px;
width: 100%;
padding-top: 15px;
border-top: 1px solid rgba(162, 162, 162, 0.2);
.close-icon,
.open-icon {
position: absolute;
cursor: pointer;
left: 45%;
}
}
.aside-nav-toggle.open {
display: none;
}
.linked-product-search-result {
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.16), 0 0 9px 0 rgba(0, 0, 0, 0.16);
z-index: 10;
text-align: left;
border-radius: 3px;
background-color: $white;
width: 70%;
max-height: 200px;
overflow-y: auto;
li {
padding: 10px;
border-bottom: 1px solid #e8e8e8;
cursor: pointer;
}
}

View File

@ -0,0 +1,165 @@
.dashboard {
.page-header {
margin-bottom: 0 !important;
padding-bottom: 15px;
border-bottom: 1px solid $border-color;
}
.page-content {
margin-top: 15px;
}
.card {
height: 445px;
background-color: $card-background;
border: 1px solid $border-color;
box-shadow: 0 5px 10px 2px $border-color;
border-radius: 0.25rem;
padding: 20px 0px 0px 20px;
overflow: auto;
.card-title {
font-size: 14px;
color: $card-title;
letter-spacing: -0.26px;
text-transform: uppercase;
}
.card-info {
width: 100%;
display: inline-block;
&.center {
text-align: center;
}
ul {
li {
border-bottom: 1px solid $border-color;
width: 100%;
display: inline-block;
padding: 10px 0;
position: relative;
.image {
height: 60px;
width: 60px;
float: left;
margin-right: 15px;
&.product {
background: #f2f2f2;
}
img {
width: 100%;
}
}
.description {
margin-top: 10px;
.name {
color: #0041ff;
}
.info {
color: #3a3a3a;
margin-top: 5px;
}
}
.icon.angle-right-icon {
position: absolute;
right: 30px;
top: 50%;
margin-top: -8px;
}
&:last-child {
border-bottom: 0;
}
}
}
.no-result-found {
margin-top: 146px;
p {
margin: 0;
color: #a2a2a2;
}
}
}
}
.dashboard-stats {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
grid-auto-rows: auto;
grid-column-gap: 30px;
grid-row-gap: 15px;
.dashboard-card {
height: 100px;
background: $card-background;
border: 1px solid $border-color;
box-shadow: 0 5px 10px 2px $border-color;
border-radius: 5px;
position: relative;
padding: 15px;
.title {
font-size: 14px;
color: $card-title;
text-transform: uppercase;
}
.data {
padding-top: 13px;
font-size: 32px;
color: $dashboard-stats-data;
.progress {
font-size: 14px;
color: #8e8e8e;
float: right;
margin-top: -2px;
.icon {
vertical-align: middle;
}
}
}
}
}
.graph-stats {
margin-top: 30px;
width: 100%;
display: inline-block;
.left-card-container {
float: left;
width: 75%;
padding-right: 9px;
}
.right-card-container {
float: left;
width: 25%;
padding-left: 21px;
}
}
.sale-stock {
width: 100%;
display: inline-block;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(435px, 1fr));
grid-auto-rows: auto;
grid-column-gap: 30px;
grid-row-gap: 15px;
margin-top: 30px;
}
}

View File

@ -0,0 +1,312 @@
body {
margin: 0;
color: $font-color;
font-family: $font-family;
font-size: $font-size-base;
font-weight: 500;
position: static;
height: 100%;
width: 100%;
background-color: $body-background;
}
::-webkit-scrollbar {
width: 12px;
}
::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 6px rgba(255, 255, 255, 0.3);
border-radius: 10px;
}
::-webkit-scrollbar-thumb {
border-radius: 10px;
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.5);
}
.navbar-top {
height: 60px;
background-color: $navbar-top-background;
font-size: 0;
@include box-shadow(0 3px 6px 0 rgba(0, 0, 0, 0.05));
border-bottom: 1px solid $border-color;
position: fixed;
left: 0;
right: 0;
z-index: 5;
.navbar-top-left {
width: 50%;
height: 60px;
display: inline-block;
vertical-align: middle;
background-color: $white;
.brand-logo {
padding: 10px;
}
}
.navbar-top-right {
width: 50%;
height: 60px;
text-align: right;
display: inline-block;
vertical-align: middle;
.profile-info {
display: inline-block;
vertical-align: middle;
text-align: left;
min-width: 50px;
position: relative;
padding: 12px 0px;
margin: 0px 25px 0px 30px;
font-size: 15px;
cursor: pointer;
position: relative;
.dropdown-list {
top: 63px;
}
.name {
color: #000311;
display: block;
text-align: left;
}
.role {
font-size: 14px;
color: #8e8e8e;
display: block;
text-align: left;
}
i.icon {
margin-left: 10px;
}
}
}
}
.navbar-left {
position: fixed;
left: 0;
top: 60px;
width: 90px;
padding-top: 20px;
border-right: 1px solid rgba(162, 162, 162, 0.2);
height: auto;
bottom: 0;
z-index: 2;
background-color: $white;
ul.menubar {
// padding-bottom: 60px;
li.menu-item {
padding: 10px 5px;
font-size: 11px;
text-align: center;
text-transform: uppercase;
a {
color: $link-color;
}
&.active {
a {
color: #0041ff;
}
}
span {
display: block;
margin: auto;
}
}
}
}
.content-container {
padding-left: 90px;
position: absolute;
margin-top: 60px;
top: 0px;
right: 0;
left: 0;
bottom: 0px;
height: calc(100% - 60px);
width: 100%;
.inner-section {
height: 100%;
}
.aside-nav {
width: 280px;
position: fixed;
top: 60px;
bottom: 0;
border-right: 1px solid $border-color;
background-color: $background-color;
padding-top: 10px;
padding-bottom: 10px;
z-index: 4;
ul {
overflow-y: auto;
height: 90%;
}
a {
padding: 15px;
display: block;
color: #000311;
}
.active {
a {
background: $white;
border-top: 1px solid $border-color;
border-bottom: 1px solid $border-color;
}
i {
float: right;
}
}
}
.content-wrapper {
padding: 25px 25px 25px 15px;
margin-left: 280px;
margin-top:1px;
background-color: $white;
}
.content {
margin-top: 25px;
&.full-page {
padding: 25px;
}
.page-header {
display: inline-block;
width: 100%;
padding: 15px 10px 15px 0px;
position: sticky;
top: 50px;
z-index: 3;
background-color: $white;
.page-title {
float: left;
.back-link {
float: left;
margin-right: 10px;
width: 24px;
height: 24px;
cursor: pointer;
margin-top: 5px;
}
h1 {
margin-bottom: 0;
vertical-align: middle;
display: inline-block;
line-height: initial;
}
}
.page-action {
float: right;
* {
display: inline-block;
}
a {
margin-left: 25px;
}
}
.control-group {
width: 180px;
display: inline-block;
margin-bottom: 0;
margin-left: 20px;
}
.control {
width: 100%;
margin: 0;
}
}
.page-content {
width: 100%;
display: inline-block;
}
}
}
.control-container {
display: flex;
flex-direction: row;
align-items: flex-start;
width: 750px;
.control {
background: $white;
border: 2px solid #c7c7c7;
@include border-radius(3px);
width: 150px;
height: 36px;
display: inline-block;
vertical-align: middle;
transition: 0.2s cubic-bezier(0.4, 0, 0.2, 1);
padding: 0px 10px;
font-size: 15px;
&:focus {
border-color: #0041ff;
}
}
.icon:hover {
cursor: pointer;
}
.control-group::last-child {
margin-right: 0px;
}
}
.boolean-control-container {
display: flex;
flex-direction: row;
justify-content: flex-start;
width: 750px;
.control-group {
width: 200px;
}
}
.control-group {
label {
width: 70%;
.locale {
float: right;
color: #8e8e8e;
}
}
.mce-tinymce {
margin-top: 10px;
margin-bottom: 5px;
}
}

View File

@ -0,0 +1,241 @@
.rtl {
direction: rtl;
.navbar-top {
.navbar-top-right {
text-align: left;
.profile-info {
margin: 0 30px 0 25px;
i.icon {
margin-left: 0px;
margin-right: 10px;
}
}
}
}
.navbar-left {
border-left: 1px solid rgba(162, 162, 162, 0.2);
border-right: none;
left: calc(100% - 90px);
background-color: $white;
}
.content-container {
padding-right: 90px;
padding-left: 0px;
.content .page-header {
.page-title {
float: right;
}
.page-action {
float: left;
a {
margin-left: 0px;
}
}
.control-group {
margin-right: 20px;
margin-left: 0px;
}
.control-group.date {
&::after {
margin-top: 6px;
position: absolute;
margin-right: -35px;
}
&:last-child {
margin-left: 0px;
}
}
}
.content-wrapper {
padding: 25px 305px 25px 25px;
margin-left: 0px;
}
.aside-nav .active i {
float: left;
transform: rotate(180deg);
}
}
.dashboard {
.dashboard-stats .dashboard-card .data span {
float: left;
}
.card {
padding: 20px 20px 0px 0px;
.card-info ul li {
.image {
float: right;
margin-right: 0px;
margin-left: 15px;
}
.icon.angle-right-icon {
left: 30px;
right: auto;
transform: rotate(180deg);
}
}
}
.graph-stats {
.left-card-container {
float: right;
padding-right: 0px;
}
.right-card-container {
float: right;
padding-left: 0px;
padding-right: 30px;
}
}
}
.sale-container .sale-summary {
float: left;
}
// ui
.grid-container {
.filter-row-one .search-filter {
border: 2px solid #c7c7c7;
border-radius: 2px;
.control {
border: none;
padding-right: 10px;
}
.icon-wrapper {
border: none;
padding-top: 2px;
padding-right: 5px;
border-right: 2px solid #c7c7c7;
border-radius: 0px;
}
}
.filter-row-two .filter-tag {
.wrapper,
.icon.cross-icon {
margin-right: 10px;
margin-left: 0px;
}
}
.filter-row-one .dropdown-filters {
right: unset;
left: 25px;
}
}
.grid-container
.filter-wrapper
.filter-row-one
.dropdown-filters
.more-filters
.dropdown-toggle
.dropdown-header
span {
padding-right: 5px;
}
.grid-container .table tbody td.action a:first-child {
margin-left: 10px;
margin-right: 0px;
}
.table table {
text-align: right;
.massaction-remove {
margin-right: 5px !important;
margin-left: 10px;
}
.btn.btn-primary {
margin-right: 10px !important;
}
}
.dropdown-list.bottom-right {
left: 0px;
right: auto;
}
.dropdown-list .dropdown-container {
text-align: right;
}
.accordian .accordian-header .icon {
float: left;
}
.tree-container .tree-item {
padding-right: 30px;
.expand-icon,
.folder-icon {
margin-left: 10px;
margin-right: 0px;
}
}
.tree-container > .tree-item {
padding-right: 0px;
}
.radio .radio-view {
margin-left: 5px;
}
.image-wrapper .image-item {
margin-right: 0px;
margin-left: 20px;
.remove-image {
margin-right: 0px;
}
}
.control-group label.required::before {
content: "*";
color: #fc6868;
font-weight: 700;
}
.control-group label.required::after {
content: none;
}
.control-group label .locale {
float: left;
}
.control-group.date {
&::after {
margin-top: 15px;
position: absolute;
margin-right: -35px;
}
}
.pagination .page-item .icon {
transform: rotate(180deg);
}
}

View File

@ -0,0 +1,97 @@
.sale-container {
.sale-section {
font-size: 16px;
.secton-title {
font-size: 18px;
color: #8e8e8e;
padding: 15px 0;
border-bottom: 1px solid $border-color;
}
.section-content {
display: block;
padding: 20px 0;
.row {
display: block;
padding: 7px 0;
.title {
width: 200px;
color: $font-color;
letter-spacing: -0.26px;
display: inline-block;
}
.value {
color: $font-color;
letter-spacing: -0.26px;
display: inline-block;
}
}
}
}
.table {
.qty-row {
display: block;
margin-bottom: 5px;
&:last-child {
margin-bottom: 0;
}
}
.radio {
margin: 0;
}
}
.sale-summary {
margin-top: 2%;
height: 130px;
float: right;
tr {
td {
padding: 5px 8px;
vertical-align: text-bottom;
}
&.bold {
font-weight: 600;
font-size: 15px;
}
&.border {
td {
border-bottom: 1px solid $border-color;
}
}
}
}
}
.stars {
margin-top: 5px;
.icon {
width: 16px;
height: 16px;
}
}
.export-import {
cursor: pointer;
.export-icon,
.import-icon {
position: relative;
top: 10px;
}
span {
margin-left: 2px;
}
}

View File

@ -0,0 +1,33 @@
// Accordion
.accordian-header {
background-color: $accordian-header;
}
// buttons
.btn.btn-primary{
background: $btn-primary-bg;
}
.fixed-action {
position: fixed;
top: 108px;
right: 32px;
z-index: 20;
}
.fixed-action-slight {
position: fixed;
top: 94px;
right: 32px;
z-index: 20;
}
.pagination {
margin-top: 30px;
}
// temporary fix untill the cause of the scrolling has been resolved.
.table {
overflow-x: hidden !important;
}

View File

@ -8,6 +8,7 @@ return [
'true' => 'صحيح',
'false' => 'خطأ'
],
'layouts' => [
'my-account' => 'حسابي',
'logout' => 'خروج',
@ -40,6 +41,7 @@ return [
'tax-categories' => 'فئات الضرائب',
'tax-rates' => 'المعدلات الضريبية'
],
'acl' => [
'dashboard' => 'لوحة العدادات',
'sales' => 'المبيعات',
@ -72,6 +74,7 @@ return [
'create' => 'Add',
'delete' => 'Delete',
],
'dashboard' => [
'title' => 'لوحة العدادات',
'from' => 'من',
@ -93,6 +96,7 @@ return [
'stock-threshold' => 'عتبة المخزون',
'qty-left' => ':qty يسار',
],
'datagrid' => [
'mass-ops' => [
'method-error' => 'خطأ! تم اكتشاف طريقة خاطئة ، الرجاء التحقق من تشكيل حركة الكتلة',
@ -146,7 +150,9 @@ return [
'role' => 'الدور',
'sub-total' => 'المجموع الفرعي',
'no-of-products' => 'عدد المنتجات',
'refunded' => 'Refunded'
],
'account' => [
'title' => 'حسابي',
'save-btn-title' => 'احفظ',
@ -158,6 +164,7 @@ return [
'change-password' => 'غير كلمة سر الحساب',
'current-password' => 'Current Password'
],
'users' => [
'forget-password' => [
'title' => 'انس كلمة السر',
@ -224,6 +231,7 @@ return [
'submit-btn-title' => 'وقع هنا'
]
],
'sales' => [
'orders' => [
'title' => 'الأوامر',
@ -262,6 +270,7 @@ return [
'item-invoice' => '3-الفواتير (:qty_invoiced)',
'item-shipped' => 'شحنت (:qty_shipped)',
'item-canceled' => 'ملغاة (:qty_canceled)',
'item-refunded' => 'Refunded (:qty_refunded)',
'price' => 'Price',
'total' => 'المجموع',
'subtotal' => 'المجموع الفرعي',
@ -276,7 +285,9 @@ return [
'total-paid' => 'المجموع المدفوع',
'total-refunded' => 'مجموع المبالغ المستردة',
'total-due' => 'المجموع المستحق',
'cancel-confirm-msg' => 'هل أنت متأكد من أنك تريد إلغاء هذا الطلب ؟'
'cancel-confirm-msg' => 'هل أنت متأكد من أنك تريد إلغاء هذا الطلب ؟',
'refunds' => 'Refunds',
'refunded' => 'Refunded'
],
'invoices' => [
'title' => 'الفواتير',
@ -301,6 +312,7 @@ return [
'creation-error' => 'لا يسمح بإنشاء الفواتير.',
'product-error' => 'ولا يمكن إعداد الفاتورة بدون منتجات.'
],
'shipments' => [
'title' => 'الشحنات',
'id' => 'Id',
@ -325,8 +337,32 @@ return [
'creation-error' => 'لا يمكن إنشاء الشحنة لهذا الطلب.',
'order-error' => 'لا يسمح بإنشاء شحنة الطلب.',
'quantity-invalid' => 'الكمية المطلوبة غير صالحة أو غير متاحة.',
],
'refunds' => [
'title' => 'Refunds',
'id' => 'Id',
'add-title' => 'Create Refund',
'save-btn-title' => 'Refund',
'order-id' => 'Order Id',
'qty-ordered' => 'Qty Ordered',
'qty-to-refund' => 'Qty To Refund',
'refund-shipping' => 'Refund Shipping',
'adjustment-refund' => 'Adjustment Refund',
'adjustment-fee' => 'Adjustment Fee',
'update-qty' => 'Update Quantities',
'invalid-qty' => 'Found invalid quantity for return items.',
'refund-limit-error' => 'The most money available to refund is :amount.',
'refunded' => 'Refunded',
'date' => 'Refund Date',
'customer-name' => 'Customer Name',
'status' => 'Status',
'action' => 'Action',
'view-title' => 'Refund #:refund_id',
'invalid-refund-amount-error' => 'Refund amount should be non zero.'
]
],
'catalog' => [
'products' => [
'title' => 'المنتجات',
@ -480,6 +516,7 @@ return [
'image' => 'Image',
]
],
'configuration' => [
'title' => 'إعدادات',
'save-btn-title' => 'احفظ',
@ -534,6 +571,7 @@ return [
]
]
],
'settings' => [
'locales' => [
'title' => 'Locales',
@ -689,6 +727,7 @@ return [
'atleast-one' => 'لا يستطيع حذف الأخير ضريبة معدل'
]
],
'customers' => [
'groups' =>[
'add-title' => 'أضف المجموعة',
@ -744,6 +783,7 @@ return [
'delete-failed' => 'خطأ! المشترك لا يمكن حذفه'
]
],
'error' => [
'go-to-home' => 'إذهب إلى البيت',
'in-maitainace' => 'In Maintenance',
@ -774,6 +814,7 @@ return [
'message' => 'ولم يطبق الطلب لأنه يفتقر إلى وثائق إثبات صحيحة للمورد المستهدف.'
],
],
'export' => [
'export' => 'صدر',
'import' => 'استيراد',
@ -786,6 +827,7 @@ return [
'upload-error' => 'الملف يجب أن يكون ملف من نوع: xls, xlsx, csv.',
'duplicate-error' => 'معرف يجب أن يكون فريد ، معرف مكرر :identifier at row :position.'
],
'response' => [
'create-success' => ':name created successfully.',
'update-success' => ':name updated successfully.',
@ -803,7 +845,68 @@ return [
'cancel-error' => ':name can not be canceled.',
'already-taken' => 'The :name has already been taken.'
],
'footer' => [
'copy-right' => '© Copyright 2018 Webkul Software, All rights reserved.'
],
'admin' => [
'system' => [
'catalog' => 'Catalog',
'products' => 'Products',
'review' => 'Review',
'allow-guest-review' => 'Allow Guest Review',
'inventory' => 'Inventory',
'stock-options' => 'Stock Options',
'allow-backorders' => 'Allow Backorders',
'customer' => 'Customer',
'settings' => 'Settings',
'address' => 'Address',
'street-lines' => 'Lines in a Street Address',
'sales' => 'Sales',
'shipping-methods' => 'Shipping Methods',
'free-shipping' => 'Free Shipping',
'flate-rate-shipping' => 'Flat Rate Shipping',
'shipping' => 'Shipping',
'origin' => 'Origin',
'country' => 'Country',
'state' => 'State',
'zip' => 'Zip',
'city' => 'City',
'street-address' => 'Street Address',
'title' => 'Title',
'description' => 'Description',
'rate' => 'Rate',
'status' => 'Status',
'type' => 'Type',
'payment-methods' => 'Payment Methods',
'cash-on-delivery' => 'Cash On Delivery',
'money-transfer' => 'Money Transfer',
'paypal-standard' => 'Paypal Standard',
'business-account' => 'Business Account',
'newsletter' => 'NewsLetter Subscription',
'newsletter-subscription' => 'Allow NewsLetter Subscription',
'email' => 'Email Verification',
'email-verification' => 'Allow Email Verification',
'sort_order' => 'Sort Order',
'general' => 'General',
'footer' => 'Footer',
'content' => 'Content',
'footer-content' => 'Footer Text',
'locale-options' => 'Unit Options',
'weight-unit' => 'Weight Unit',
'design' => 'Design',
'admin-logo' => 'Admin Logo',
'logo-image' => 'Logo Image',
'credit-max' => 'Customer Credit Max',
'credit-max-value' => 'Credit Max Value',
'use-credit-max' => 'Use Credit Max',
'order-settings' => 'Order Settings',
'orderNumber' => 'Order Number Settings',
'order-number-prefix' => 'Order Number Prefix',
'order-number-length' => 'Order Number Length',
'order-number-suffix' => 'Order Number Suffix',
'default' => 'Default',
]
]
];

View File

@ -31,6 +31,7 @@ return [
'channel-based' => 'Channel based',
'status' => 'Status',
'select-option' => 'Select option',
'category' => 'Category',
'common' => [
'no-result-found' => 'We could not find any records.',
@ -49,6 +50,7 @@ return [
'orders' => 'Orders',
'shipments' => 'Shipments',
'invoices' => 'Invoices',
'refunds' => 'Refunds',
'catalog' => 'Catalog',
'products' => 'Products',
'categories' => 'Categories',
@ -130,7 +132,7 @@ return [
'order-count' => ':count Orders',
'revenue' => 'Revenue :total',
'stock-threshold' => 'Stock Threshold',
'qty-left' => ':qty Left',
'qty-left' => ':qty Left'
],
'datagrid' => [
@ -196,7 +198,10 @@ return [
'ends-till' => 'Ends Till',
'per-cust' => 'Per Customer',
'usage-throttle' => 'Usage Times',
'for-guest' => 'For Guest'
'for-guest' => 'For Guest',
'order_number' => 'Order Number',
'refund-date' => 'Refund Date',
'refunded' => 'Refunded'
],
'account' => [
@ -319,6 +324,7 @@ return [
'item-invoice' => 'Invoiced (:qty_invoiced)',
'item-shipped' => 'shipped (:qty_shipped)',
'item-canceled' => 'Canceled (:qty_canceled)',
'item-refunded' => 'Refunded (:qty_refunded)',
'price' => 'Price',
'total' => 'Total',
'subtotal' => 'Subtotal',
@ -333,7 +339,9 @@ return [
'total-paid' => 'Total Paid',
'total-refunded' => 'Total Refunded',
'total-due' => 'Total Due',
'cancel-confirm-msg' => 'Are you sure you want to cancel this order ?'
'cancel-confirm-msg' => 'Are you sure you want to cancel this order ?',
'refund-btn-title' => 'Refund',
'refunds' => 'Refunds'
],
'invoices' => [
@ -384,6 +392,30 @@ return [
'creation-error' => 'Shipment can not be created for this order.',
'order-error' => 'Order shipment creation is not allowed.',
'quantity-invalid' => 'Requested quantity is invalid or not available.',
],
'refunds' => [
'title' => 'Refunds',
'id' => 'Id',
'add-title' => 'Create Refund',
'save-btn-title' => 'Refund',
'order-id' => 'Order Id',
'qty-ordered' => 'Qty Ordered',
'qty-to-refund' => 'Qty To Refund',
'refund-shipping' => 'Refund Shipping',
'adjustment-refund' => 'Adjustment Refund',
'adjustment-fee' => 'Adjustment Fee',
'update-qty' => 'Update Quantities',
'invalid-qty' => 'Found invalid quantity for return items.',
'refund-limit-error' => 'The most money available to refund is :amount.',
'refunded' => 'Refunded',
'date' => 'Refund Date',
'customer-name' => 'Customer Name',
'status' => 'Status',
'action' => 'Action',
'view-title' => 'Refund #:refund_id',
'invalid-refund-amount-error' => 'Refund amount should be non zero.'
]
],
@ -1149,6 +1181,7 @@ return [
'footer' => 'Footer',
'content' => 'Content',
'footer-content' => 'Footer Text',
'footer-toggle' => 'Toggle footer',
'locale-options' => 'Unit Options',
'weight-unit' => 'Weight Unit',
'design' => 'Design',
@ -1156,7 +1189,13 @@ return [
'logo-image' => 'Logo Image',
'credit-max' => 'Customer Credit Max',
'credit-max-value' => 'Credit Max Value',
'use-credit-max' => 'Use Credit Max'
'use-credit-max' => 'Use Credit Max',
'order-settings' => 'Order Settings',
'orderNumber' => 'Order Number Settings',
'order-number-prefix' => 'Order Number Prefix',
'order-number-length' => 'Order Number Length',
'order-number-suffix' => 'Order Number Suffix',
'default' => 'Default',
]
]
];

View File

@ -166,7 +166,8 @@ return [
'action_type' => 'نوع عملیات',
'disc_quantity' => 'مقدار استفاده نشده',
'disc_threshold' => 'آستانه استفاده نشده',
'use_coupon' => 'استافده از کوپن'
'use_coupon' => 'استافده از کوپن',
'refunded' => 'Refunded'
],
'account' => [
@ -289,6 +290,7 @@ return [
'item-invoice' => 'صورت حساب (:qty_invoiced)',
'item-shipped' => 'حمل شده (:qty_shipped)',
'item-canceled' => 'لغو شده (:qty_canceled)',
'item-refunded' => 'Refunded (:qty_refunded)',
'price' => 'قیمت',
'total' => 'کل',
'subtotal' => 'فرعی',
@ -302,7 +304,9 @@ return [
'total-paid' => 'کل پرداخت شده',
'total-refunded' => 'بازپرداخت کل',
'total-due' => 'بدهی کل',
'cancel-confirm-msg' => 'مطمئن هستید که می خواهید این سفارش را لغو کنید ؟'
'cancel-confirm-msg' => 'مطمئن هستید که می خواهید این سفارش را لغو کنید ؟',
'refunds' => 'Refunds',
'refunded' => 'Refunded'
],
'invoices' => [
@ -353,6 +357,29 @@ return [
'creation-error' => 'حمل و نقل برای این سفارش ایجاد نمی شود.',
'order-error' => 'ایجاد محموله سفارش مجاز نیست.',
'quantity-invalid' => 'مقدار درخواستی نامعتبر است یا در دسترس نیست.',
],
'refunds' => [
'title' => 'Refunds',
'id' => 'Id',
'add-title' => 'Create Refund',
'save-btn-title' => 'Refund',
'order-id' => 'Order Id',
'qty-ordered' => 'Qty Ordered',
'qty-to-refund' => 'Qty To Refund',
'refund-shipping' => 'Refund Shipping',
'adjustment-refund' => 'Adjustment Refund',
'adjustment-fee' => 'Adjustment Fee',
'update-qty' => 'Update Quantities',
'invalid-qty' => 'Found invalid quantity for return items.',
'refund-limit-error' => 'The most money available to refund is :amount.',
'refunded' => 'Refunded',
'date' => 'Refund Date',
'customer-name' => 'Customer Name',
'status' => 'Status',
'action' => 'Action',
'view-title' => 'Refund #:refund_id',
'invalid-refund-amount-error' => 'Refund amount should be non zero.'
]
],

View File

@ -154,7 +154,8 @@ return [
'ends-till' => 'Termina Até',
'per-cust' => 'Por cliente',
'usage-throttle' => 'Tempos de uso',
'for-guest' => 'Para convidados'
'for-guest' => 'Para convidados',
'refunded' => 'Refunded'
],
'account' => [
'title' => 'Minha Conta',
@ -270,6 +271,7 @@ return [
'item-invoice' => 'Faturado(s) (:qty_invoiced)',
'item-shipped' => 'Enviado(s) (:qty_shipped)',
'item-canceled' => 'Cancelado(s) (:qty_canceled)',
'item-refunded' => 'Refunded (:qty_refunded)',
'price' => 'Preço',
'total' => 'Total',
'subtotal' => 'Subtotal',
@ -284,7 +286,9 @@ return [
'total-paid' => 'Total Pago',
'total-refunded' => 'Total Estornado',
'total-due' => 'Total Devido',
'cancel-confirm-msg' => 'Tem certeza que deseja cancelar esse pedido ?'
'cancel-confirm-msg' => 'Tem certeza que deseja cancelar esse pedido ?',
'refunds' => 'Refunds',
'refunded' => 'Refunded'
],
'invoices' => [
'title' => 'Faturas',
@ -309,6 +313,7 @@ return [
'creation-error' => 'A criação de fatura de pedido não é permitida.',
'product-error' => 'A fatura não pode ser criada sem produtos.'
],
'shipments' => [
'title' => 'Entregas',
'id' => 'Id',
@ -333,6 +338,29 @@ return [
'creation-error' => 'A expedição não pode ser criada para este pedido.',
'order-error' => 'A criação de remessa de pedidos não é permitida.',
'quantity-invalid' => 'A quantidade solicitada é inválida ou não está disponível.'
],
'refunds' => [
'title' => 'Refunds',
'id' => 'Id',
'add-title' => 'Create Refund',
'save-btn-title' => 'Refund',
'order-id' => 'Order Id',
'qty-ordered' => 'Qty Ordered',
'qty-to-refund' => 'Qty To Refund',
'refund-shipping' => 'Refund Shipping',
'adjustment-refund' => 'Adjustment Refund',
'adjustment-fee' => 'Adjustment Fee',
'update-qty' => 'Update Quantities',
'invalid-qty' => 'Found invalid quantity for return items.',
'refund-limit-error' => 'The most money available to refund is :amount.',
'refunded' => 'Refunded',
'date' => 'Refund Date',
'customer-name' => 'Customer Name',
'status' => 'Status',
'action' => 'Action',
'view-title' => 'Refund #:refund_id',
'invalid-refund-amount-error' => 'Refund amount should be non zero.'
]
],
'catalog' => [
@ -998,7 +1026,12 @@ return [
'logo-image' => 'Logo Imagem',
'credit-max' => 'Máximo de crédito do cliente',
'credit-max-value' => 'Valor Máximo de Crédito',
'use-credit-max' => 'Use o máximo de crédito'
'use-credit-max' => 'Use o máximo de crédito',
'order-settings' => 'Order Settings',
'orderNumber' => 'Order Number Settings',
'order-number-prefix' => 'Order Number Prefix',
'order-number-length' => 'Order Number Length',
'order-number-suffix' => 'Order Number Suffix',
]
]
];

View File

@ -20,7 +20,7 @@
<div class="page-action">
<button type="submit" class="btn btn-lg btn-primary">
{{ __('admin::app.catalog.categories-btn-title') }}
{{ __('admin::app.save') }} {{ __('admin::app.category') }}
</button>
</div>
</div>

View File

@ -73,7 +73,7 @@
:validations = "'{{ $validations }}'"
:depend = "'{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $dependField }}]'"
:value = "'{{ $dependValue }}'"
:field_name = "'{{ $field['title'] }}'"
:field_name = "'{{ trans($field['title']) }}'"
:channel_locale = "'{{ $channel_locale }}'"
:result = "'{{ $selectedOption }}'"
></depends>

View File

@ -78,17 +78,6 @@
@endforeach
</select>
</div>
<div class="control-group" :class="[errors.has('channel_id') ? 'has-error' : '']">
<label for="channel" >{{ __('admin::app.customers.customers.channel_name') }}</label>
<select class="control" name="channel_id" v-validate="'required'" data-vv-as="&quot;{{ __('shop::app.customers.customers.channel_name') }}&quot;">
@foreach ($channelName as $channel)
<option value="{{ $channel->id }}"> {{ $channel->name}} </>
@endforeach
</select>
<span class="control-error" v-if="errors.has('channel_id')">@{{ errors.first('channel_id') }}</span>
</div>
</div>
</div>
</form>

View File

@ -102,26 +102,6 @@
@endforeach
</select>
</div>
<div class="control-group" :class="[errors.has('channel_id') ? 'has-error' : '']">
<label for="channel" >{{ __('admin::app.customers.customers.channel_name') }}</label>
@if (! is_null($customer->channel_id))
<?php $selectedChannelOption = $customer->channel_id ?>
@else
<?php $selectedChannelOption = $customer->channel_id ?>
@endif
<select class="control" name="channel_id" v-validate="'required'" data-vv-as="&quot;{{ __('shop::app.customers.customers.channel_name') }}&quot;">
@foreach ($channelName as $channel)
<option value="{{ $channel->id }}" {{ $selectedChannelOption == $channel->id ? 'selected' : '' }}>
{{ $channel->name}}
</option>
@endforeach
</select>
<span class="control-error" v-if="errors.has('channel_id')">@{{ errors.first('channel_id') }}</span>
</div>
</div>
</accordian>

View File

@ -164,7 +164,7 @@
<div class="info">
{{ __('admin::app.dashboard.product-count', ['count' => $item->total_products]) }}
&nbsp;.&nbsp;
{{ __('admin::app.dashboard.sale-count', ['count' => $item->total_qty_ordered]) }}
{{ __('admin::app.dashboard.sale-count', ['count' => $item->total_qty_invoiced]) }}
</div>
</div>
@ -221,7 +221,7 @@
</div>
<div class="info">
{{ __('admin::app.dashboard.sale-count', ['count' => $item->total_qty_ordered]) }}
{{ __('admin::app.dashboard.sale-count', ['count' => $item->total_qty_invoiced]) }}
</div>
</div>
@ -274,7 +274,7 @@
{{ __('admin::app.dashboard.order-count', ['count' => $item->total_orders]) }}
&nbsp;.&nbsp;
{{ __('admin::app.dashboard.revenue', [
'total' => core()->formatBasePrice($item->total_base_grand_total)
'total' => core()->formatBasePrice($item->total_base_grand_total_invoiced)
])
}}
</div>

View File

@ -90,16 +90,17 @@
{!! view_render_event('bagisto.admin.layout.content.after') !!}
<div class="footer">
<p>
@if (core()->getConfigData('general.content.footer.footer_content'))
{{ core()->getConfigData('general.content.footer.footer_content') }}
@else
{{ trans('admin::app.footer.copy-right') }}
@endif
</p>
</div>
@if (core()->getConfigData('general.content.footer.footer_toggle'))
<div class="footer">
<p style="text-align: center;">
@if (core()->getConfigData('general.content.footer.footer_content'))
{{ core()->getConfigData('general.content.footer.footer_content') }}
@else
{{ trans('admin::app.footer.copy-right') }}
@endif
</p>
</div>
@endif
</div>
</div>

View File

@ -8,8 +8,8 @@
<meta name="csrf-token" content="{{ csrf_token() }}">
<link rel="icon" sizes="16x16" href="{{ asset('vendor/webkul/ui/assets/images/favicon.ico') }}" />
<link rel="stylesheet" href="{{ asset('vendor/webkul/admin/assets/css/admin.css') }}">
<link rel="stylesheet" href="{{ asset('vendor/webkul/ui/assets/css/ui.css') }}">
<link rel="stylesheet" href="{{ asset('vendor/webkul/admin/assets/css/admin.css') }}">
@yield('head')

View File

@ -43,7 +43,7 @@
</span>
<span class="value">
<a href="{{ route('admin.sales.orders.view', $order->id) }}">#{{ $order->id }}</a>
<a href="{{ route('admin.sales.orders.view', $order->id) }}">#{{ $order->increment_id }}</a>
</span>
</div>

View File

@ -90,7 +90,7 @@
<div class="row">
<span class="label">{{ __('admin::app.sales.invoices.order-id') }} -</span>
<span class="value">#{{ $invoice->order_id }}</span>
<span class="value">#{{ $invoice->order->increment_id }}</span>
</div>
<div class="row">

View File

@ -43,7 +43,7 @@
</span>
<span class="value">
<a href="{{ route('admin.sales.orders.view', $order->id) }}">#{{ $order->id }}</a>
<a href="{{ route('admin.sales.orders.view', $order->id) }}">#{{ $order->increment_id }}</a>
</span>
</div>
@ -288,7 +288,7 @@
<tr>
<td>{{ __('admin::app.sales.orders.discount') }}</td>
<td>-</td>
<td>-{{ core()->formatBasePrice($invoice->base_discount_amount) }}</td>
<td>{{ core()->formatBasePrice($invoice->base_discount_amount) }}</td>
</tr>
@endif

View File

@ -1,7 +1,7 @@
@extends('admin::layouts.master')
@section('page_title')
{{ __('admin::app.sales.orders.view-title', ['order_id' => $order->id]) }}
{{ __('admin::app.sales.orders.view-title', ['order_id' => $order->increment_id]) }}
@stop
@section('content-wrapper')
@ -14,7 +14,7 @@
<h1>
<i class="icon angle-left-icon back-link" onclick="history.length > 1 ? history.go(-1) : window.location = '{{ url('/admin/dashboard') }}';"></i>
{{ __('admin::app.sales.orders.view-title', ['order_id' => $order->id]) }}
{{ __('admin::app.sales.orders.view-title', ['order_id' => $order->increment_id]) }}
</h1>
</div>
@ -31,6 +31,12 @@
</a>
@endif
@if ($order->canRefund())
<a href="{{ route('admin.sales.refunds.create', $order->id) }}" class="btn btn-lg btn-primary">
{{ __('admin::app.sales.orders.refund-btn-title') }}
</a>
@endif
@if ($order->canShip())
<a href="{{ route('admin.sales.shipments.create', $order->id) }}" class="btn btn-lg btn-primary">
{{ __('admin::app.sales.orders.shipment-btn-title') }}
@ -282,6 +288,10 @@
{{ $item->qty_shipped ? __('admin::app.sales.orders.item-shipped', ['qty_shipped' => $item->qty_shipped]) : '' }}
</span>
<span class="qty-row">
{{ $item->qty_refunded ? __('admin::app.sales.orders.item-refunded', ['qty_refunded' => $item->qty_refunded]) : '' }}
</span>
<span class="qty-row">
{{ $item->qty_canceled ? __('admin::app.sales.orders.item-canceled', ['qty_canceled' => $item->qty_canceled]) : '' }}
</span>
@ -322,7 +332,7 @@
<tr>
<td>{{ __('admin::app.sales.orders.discount') }}</td>
<td>-</td>
<td>-{{ core()->formatBasePrice($order->base_discount_amount) }}</td>
<td>{{ core()->formatBasePrice($order->base_discount_amount) }}</td>
</tr>
@endif
@ -385,7 +395,7 @@
<tr>
<td>#{{ $invoice->id }}</td>
<td>{{ $invoice->created_at }}</td>
<td>#{{ $invoice->order->id }}</td>
<td>#{{ $invoice->order->increment_id }}</td>
<td>{{ $invoice->address->name }}</td>
<td>{{ $invoice->status_label }}</td>
<td>{{ core()->formatBasePrice($invoice->base_grand_total) }}</td>
@ -452,6 +462,50 @@
</tab>
@endif
<tab name="{{ __('admin::app.sales.orders.refunds') }}">
<div class="table" style="padding: 20px 0">
<table>
<thead>
<tr>
<th>{{ __('admin::app.sales.refunds.id') }}</th>
<th>{{ __('admin::app.sales.refunds.date') }}</th>
<th>{{ __('admin::app.sales.refunds.order-id') }}</th>
<th>{{ __('admin::app.sales.refunds.customer-name') }}</th>
<th>{{ __('admin::app.sales.refunds.status') }}</th>
<th>{{ __('admin::app.sales.refunds.refunded') }}</th>
<th>{{ __('admin::app.sales.refunds.action') }}</th>
</tr>
</thead>
<tbody>
@foreach ($order->refunds as $refund)
<tr>
<td>#{{ $refund->id }}</td>
<td>{{ $refund->created_at }}</td>
<td>#{{ $refund->order->increment_id }}</td>
<td>{{ $refund->order->customer_full_name }}</td>
<td>{{ __('admin::app.sales.refunds.refunded') }}</td>
<td>{{ core()->formatBasePrice($refund->base_grand_total) }}</td>
<td class="action">
<a href="{{ route('admin.sales.refunds.view', $refund->id) }}">
<i class="icon eye-icon"></i>
</a>
</td>
</tr>
@endforeach
@if (! $order->refunds->count())
<tr>
<td class="empty" colspan="7">{{ __('admin::app.common.no-result-found') }}</td>
<tr>
@endif
</table>
</div>
</tab>
</tabs>
</div>

View File

@ -0,0 +1,427 @@
@extends('admin::layouts.master')
@section('page_title')
{{ __('admin::app.sales.refunds.add-title') }}
@stop
@section('content-wrapper')
<div class="content full-page">
<form method="POST" action="{{ route('admin.sales.refunds.store', $order->id) }}" @submit.prevent="onSubmit">
@csrf()
<div class="page-header">
<div class="page-title">
<h1>
<i class="icon angle-left-icon back-link" onclick="history.length > 1 ? history.go(-1) : window.location = '{{ url('/admin/dashboard') }}';"></i>
{{ __('admin::app.sales.refunds.add-title') }}
</h1>
</div>
<div class="page-action">
<button type="submit" class="btn btn-lg btn-primary">
{{ __('admin::app.sales.refunds.save-btn-title') }}
</button>
</div>
</div>
<div class="page-content">
<div class="sale-container">
<accordian :title="'{{ __('admin::app.sales.orders.order-and-account') }}'" :active="true">
<div slot="body">
<div class="sale-section">
<div class="secton-title">
<span>{{ __('admin::app.sales.orders.order-info') }}</span>
</div>
<div class="section-content">
<div class="row">
<span class="title">
{{ __('admin::app.sales.refunds.order-id') }}
</span>
<span class="value">
<a href="{{ route('admin.sales.orders.view', $order->id) }}">#{{ $order->increment_id }}</a>
</span>
</div>
<div class="row">
<span class="title">
{{ __('admin::app.sales.orders.order-date') }}
</span>
<span class="value">
{{ $order->created_at }}
</span>
</div>
<div class="row">
<span class="title">
{{ __('admin::app.sales.orders.order-status') }}
</span>
<span class="value">
{{ $order->status_label }}
</span>
</div>
<div class="row">
<span class="title">
{{ __('admin::app.sales.orders.channel') }}
</span>
<span class="value">
{{ $order->channel_name }}
</span>
</div>
</div>
</div>
<div class="sale-section">
<div class="secton-title">
<span>{{ __('admin::app.sales.orders.account-info') }}</span>
</div>
<div class="section-content">
<div class="row">
<span class="title">
{{ __('admin::app.sales.orders.customer-name') }}
</span>
<span class="value">
{{ $order->customer_full_name }}
</span>
</div>
<div class="row">
<span class="title">
{{ __('admin::app.sales.orders.email') }}
</span>
<span class="value">
{{ $order->customer_email }}
</span>
</div>
</div>
</div>
</div>
</accordian>
<accordian :title="'{{ __('admin::app.sales.orders.address') }}'" :active="true">
<div slot="body">
<div class="sale-section">
<div class="secton-title">
<span>{{ __('admin::app.sales.orders.billing-address') }}</span>
</div>
<div class="section-content">
@include ('admin::sales.address', ['address' => $order->billing_address])
</div>
</div>
@if ($order->shipping_address)
<div class="sale-section">
<div class="secton-title">
<span>{{ __('admin::app.sales.orders.shipping-address') }}</span>
</div>
<div class="section-content">
@include ('admin::sales.address', ['address' => $order->shipping_address])
</div>
</div>
@endif
</div>
</accordian>
<accordian :title="'{{ __('admin::app.sales.orders.payment-and-shipping') }}'" :active="true">
<div slot="body">
<div class="sale-section">
<div class="secton-title">
<span>{{ __('admin::app.sales.orders.payment-info') }}</span>
</div>
<div class="section-content">
<div class="row">
<span class="title">
{{ __('admin::app.sales.orders.payment-method') }}
</span>
<span class="value">
{{ core()->getConfigData('sales.paymentmethods.' . $order->payment->method . '.title') }}
</span>
</div>
<div class="row">
<span class="title">
{{ __('admin::app.sales.orders.currency') }}
</span>
<span class="value">
{{ $order->order_currency_code }}
</span>
</div>
</div>
</div>
<div class="sale-section">
<div class="secton-title">
<span>{{ __('admin::app.sales.orders.shipping-info') }}</span>
</div>
<div class="section-content">
<div class="row">
<span class="title">
{{ __('admin::app.sales.orders.shipping-method') }}
</span>
<span class="value">
{{ $order->shipping_title }}
</span>
</div>
<div class="row">
<span class="title">
{{ __('admin::app.sales.orders.shipping-price') }}
</span>
<span class="value">
{{ core()->formatBasePrice($order->base_shipping_amount) }}
</span>
</div>
</div>
</div>
</div>
</accordian>
<accordian :title="'{{ __('admin::app.sales.orders.products-ordered') }}'" :active="true">
<div slot="body">
<refund-items></refund-items>
</div>
</accordian>
</div>
</div>
</form>
</div>
@stop
@push('scripts')
<script type="text/x-template" id="refund-items-template">
<div>
<div class="table">
<table>
<thead>
<tr>
<th>{{ __('admin::app.sales.orders.SKU') }}</th>
<th>{{ __('admin::app.sales.orders.product-name') }}</th>
<th>{{ __('admin::app.sales.orders.item-status') }}</th>
<th>{{ __('admin::app.sales.orders.subtotal') }}</th>
<th>{{ __('admin::app.sales.orders.tax-amount') }}</th>
@if ($order->base_discount_amount > 0)
<th>{{ __('admin::app.sales.orders.discount-amount') }}</th>
@endif
<th>{{ __('admin::app.sales.orders.grand-total') }}</th>
<th>{{ __('admin::app.sales.refunds.qty-ordered') }}</th>
<th>{{ __('admin::app.sales.refunds.qty-to-refund') }}</th>
</tr>
</thead>
<tbody>
@foreach ($order->items as $item)
<tr>
<td>{{ $item->type == 'configurable' ? $item->child->sku : $item->sku }}</td>
<td>
{{ $item->name }}
@if ($html = $item->getOptionDetailHtml())
<p>{{ $html }}</p>
@endif
</td>
<td>
<span class="qty-row">
{{ $item->qty_ordered ? __('admin::app.sales.orders.item-ordered', ['qty_ordered' => $item->qty_ordered]) : '' }}
</span>
<span class="qty-row">
{{ $item->qty_invoiced ? __('admin::app.sales.orders.item-invoice', ['qty_invoiced' => $item->qty_invoiced]) : '' }}
</span>
<span class="qty-row">
{{ $item->qty_shipped ? __('admin::app.sales.orders.item-shipped', ['qty_shipped' => $item->qty_shipped]) : '' }}
</span>
<span class="qty-row">
{{ $item->qty_refunded ? __('admin::app.sales.orders.item-refunded', ['qty_refunded' => $item->qty_refunded]) : '' }}
</span>
<span class="qty-row">
{{ $item->qty_canceled ? __('admin::app.sales.orders.item-canceled', ['qty_canceled' => $item->qty_canceled]) : '' }}
</span>
</td>
<td>{{ core()->formatBasePrice($item->base_price) }}</td>
<td>{{ core()->formatBasePrice($item->base_tax_amount) }}</td>
@if ($order->base_discount_amount > 0)
<td>{{ core()->formatBasePrice($item->base_discount_amount) }}</td>
@endif
<td>{{ core()->formatBasePrice($item->base_total + $item->base_tax_amount - $item->base_discount_amount) }}</td>
<td>{{ $item->qty_ordered }}</td>
<td>
<div class="control-group" :class="[errors.has('refund[items][{{ $item->id }}]') ? 'has-error' : '']">
<input type="text" v-validate="'required|numeric|min:0'" class="control" id="refund[items][{{ $item->id }}]" name="refund[items][{{ $item->id }}]" v-model="refund.items[{{ $item->id }}]" data-vv-as="&quot;{{ __('admin::app.sales.refunds.qty-to-refund') }}&quot;"/>
<span class="control-error" v-if="errors.has('refund[items][{{ $item->id }}]')">
@verbatim
{{ errors.first('refund[items][<?php echo $item->id ?>]') }}
@endverbatim
</span>
</div>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
<div style="width: 100%; display: inline-block">
<button type="button" class="btn btn-lg btn-primary" style="float: right" @click="updateQty">
{{ __('admin::app.sales.refunds.update-qty') }}
</button>
</div>
<table v-if="refund.summary" class="sale-summary">
<tr>
<td>{{ __('admin::app.sales.orders.subtotal') }}</td>
<td>-</td>
<td>@{{ refund.summary.subtotal.formated_price }}</td>
</tr>
<tr>
<td>{{ __('admin::app.sales.orders.discount') }}</td>
<td>-</td>
<td>-@{{ refund.summary.discount.formated_price }}</td>
</tr>
<tr>
<td>{{ __('admin::app.sales.refunds.refund-shipping') }}</td>
<td>-</td>
<td>
<div class="control-group" :class="[errors.has('refund[shipping]') ? 'has-error' : '']" style="width: 100px; margin-bottom: 0;">
<input type="text" v-validate="'required|min_value:0|max_value:{{$order->base_shipping_invoiced - $order->base_shipping_refunded}}'" class="control" id="refund[shipping]" name="refund[shipping]" v-model="refund.summary.shipping.price" data-vv-as="&quot;{{ __('admin::app.sales.refunds.refund-shipping') }}&quot;" style="width: 100%; margin: 0"/>
<span class="control-error" v-if="errors.has('refund[shipping]')">
@{{ errors.first('refund[shipping]') }}
</span>
</div>
</td>
</tr>
<tr>
<td>{{ __('admin::app.sales.refunds.adjustment-refund') }}</td>
<td>-</td>
<td>
<div class="control-group" :class="[errors.has('refund[adjustment_refund]') ? 'has-error' : '']" style="width: 100px; margin-bottom: 0;">
<input type="text" v-validate="'required|min_value:0'" class="control" id="refund[adjustment_refund]" name="refund[adjustment_refund]" value="0" data-vv-as="&quot;{{ __('admin::app.sales.refunds.adjustment-refund') }}&quot;" style="width: 100%; margin: 0"/>
<span class="control-error" v-if="errors.has('refund[adjustment_refund]')">
@{{ errors.first('refund[adjustment_refund]') }}
</span>
</div>
</td>
</tr>
<tr>
<td>{{ __('admin::app.sales.refunds.adjustment-fee') }}</td>
<td>-</td>
<td>
<div class="control-group" :class="[errors.has('refund[adjustment_fee]') ? 'has-error' : '']" style="width: 100px; margin-bottom: 0;">
<input type="text" v-validate="'required|min_value:0'" class="control" id="refund[adjustment_fee]" name="refund[adjustment_fee]" value="0" data-vv-as="&quot;{{ __('admin::app.sales.refunds.adjustment-fee') }}&quot;" style="width: 100%; margin: 0"/>
<span class="control-error" v-if="errors.has('refund[adjustment_fee]')">
@{{ errors.first('refund[adjustment_fee]') }}
</span>
</div>
</td>
</tr>
<tr class="border">
<td>{{ __('admin::app.sales.orders.tax') }}</td>
<td>-</td>
<td>@{{ refund.summary.tax.formated_price }}</td>
</tr>
<tr class="bold">
<td>{{ __('admin::app.sales.orders.grand-total') }}</td>
<td>-</td>
<td>@{{ refund.summary.grand_total.formated_price }}</td>
</tr>
</table>
</div>
</script>
<script>
Vue.component('refund-items', {
template: '#refund-items-template',
inject: ['$validator'],
data: function() {
return {
refund: {
items: {},
summary: null
}
}
},
mounted: function() {
@foreach ($order->items as $item)
this.refund.items[{{$item->id}}] = {{ $item->qty_to_refund }};
@endforeach
this.updateQty();
},
methods: {
updateQty: function() {
var this_this = this;
this.$http.post("{{ route('admin.sales.refunds.update_qty', $order->id) }}", this.refund.items)
.then(function(response) {
if (! response.data) {
window.flashMessages = [{
'type': 'alert-error',
'message': "{{ __('admin::app.sales.refunds.invalid-qty') }}"
}];
this_this.$root.addFlashMessages()
} else {
this_this.refund.summary = response.data;
}
})
.catch(function (error) {})
}
}
});
</script>
@endpush

View File

@ -0,0 +1,42 @@
@extends('admin::layouts.content')
@section('page_title')
{{ __('admin::app.sales.refunds.title') }}
@stop
@section('content')
<div class="content">
<div class="page-header">
<div class="page-title">
<h1>{{ __('admin::app.sales.refunds.title') }}</h1>
</div>
<div class="page-action">
<div class="export-import" @click="showModal('downloadDataGrid')">
<i class="export-icon"></i>
<span>
{{ __('admin::app.export.export') }}
</span>
</div>
</div>
</div>
<div class="page-content">
@inject('refundGrid', 'Webkul\Admin\DataGrids\OrderRefundDataGrid')
{!! $refundGrid->render() !!}
</div>
</div>
<modal id="downloadDataGrid" :is-open="modalIds.downloadDataGrid">
<h3 slot="header">{{ __('admin::app.export.download') }}</h3>
<div slot="body">
<export-form></export-form>
</div>
</modal>
@stop
@push('scripts')
@include('admin::export.export', ['gridName' => $refundGrid])
@endpush

View File

@ -0,0 +1,316 @@
@extends('admin::layouts.master')
@section('page_title')
{{ __('admin::app.sales.refunds.view-title', ['refund_id' => $refund->id]) }}
@stop
@section('content-wrapper')
<?php $order = $refund->order; ?>
<div class="content full-page">
<div class="page-header">
<div class="page-title">
<h1>
<i class="icon angle-left-icon back-link" onclick="history.length > 1 ? history.go(-1) : window.location = '{{ url('/admin/dashboard') }}';"></i>
{{ __('admin::app.sales.refunds.view-title', ['refund_id' => $refund->id]) }}
</h1>
</div>
<div class="page-action">
</div>
</div>
<div class="page-content">
<div class="sale-container">
<accordian :title="'{{ __('admin::app.sales.orders.order-and-account') }}'" :active="true">
<div slot="body">
<div class="sale-section">
<div class="secton-title">
<span>{{ __('admin::app.sales.orders.order-info') }}</span>
</div>
<div class="section-content">
<div class="row">
<span class="title">
{{ __('admin::app.sales.refunds.order-id') }}
</span>
<span class="value">
<a href="{{ route('admin.sales.orders.view', $order->id) }}">#{{ $order->increment_id }}</a>
</span>
</div>
<div class="row">
<span class="title">
{{ __('admin::app.sales.orders.order-date') }}
</span>
<span class="value">
{{ $order->created_at }}
</span>
</div>
<div class="row">
<span class="title">
{{ __('admin::app.sales.orders.order-status') }}
</span>
<span class="value">
{{ $order->status_label }}
</span>
</div>
<div class="row">
<span class="title">
{{ __('admin::app.sales.orders.channel') }}
</span>
<span class="value">
{{ $order->channel_name }}
</span>
</div>
</div>
</div>
<div class="sale-section">
<div class="secton-title">
<span>{{ __('admin::app.sales.orders.account-info') }}</span>
</div>
<div class="section-content">
<div class="row">
<span class="title">
{{ __('admin::app.sales.orders.customer-name') }}
</span>
<span class="value">
{{ $refund->order->customer_full_name }}
</span>
</div>
<div class="row">
<span class="title">
{{ __('admin::app.sales.orders.email') }}
</span>
<span class="value">
{{ $refund->order->customer_email }}
</span>
</div>
</div>
</div>
</div>
</accordian>
<accordian :title="'{{ __('admin::app.sales.orders.address') }}'" :active="true">
<div slot="body">
<div class="sale-section">
<div class="secton-title">
<span>{{ __('admin::app.sales.orders.billing-address') }}</span>
</div>
<div class="section-content">
@include ('admin::sales.address', ['address' => $order->billing_address])
</div>
</div>
@if ($order->shipping_address)
<div class="sale-section">
<div class="secton-title">
<span>{{ __('admin::app.sales.orders.shipping-address') }}</span>
</div>
<div class="section-content">
@include ('admin::sales.address', ['address' => $order->shipping_address])
</div>
</div>
@endif
</div>
</accordian>
<accordian :title="'{{ __('admin::app.sales.orders.payment-and-shipping') }}'" :active="true">
<div slot="body">
<div class="sale-section">
<div class="secton-title">
<span>{{ __('admin::app.sales.orders.payment-info') }}</span>
</div>
<div class="section-content">
<div class="row">
<span class="title">
{{ __('admin::app.sales.orders.payment-method') }}
</span>
<span class="value">
{{ core()->getConfigData('sales.paymentmethods.' . $order->payment->method . '.title') }}
</span>
</div>
<div class="row">
<span class="title">
{{ __('admin::app.sales.orders.currency') }}
</span>
<span class="value">
{{ $order->order_currency_code }}
</span>
</div>
</div>
</div>
<div class="sale-section">
<div class="secton-title">
<span>{{ __('admin::app.sales.orders.shipping-info') }}</span>
</div>
<div class="section-content">
<div class="row">
<span class="title">
{{ __('admin::app.sales.orders.shipping-method') }}
</span>
<span class="value">
{{ $order->shipping_title }}
</span>
</div>
<div class="row">
<span class="title">
{{ __('admin::app.sales.orders.shipping-price') }}
</span>
<span class="value">
{{ core()->formatBasePrice($order->base_shipping_amount) }}
</span>
</div>
</div>
</div>
</div>
</accordian>
<accordian :title="'{{ __('admin::app.sales.orders.products-ordered') }}'" :active="true">
<div slot="body">
<div class="table">
<table>
<thead>
<tr>
<th>{{ __('admin::app.sales.orders.SKU') }}</th>
<th>{{ __('admin::app.sales.orders.product-name') }}</th>
<th>{{ __('admin::app.sales.orders.price') }}</th>
<th>{{ __('admin::app.sales.orders.qty') }}</th>
<th>{{ __('admin::app.sales.orders.subtotal') }}</th>
<th>{{ __('admin::app.sales.orders.tax-amount') }}</th>
<th>{{ __('admin::app.sales.orders.discount-amount') }}</th>
<th>{{ __('admin::app.sales.orders.grand-total') }}</th>
</tr>
</thead>
<tbody>
@foreach ($refund->items as $item)
<tr>
<td>{{ $item->child ? $item->child->sku : $item->sku }}</td>
<td>
{{ $item->name }}
@if ($html = $item->getOptionDetailHtml())
<p>{{ $html }}</p>
@endif
</td>
<td>{{ core()->formatBasePrice($item->base_price) }}</td>
<td>{{ $item->qty }}</td>
<td>{{ core()->formatBasePrice($item->base_total) }}</td>
<td>{{ core()->formatBasePrice($item->base_tax_amount) }}</td>
<td>{{ core()->formatBasePrice($item->base_discount_amount) }}</td>
<td>{{ core()->formatBasePrice($item->base_total + $item->base_tax_amount - $item->base_discount_amount) }}</td>
</tr>
@endforeach
@if (! $refund->items->count())
<tr>
<td class="empty" colspan="7">{{ __('admin::app.common.no-result-found') }}</td>
<tr>
@endif
</tbody>
</table>
</div>
<table class="sale-summary">
<tr>
<td>{{ __('admin::app.sales.orders.subtotal') }}</td>
<td>-</td>
<td>{{ core()->formatBasePrice($refund->base_sub_total) }}</td>
</tr>
@if ($refund->base_shipping_amount > 0)
<tr>
<td>{{ __('admin::app.sales.orders.shipping-handling') }}</td>
<td>-</td>
<td>{{ core()->formatBasePrice($refund->base_shipping_amount) }}</td>
</tr>
@endif
@if ($refund->base_tax_amount > 0)
<tr>
<td>{{ __('admin::app.sales.orders.tax') }}</td>
<td>-</td>
<td>{{ core()->formatBasePrice($refund->base_tax_amount) }}</td>
</tr>
@endif
@if ($refund->base_discount_amount > 0)
<tr>
<td>{{ __('admin::app.sales.orders.discount') }}</td>
<td>-</td>
<td>-{{ core()->formatBasePrice($refund->base_discount_amount) }}</td>
</tr>
@endif
<tr>
<td>{{ __('admin::app.sales.refunds.adjustment-refund') }}</td>
<td>-</td>
<td>{{ core()->formatBasePrice($refund->base_adjustment_refund) }}</td>
</tr>
<tr>
<td>{{ __('admin::app.sales.refunds.adjustment-fee') }}</td>
<td>-</td>
<td>{{ core()->formatBasePrice($refund->base_adjustment_fee) }}</td>
</tr>
<tr class="bold">
<td>{{ __('admin::app.sales.orders.grand-total') }}</td>
<td>-</td>
<td>{{ core()->formatBasePrice($refund->base_grand_total) }}</td>
</tr>
</table>
</div>
</accordian>
</div>
</div>
</div>
@stop

View File

@ -43,7 +43,7 @@
</span>
<span class="value">
<a href="{{ route('admin.sales.orders.view', $order->id) }}">#{{ $order->id }}</a>
<a href="{{ route('admin.sales.orders.view', $order->id) }}">#{{ $order->increment_id }}</a>
</span>
</div>

View File

@ -39,7 +39,7 @@
</span>
<span class="value">
<a href="{{ route('admin.sales.orders.view', $order->id) }}">#{{ $order->id }}</a>
<a href="{{ route('admin.sales.orders.view', $order->id) }}">#{{ $order->increment_id }}</a>
</span>
</div>

View File

@ -0,0 +1,32 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class ChangeRateColumnInCurrencyExchangeRatesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('currency_exchange_rates', function (Blueprint $table) {
$table->decimal('rate', 24, 12)->change();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('currency_exchange_rates', function (Blueprint $table) {
$table->decimal('rate', 10, 5)->change();
});
}
}

View File

@ -3,7 +3,7 @@
namespace Webkul\Core\Eloquent;
use Illuminate\Database\Eloquent\Model;
use Dimsav\Translatable\Translatable;
use Astrotomic\Translatable\Translatable;
use Webkul\Core\Models\Locale;
class TranslatableModel extends Model

View File

@ -98,7 +98,7 @@ class SubscriptionController extends Controller
$subscriber = $this->subscribersListRepository->findOrFail($id);
try {
$this->subscriber->delete($id);
$this->subscribers->delete($id);
session()->flash('success', trans('admin::app.response.delete-success', ['name' => 'Subscriber']));

View File

@ -0,0 +1,34 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class RemoveChannelIdFromCustomersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('customers', function (Blueprint $table) {
$table->dropForeign('customers_channel_id_foreign');
$table->dropColumn('channel_id');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('customers', function (Blueprint $table) {
$table->integer('channel_id')->unsigned();
$table->foreign('channel_id')->references('id')->on('channels')->onDelete('restrict');
});
}
}

View File

@ -114,6 +114,32 @@ class CustomerController extends Controller
}
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
$id = auth()->guard('customer')->user()->id;
$customer = $this->customer->findorFail($id);
try {
$this->customer->delete($id);
session()->flash('success', trans('admin::app.response.delete-success', ['name' => 'Customer']));
return redirect()->route($this->_config['redirect']);
} catch(\Exception $e) {
session()->flash('error', trans('admin::app.response.delete-failed', ['name' => 'Customer']));
return redirect()->route($this->_config['redirect']);
}
}
/**
* Load the view for the customer account panel, showing approved reviews.
*
@ -121,7 +147,7 @@ class CustomerController extends Controller
*/
public function reviews()
{
$reviews = auth()->guard('customer')->user()->all_reviews;
$reviews = $this->productReview->getCustomerReview();
return view($this->_config['view'], compact('reviews'));
}

View File

@ -4,6 +4,7 @@ namespace Webkul\Customer\Http\Controllers;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Mail;
use Webkul\Customer\Mail\RegistrationEmail;
use Webkul\Customer\Mail\VerificationEmail;
use Webkul\Customer\Repositories\CustomerRepository;
use Webkul\Customer\Repositories\CustomerGroupRepository;
@ -85,8 +86,6 @@ class RegistrationController extends Controller
$data['password'] = bcrypt($data['password']);
$data['channel_id'] = core()->getCurrentChannel()->id;
if (core()->getConfigData('customer.settings.email.verification')) {
$data['is_verified'] = 0;
} else {
@ -115,6 +114,15 @@ class RegistrationController extends Controller
session()->flash('info', trans('shop::app.customer.signup-form.success-verify-email-unsent'));
}
} else {
try {
Mail::queue(new RegistrationEmail(request()->all()));
session()->flash('success', trans('shop::app.customer.signup-form.success-verify')); //customer registered successfully
} catch (\Exception $e) {
session()->flash('info', trans('shop::app.customer.signup-form.success-verify-email-unsent'));
}
session()->flash('success', trans('shop::app.customer.signup-form.success'));
}

View File

@ -0,0 +1,38 @@
<?php
namespace Webkul\Customer\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
/**
* Registration Mail class
*
* @author Prateek Srivastava
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class RegistrationEmail extends Mailable
{
use Queueable, SerializesModels;
public $data;
public function __construct($data) {
$this->data = $data;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
return $this->to($this->data['email'])
->from(env('SHOP_MAIL_FROM'))
->subject(trans('shop::app.mail.customer.registration.customer-registration'))
->view('shop::emails.customer.registration')->with('data', $this->data);
}
}

View File

@ -32,7 +32,7 @@ class VerificationEmail extends Mailable
{
return $this->to($this->verificationData['email'])
->from(env('SHOP_MAIL_FROM'))
->subject('Verification email')
->subject(trans('shop::app.mail.customer.verification.subject'))
->view('shop::emails.customer.verification-email')->with('data', ['email' => $this->verificationData['email'], 'token' => $this->verificationData['token']]);
}
}

View File

@ -17,7 +17,7 @@ class Customer extends Authenticatable implements CustomerContract, JWTSubject
protected $table = 'customers';
protected $fillable = ['first_name', 'channel_id', 'last_name', 'gender', 'date_of_birth', 'email', 'phone', 'password', 'customer_group_id', 'subscribed_to_news_letter', 'is_verified', 'token', 'notes', 'status'];
protected $fillable = ['first_name', 'last_name', 'gender', 'date_of_birth', 'email', 'phone', 'password', 'customer_group_id', 'subscribed_to_news_letter', 'is_verified', 'token', 'notes', 'status'];
protected $hidden = ['password', 'remember_token'];

View File

@ -61,4 +61,17 @@ class WishlistRepository extends Repository
public function getItemsWithProducts($id) {
return $this->model->find($id)->item_wishlist;
}
/**
* get customer wishlist Items.
*
* @return mixed
*/
public function getCustomerWhishlist() {
return $this->model->where([
'channel_id' => core()->getCurrentChannel()->id,
'customer_id' => auth()->guard('customer')->user()->id
])->paginate(5);
}
}

View File

@ -26,28 +26,8 @@ abstract class Action
foreach ($items as $item) {
foreach ($matchingIDs as $matchingID) {
if (isset($item->children)) {
$isQtyZero = true;
foreach ($item->children as $children) {
if ($children->quantity > 0) {
$isQtyZero = false;
}
}
if ($isQtyZero) {
if ($matchingID == ($item->child ? $item->child->product_id : $item->product_id)) {
$matchedItems->push($item);
}
} else {
if ($matchingID == $item->product_id) {
$matchedItems->push($item);
}
}
} else {
if ($matchingID == $item->product_id) {
$matchedItems->push($item);
}
if ($matchingID == ($item->child ? $item->child->product_id : $item->product_id)) {
$matchedItems->push($item);
}
}
}

View File

@ -192,8 +192,7 @@ class ConvertXToProductId
} else if ($testCondition == '=') {
$foundProducts = $this->product->findWhere([
['sku', '=', $testValue],
['type', '!=', 'configurable'],
['type', '!=', 'group']
['type', '!=', 'configurable']
])->flatten()->all();
}
}

View File

@ -18,6 +18,7 @@ class Payment
return [
'jump_to_section' => 'payment',
'paymentMethods' => $this->getPaymentMethods(),
'html' => view('shop::checkout.onepage.payment', compact('paymentMethods'))->render()
];
}

View File

@ -113,7 +113,7 @@ abstract class Payment
/**
* Returns payment method sort order
*
* @return array
* @return int
*/
public function getSortOrder()
{

View File

@ -105,7 +105,7 @@ class Ipn
*/
protected function processOrder()
{
if ($this->post['payment_status'] == 'completed') {
if ($this->post['payment_status'] == 'Completed') {
if ($this->post['mc_gross'] != $this->order->grand_total) {
} else {

View File

@ -8,9 +8,9 @@ Route::group(['middleware' => ['web']], function () {
Route::get('/success', 'Webkul\Paypal\Http\Controllers\StandardController@success')->name('paypal.standard.success');
Route::get('/cancel', 'Webkul\Paypal\Http\Controllers\StandardController@cancel')->name('paypal.standard.cancel');
Route::get('/ipn', 'Webkul\Paypal\Http\Controllers\StandardController@ipn')->name('paypal.standard.ipn');
Route::post('/ipn', 'Webkul\Paypal\Http\Controllers\StandardController@ipn')->name('paypal.standard.ipn');
});
});
Route::get('paypal/standard/ipn', 'Webkul\Paypal\Http\Controllers\StandardController@ipn')->name('paypal.standard.ipn');
Route::post('paypal/standard/ipn', 'Webkul\Paypal\Http\Controllers\StandardController@ipn')->name('paypal.standard.ipn');

View File

@ -0,0 +1,179 @@
<?php
namespace Webkul\Product\Helpers;
use Webkul\Product\Repositories\ProductRepository as Product;
use Webkul\Attribute\Repositories\AttributeFamilyRepository as AttributeFamily;
class GenerateProduct
{
/**
* Product Repository instance
*/
protected $product;
/**
* AttributeFamily Repository instance
*/
protected $attributeFamily;
/**
* Product Attribute Types
*/
protected $types;
public function __construct(Product $product, AttributeFamily $attributeFamily)
{
$this->product = $product;
$this->types = [
'text', 'textarea', 'boolean', 'select', 'multiselect', 'datetime', 'date', 'price', 'image', 'file', 'checkbox'
];
$this->attributeFamily = $attributeFamily;
}
public function create()
{
$attributes = $this->getDefaultFamilyAttributes();
$attributeFamily = $this->attributeFamily->findWhere([
'code' => 'default'
]);
$sku = str_random(10);
$data['sku'] = strtolower($sku);
$data['attribute_family_id'] = $attributeFamily->first()->id;
$data['type'] = 'simple';
$product = $this->product->create($data);
unset($data);
$faker = \Faker\Factory::create();
$date = date('Y-m-d');
$date = \Carbon\Carbon::parse($date);
$specialFrom = $date->toDateString();
$specialTo = $date->addDays(7)->toDateString();
foreach ($attributes as $attribute) {
if ($attribute->type == 'text') {
if ($attribute->code == 'width' || $attribute->code == 'height' || $attribute->code == 'depth' || $attribute->code == 'weight') {
$data[$attribute->code] = $faker->randomNumber(3);
} else if ($attribute->code == 'url_key') {
$data[$attribute->code] = strtolower($sku);
} else if ($attribute->code != 'sku') {
$data[$attribute->code] = $faker->name;
} else {
$data[$attribute->code] = $sku;
}
} else if ($attribute->type == 'textarea') {
$data[$attribute->code] = $faker->text;
if ($attribute->code == 'description' || $attribute->code == 'short_description') {
$data[$attribute->code] = '<p>'. $data[$attribute->code] . '</p>';
}
} else if ($attribute->type == 'boolean') {
$data[$attribute->code] = $faker->boolean;
} else if ($attribute->type == 'price') {
$data[$attribute->code] = $faker->randomNumber(2);
} else if ($attribute->type == 'datetime') {
$data[$attribute->code] = $date->toDateTimeString();
} else if ($attribute->type == 'date') {
if ($attribute->code == 'special_price_from') {
$data[$attribute->code] = $specialFrom;
} else if ($attribute->code == 'special_price_to') {
$data[$attribute->code] = $specialTo;
} else {
$data[$attribute->code] = $date->toDateString();
}
} else if ($attribute->code != 'tax_category_id' && ($attribute->type == 'select' || $attribute->type == 'multiselect')) {
$options = $attribute->options;
if ($attribute->type == 'select') {
if ($options->count()) {
$option = $options->first()->id;
$data[$attribute->code] = $option;
} else {
$data[$attribute->code] = "";
}
} else if ($attribute->type == 'multiselect') {
if ($options->count()) {
$option = $options->first()->id;
$optionArray = [];
array_push($optionArray, $option);
$data[$attribute->code] = $optionArray;
} else {
$data[$attribute->code] = "";
}
} else {
$data[$attribute->code] = "";
}
} else if ($attribute->code == 'checkbox') {
$options = $attribute->options;
if ($options->count()) {
$option = $options->first()->id;
$optionArray = [];
array_push($optionArray, $option);
$data[$attribute->code] = $optionArray;
} else {
$data[$attribute->code] = "";
}
}
}
$channel = core()->getCurrentChannel();
$data['locale'] = core()->getCurrentLocale()->code;
$data['channel'] = $channel->code;
$data['channels'] = [
0 => $channel->id
];
$inventorySource = $channel->inventory_sources[0];
$data['inventories'] = [
$inventorySource->id => 10
];
$data['categories'] = [
0 => $channel->root_category->id
];
$updated = $this->product->update($data, $product->id);
return $updated;
}
public function getDefaultFamilyAttributes()
{
$attributeFamily = $this->attributeFamily->findWhere([
'code' => 'default'
]);
$attributes = collect();
if ($attributeFamily->count()) {
$attributeGroups = $attributeFamily->first()->attribute_groups;
foreach ($attributeGroups as $attributeGroup) {
foreach ($attributeGroup->custom_attributes as $customAttribute) {
$attributes->push($customAttribute);
}
}
}
return $attributes;
}
}

View File

@ -284,7 +284,9 @@ class ProductFlat
$productFlat->save();
}
} else {
if (request()->route()->getName() == 'admin.catalog.products.update') {
$route = request()->route() ? request()->route()->getName() : "";
if ($route == 'admin.catalog.products.update') {
$productFlat = $this->productFlatRepository->findOneWhere([
'product_id' => $product->id,
'channel' => $channel->code,

View File

@ -32,7 +32,7 @@ class ProductReviewRepository extends Repository
{
$customerId = auth()->guard('customer')->user()->id;
$reviews = $this->model->where(['customer_id'=> $customerId])->with('product')->get();
$reviews = $this->model->where(['customer_id'=> $customerId])->with('product')->paginate(5);
return $reviews;
}

View File

@ -0,0 +1,39 @@
<?php
return [
[
'key' => 'sales.orderSettings',
'name' => 'admin::app.admin.system.order-settings',
'sort' => 3,
],[
'key' => 'sales.orderSettings.order_number',
'name' => 'admin::app.admin.system.orderNumber',
'sort' => 0,
'fields' => [
[
'name' => 'order_number_prefix',
'title' => 'admin::app.admin.system.order-number-prefix',
'type' => 'text',
'validation' => false,
'channel_based' => true,
'locale_based' => true
],
[
'name' => 'order_number_length',
'title' => 'admin::app.admin.system.order-number-length',
'type' => 'text',
'validation' => false,
'channel_based' => true,
'locale_based' => true
],
[
'name' => 'order_number_suffix',
'title' => 'admin::app.admin.system.order-number-suffix',
'type' => 'text',
'validation' => false,
'channel_based' => true,
'locale_based' => true
],
]
]
];

View File

@ -0,0 +1,7 @@
<?php
namespace Webkul\Sales\Contracts;
interface Refund
{
}

View File

@ -0,0 +1,7 @@
<?php
namespace Webkul\Sales\Contracts;
interface RefundItem
{
}

View File

@ -0,0 +1,65 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateRefundsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('refunds', function (Blueprint $table) {
$table->increments('id');
$table->string('increment_id')->nullable();
$table->string('state')->nullable();
$table->boolean('email_sent')->default(0);
$table->integer('total_qty')->nullable();
$table->string('base_currency_code')->nullable();
$table->string('channel_currency_code')->nullable();
$table->string('order_currency_code')->nullable();
$table->decimal('adjustment_refund', 12, 4)->default(0)->nullable();
$table->decimal('base_adjustment_refund', 12, 4)->default(0)->nullable();
$table->decimal('adjustment_fee', 12, 4)->default(0)->nullable();
$table->decimal('base_adjustment_fee', 12, 4)->default(0)->nullable();
$table->decimal('sub_total', 12, 4)->default(0)->nullable();
$table->decimal('base_sub_total', 12, 4)->default(0)->nullable();
$table->decimal('grand_total', 12, 4)->default(0)->nullable();
$table->decimal('base_grand_total', 12, 4)->default(0)->nullable();
$table->decimal('shipping_amount', 12, 4)->default(0)->nullable();
$table->decimal('base_shipping_amount', 12, 4)->default(0)->nullable();
$table->decimal('tax_amount', 12, 4)->default(0)->nullable();
$table->decimal('base_tax_amount', 12, 4)->default(0)->nullable();
$table->decimal('discount_percent', 12, 4)->default(0)->nullable();
$table->decimal('discount_amount', 12, 4)->default(0)->nullable();
$table->decimal('base_discount_amount', 12, 4)->default(0)->nullable();
$table->integer('order_id')->unsigned()->nullable();
$table->foreign('order_id')->references('id')->on('orders')->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('refunds');
}
}

View File

@ -0,0 +1,62 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateRefundItemsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('refund_items', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->nullable();
$table->string('description')->nullable();
$table->string('sku')->nullable();
$table->integer('qty')->nullable();
$table->decimal('price', 12,4)->default(0);
$table->decimal('base_price', 12,4)->default(0);
$table->decimal('total', 12,4)->default(0);
$table->decimal('base_total', 12,4)->default(0);
$table->decimal('tax_amount', 12,4)->default(0)->nullable();
$table->decimal('base_tax_amount', 12,4)->default(0)->nullable();
$table->decimal('discount_percent', 12, 4)->default(0)->nullable();
$table->decimal('discount_amount', 12, 4)->default(0)->nullable();
$table->decimal('base_discount_amount', 12, 4)->default(0)->nullable();
$table->integer('product_id')->unsigned()->nullable();
$table->string('product_type')->nullable();
$table->integer('order_item_id')->unsigned()->nullable();
$table->foreign('order_item_id')->references('id')->on('order_items')->onDelete('cascade');
$table->integer('refund_id')->unsigned()->nullable();
$table->foreign('refund_id')->references('id')->on('refunds')->onDelete('cascade');
$table->integer('parent_id')->unsigned()->nullable();
$table->foreign('parent_id')->references('id')->on('refund_items')->onDelete('cascade');
$table->json('additional')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('refund_items');
}
}

View File

@ -83,6 +83,14 @@ class Order extends Model implements OrderContract
return $this->hasMany(InvoiceProxy::modelClass());
}
/**
* Get the order refunds record associated with the order.
*/
public function refunds()
{
return $this->hasMany(RefundProxy::modelClass());
}
/**
* Get the customer record associated with the order.
*/
@ -195,7 +203,7 @@ class Order extends Model implements OrderContract
}
/**
* Checks if order could can canceled on not
* Checks if order can be canceled or not
*/
public function canCancel()
{
@ -209,4 +217,23 @@ class Order extends Model implements OrderContract
return false;
}
/**
* Checks if order can be refunded or not
*/
public function canRefund()
{
if ($this->status == 'fraud')
return false;
foreach ($this->items as $item) {
if ($item->qty_to_refund > 0)
return true;
}
if ($this->base_grand_total_invoiced - $this->base_grand_total_refunded - $this->refunds()->sum('base_adjustment_fee') > 0)
return true;
return false;
}
}

View File

@ -105,6 +105,14 @@ class OrderItem extends Model implements OrderItemContract
return $this->qty_ordered - $this->qty_canceled - $this->qty_invoiced;
}
/**
* Get remaining qty for refund.
*/
public function getQtyToRefundAttribute()
{
return $this->qty_invoiced - $this->qty_refunded;
}
/**
* Get the order record associated with the order item.
*/
@ -162,10 +170,36 @@ class OrderItem extends Model implements OrderItemContract
}
/**
* Get the invoice items record associated with the order item.
* Get the refund items record associated with the order item.
*/
public function refund_items()
{
return $this->hasMany(RefundItemProxy::modelClass());
}
/**
* Returns configurable option html
*/
public function downloadable_link_purchased()
{
return $this->hasMany(DownloadableLinkPurchasedProxy::modelClass());
}
/**
* @return array
*/
public function toArray()
{
$array = parent::toArray();
$array['qty_to_ship'] = $this->qty_to_ship;
$array['qty_to_invoice'] = $this->qty_to_invoice;
$array['qty_to_cancel'] = $this->qty_to_cancel;
$array['qty_to_refund'] = $this->qty_to_refund;
return $array;
}
}

View File

@ -0,0 +1,61 @@
<?php
namespace Webkul\Sales\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\Sales\Contracts\Refund as RefundContract;
class Refund extends Model implements RefundContract
{
protected $guarded = ['id', 'created_at', 'updated_at'];
protected $statusLabel = [
];
/**
* Returns the status label from status code
*/
public function getStatusLabelAttribute()
{
return isset($this->statusLabel[$this->state]) ? $this->statusLabel[$this->state] : '';
}
/**
* Get the order that belongs to the Refund.
*/
public function order()
{
return $this->belongsTo(OrderProxy::modelClass());
}
/**
* Get the Refund items record associated with the Refund.
*/
public function items() {
return $this->hasMany(RefundItemProxy::modelClass())->whereNull('parent_id');
}
/**
* Get the customer record associated with the Refund.
*/
public function customer()
{
return $this->morphTo();
}
/**
* Get the channel record associated with the Refund.
*/
public function channel()
{
return $this->morphTo();
}
/**
* Get the addresses for the shipment.
*/
public function address()
{
return $this->belongsTo(OrderAddressProxy::modelClass(), 'order_address_id');
}
}

View File

@ -0,0 +1,64 @@
<?php
namespace Webkul\Sales\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\Sales\Contracts\RefundItem as RefundItemContract;
class RefundItem extends Model implements RefundItemContract
{
protected $guarded = ['id', 'created_at', 'updated_at'];
protected $casts = [
'additional' => 'array',
];
/**
* Get the Refund record associated with the Refund item.
*/
public function refund()
{
return $this->belongsTo(RefundProxy::modelClass());
}
/**
* Get the order item record associated with the Refund item.
*/
public function order_item()
{
return $this->belongsTo(OrderItemProxy::modelClass());
}
/**
* Get the Refund record associated with the Refund item.
*/
public function product()
{
return $this->morphTo();
}
/**
* Get the child item record associated with the Refund item.
*/
public function child()
{
return $this->hasOne(RefundItemProxy::modelClass(), 'parent_id');
}
/**
* Returns configurable option html
*/
public function getOptionDetailHtml()
{
if ($this->type == 'configurable' && isset($this->additional['attributes'])) {
$labels = [];
foreach ($this->additional['attributes'] as $attribute) {
$labels[] = $attribute['attribute_name'] . ' : ' . $attribute['option_label'];
}
return implode(', ', $labels);
}
}
}

View File

@ -0,0 +1,10 @@
<?php
namespace Webkul\Sales\Models;
use Konekt\Concord\Proxies\ModelProxy;
class RefundItemProxy extends ModelProxy
{
}

View File

@ -0,0 +1,10 @@
<?php
namespace Webkul\Sales\Models;
use Konekt\Concord\Proxies\ModelProxy;
class RefundProxy extends ModelProxy
{
}

View File

@ -16,5 +16,7 @@ class ModuleServiceProvider extends BaseModuleServiceProvider
\Webkul\Sales\Models\InvoiceItem::class,
\Webkul\Sales\Models\Shipment::class,
\Webkul\Sales\Models\ShipmentItem::class,
\Webkul\Sales\Models\Refund::class,
\Webkul\Sales\Models\RefundItem::class,
];
}

View File

@ -18,5 +18,8 @@ class SalesServiceProvider extends ServiceProvider
*/
public function register()
{
$this->mergeConfigFrom(
dirname(__DIR__) . '/Config/system.php', 'core'
);
}
}

View File

@ -107,9 +107,7 @@ class InvoiceRepository extends Repository
'base_currency_code' => $order->base_currency_code,
'channel_currency_code' => $order->channel_currency_code,
'order_currency_code' => $order->order_currency_code,
'order_address_id' => $order->billing_address->id,
"discount_amount" => $order->discount_amount,
"base_discount_amount" => $order->base_discount_amount,
'order_address_id' => $order->billing_address->id
]);
foreach ($data['invoice']['items'] as $itemId => $qty) {
@ -214,44 +212,33 @@ class InvoiceRepository extends Repository
*/
public function collectTotals($invoice)
{
$subTotal = $baseSubTotal = 0;
$taxAmount = $baseTaxAmount = 0;
$discountAmount = $baseDiscountAmount = 0;
$invoice->sub_total = $invoice->base_sub_total = 0;
$invoice->tax_amount = $invoice->base_tax_amount = 0;
$invoice->discount_amount = $invoice->base_discount_amount = 0;
foreach ($invoice->items as $invoiceItem) {
$subTotal += $invoiceItem->total;
$baseSubTotal += $invoiceItem->base_total;
$invoice->sub_total += $invoiceItem->total;
$invoice->base_sub_total += $invoiceItem->base_total;
$taxAmount += $invoiceItem->tax_amount;
$baseTaxAmount += $invoiceItem->base_tax_amount;
$invoice->tax_amount += $invoiceItem->tax_amount;
$invoice->base_tax_amount += $invoiceItem->base_tax_amount;
$discountAmount += $invoiceItem->discount_amount;
$baseDiscountAmount += $invoiceItem->base_discount_amount;
$invoice->discount_amount += $invoiceItem->discount_amount;
$invoice->base_discount_amount += $invoiceItem->base_discount_amount;
}
$shippingAmount = $invoice->order->shipping_amount;
$baseShippingAmount = $invoice->order->base_shipping_amount;
$invoice->shipping_amount = $invoice->order->shipping_amount;
$invoice->base_shipping_amount = $invoice->order->base_shipping_amount;
if ($invoice->order->shipping_amount) {
foreach ($invoice->order->invoices as $prevInvoice) {
if ((float) $prevInvoice->shipping_amount) {
$shippingAmount = 0;
$baseShippingAmount = 0;
}
if ((float) $prevInvoice->shipping_amount)
$invoice->shipping_amount = $invoice->base_shipping_amount = 0;
}
}
$invoice->sub_total = $subTotal;
$invoice->base_sub_total = $baseSubTotal;
$invoice->shipping_amount = $shippingAmount;
$invoice->base_shipping_amount = $baseShippingAmount;
$invoice->tax_amount = $taxAmount;
$invoice->base_tax_amount = $baseTaxAmount;
$invoice->grand_total = $subTotal + $taxAmount + $shippingAmount - $discountAmount;
$invoice->base_grand_total = $baseSubTotal + $baseTaxAmount + $baseShippingAmount - $baseDiscountAmount;
$invoice->grand_total = $invoice->sub_total + $invoice->tax_amount + $invoice->shipping_amount - $invoice->discount_amount;
$invoice->base_grand_total = $invoice->base_sub_total + $invoice->base_tax_amount + $invoice->base_shipping_amount - $invoice->base_discount_amount;
$invoice->save();

View File

@ -47,10 +47,14 @@ class OrderItemRepository extends Repository
*/
public function collectTotals($orderItem)
{
$qtyShipped = $qtyInvoiced = 0;
$qtyShipped = $qtyInvoiced = $qtyRefunded = 0;
$totalInvoiced = $baseTotalInvoiced = 0;
$taxInvoiced = $baseTaxInvoiced = 0;
$totalRefunded = $baseTotalRefunded = 0;
$taxRefunded = $baseTaxRefunded = 0;
foreach ($orderItem->invoice_items as $invoiceItem) {
$qtyInvoiced += $invoiceItem->qty;
@ -65,8 +69,19 @@ class OrderItemRepository extends Repository
$qtyShipped += $shipmentItem->qty;
}
foreach ($orderItem->refund_items as $refundItem) {
$qtyRefunded += $refundItem->qty;
$totalRefunded += $refundItem->total;
$baseTotalRefunded += $refundItem->base_total;
$taxRefunded += $refundItem->tax_amount;
$baseTaxRefunded += $refundItem->base_tax_amount;
}
$orderItem->qty_shipped = $qtyShipped;
$orderItem->qty_invoiced = $qtyInvoiced;
$orderItem->qty_refunded = $qtyRefunded;
$orderItem->total_invoiced = $totalInvoiced;
$orderItem->base_total_invoiced = $baseTotalInvoiced;
@ -74,6 +89,12 @@ class OrderItemRepository extends Repository
$orderItem->tax_amount_invoiced = $taxInvoiced;
$orderItem->base_tax_amount_invoiced = $baseTaxInvoiced;
$orderItem->amount_refunded = $totalRefunded;
$orderItem->base_amount_refunded = $baseTotalRefunded;
$orderItem->tax_amount_refunded = $taxRefunded;
$orderItem->base_tax_amount_refunded = $baseTaxRefunded;
$orderItem->save();
return $orderItem;
@ -122,7 +143,7 @@ class OrderItemRepository extends Repository
/**
* Returns qty to product inventory after order cancelation
*
* @param mixed $orderItem
* @param OrderItem $orderItem
* @return void
*/
public function returnQtyToProductInventory($orderItem)
@ -137,8 +158,6 @@ class OrderItemRepository extends Repository
if (($qty = $orderedInventory->qty - ($orderItem->qty_ordered ? $orderItem->qty_to_cancel : $orderItem->parent->qty_ordered)) < 0)
$qty = 0;
$orderedInventory->update([
'qty' => $qty
]);
$orderedInventory->update(['qty' => $qty]);
}
}

View File

@ -8,6 +8,7 @@ use Illuminate\Support\Facades\DB;
use Webkul\Core\Eloquent\Repository;
use Webkul\Sales\Contracts\Order;
use Webkul\Sales\Repositories\OrderItemRepository;
use Webkul\Core\Models\CoreConfig;
/**
* Order Reposotory
@ -185,11 +186,27 @@ class OrderRepository extends Repository
*/
public function generateIncrementId()
{
$lastOrder = $this->model->orderBy('id', 'desc')->limit(1)->first();
$config = new CoreConfig();
$invoiceNumberPrefix = $config->where('code','=',"sales.orderSettings.order_number.order_number_prefix")->first()
? $config->where('code','=',"sales.orderSettings.order_number.order_number_prefix")->first()->value : false;
$invoiceNumberLength = $config->where('code','=',"sales.orderSettings.order_number.order_number_length")->first()
? $config->where('code','=',"sales.orderSettings.order_number.order_number_length")->first()->value : false;
$invoiceNumberSuffix = $config->where('code','=',"sales.orderSettings.order_number.order_number_suffix")->first()
? $config->where('code','=',"sales.orderSettings.order_number.order_number_suffix")->first()->value: false;
$lastOrder = $this->model->orderBy('id', 'desc')->limit(1)->first();
$lastId = $lastOrder ? $lastOrder->id : 0;
return $lastId + 1;
if ($invoiceNumberLength && ( $invoiceNumberPrefix || $invoiceNumberSuffix) ) {
$invoiceNumber = $invoiceNumberPrefix . sprintf("%0{$invoiceNumberLength}d", 0) . ($lastId + 1) . $invoiceNumberSuffix;
} else {
$invoiceNumber = $lastId + 1;
}
return $invoiceNumber;
}
/**
@ -198,11 +215,7 @@ class OrderRepository extends Repository
*/
public function isInCompletedState($order)
{
$totalQtyOrdered = 0;
$totalQtyInvoiced = 0;
$totalQtyShipped = 0;
$totalQtyRefunded = 0;
$totalQtyCanceled = 0;
$totalQtyOrdered = $totalQtyInvoiced = $totalQtyShipped = $totalQtyRefunded = $totalQtyCanceled = 0;
foreach ($order->items as $item) {
$totalQtyOrdered += $item->qty_ordered;
@ -294,9 +307,11 @@ class OrderRepository extends Repository
*/
public function collectTotals($order)
{
//Order invoice total
$order->sub_total_invoiced = $order->base_sub_total_invoiced = 0;
$order->shipping_invoiced = $order->base_shipping_invoiced = 0;
$order->tax_amount_invoiced = $order->base_tax_amount_invoiced = 0;
$order->discount_invoiced = $order->base_discount_invoiced = 0;
foreach ($order->invoices as $invoice) {
$order->sub_total_invoiced += $invoice->sub_total;
@ -315,6 +330,33 @@ class OrderRepository extends Repository
$order->grand_total_invoiced = $order->sub_total_invoiced + $order->shipping_invoiced + $order->tax_amount_invoiced - $order->discount_invoiced;
$order->base_grand_total_invoiced = $order->base_sub_total_invoiced + $order->base_shipping_invoiced + $order->base_tax_amount_invoiced - $order->base_discount_invoiced;
//Order refund total
$order->sub_total_refunded = $order->base_sub_total_refunded = 0;
$order->shipping_refunded = $order->base_shipping_refunded = 0;
$order->tax_amount_refunded = $order->base_tax_amount_refunded = 0;
$order->discount_refunded = $order->base_discount_refunded = 0;
$order->grand_total_refunded = $order->base_grand_total_refunded = 0;
foreach ($order->refunds as $refund) {
$order->sub_total_refunded += $refund->sub_total;
$order->base_sub_total_refunded += $refund->base_sub_total;
$order->shipping_refunded += $refund->shipping_amount;
$order->base_shipping_refunded += $refund->base_shipping_amount;
$order->tax_amount_refunded += $refund->tax_amount;
$order->base_tax_amount_refunded += $refund->base_tax_amount;
$order->discount_refunded += $refund->discount_amount;
$order->base_discount_refunded += $refund->base_discount_amount;
$order->grand_total_refunded += $refund->adjustment_refund - $refund->adjustment_fee;
$order->base_grand_total_refunded += $refund->base_adjustment_refund - $refund->base_adjustment_fee;
}
$order->grand_total_refunded += $order->sub_total_refunded + $order->shipping_refunded + $order->tax_amount_refunded - $order->discount_refunded;
$order->base_grand_total_refunded += $order->base_sub_total_refunded + $order->base_shipping_refunded + $order->base_tax_amount_refunded - $order->base_discount_refunded;
$order->save();
return $order;

View File

@ -0,0 +1,81 @@
<?php
namespace Webkul\Sales\Repositories;
use Illuminate\Container\Container as App;
use Webkul\Core\Eloquent\Repository;
use Webkul\Sales\Contracts\RefundItem;
/**
* Refund Item Reposotory
*
* @author Jitendra Singh <jitendra@webkul.com>
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class RefundItemRepository extends Repository
{
/**
* Specify Model class name
*
* @return Mixed
*/
function model()
{
return RefundItem::class;
}
/**
* Returns qty to product inventory after order refund
*
* @param OrdreItem $orderItem
* @param integer $quantity
* @return void
*/
public function returnQtyToProductInventory($orderItem, $quantity)
{
if (! $product = $orderItem->product)
return;
if ($orderItem->qty_shipped && $quantity > $orderItem->qty_ordered - $orderItem->qty_shipped) {
$nonShippedQty = $orderItem->qty_ordered - $orderItem->qty_shipped;
if (($totalShippedQtyToRefund = $quantity - $nonShippedQty) > 0) {
foreach ($orderItem->shipment_items as $shipmentItem) {
if (! $totalShippedQtyToRefund)
break;
if (! $shipmentItem->shipment->inventory_source_id)
continue;
$shippedQtyToRefund = $totalShippedQtyToRefund > $shipmentItem->qty ? $shipmentItem->qty : $totalShippedQtyToRefund;
$totalShippedQtyToRefund = $totalShippedQtyToRefund > $shipmentItem->qty ? $totalShippedQtyToRefund - $shipmentItem->qty : 0;
$inventory = $product->inventories()
// ->where('vendor_id', $data['vendor_id'])
->where('inventory_source_id', $shipmentItem->shipment->inventory_source_id)
->first();
$inventory->update(['qty' => $inventory->qty + $shippedQtyToRefund]);
}
$quantity -= $totalShippedQtyToRefund;
}
}
if ($quantity) {
$orderedInventory = $product->ordered_inventories()
->where('channel_id', $orderItem->order->channel->id)
->first();
if (! $orderedInventory)
return;
if (($qty = $orderedInventory->qty - $quantity) < 0)
$qty = 0;
$orderedInventory->update(['qty' => $qty]);
}
}
}

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