@ -0,0 +1,48 @@ |
|||||
|
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.svg |
||||
|
:target: https://www.gnu.org/licenses/agpl-3.0-standalone.html |
||||
|
:alt: License: AGPL-3 |
||||
|
|
||||
|
Stock Analysis By Location Report |
||||
|
================================ |
||||
|
* Analyse the product or product variant stock based on locations. |
||||
|
|
||||
|
Configuration |
||||
|
============ |
||||
|
- www.odoo.com/documentation/17.0/setup/install.html |
||||
|
- Install our custom addon |
||||
|
|
||||
|
Company |
||||
|
------- |
||||
|
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__ |
||||
|
|
||||
|
License |
||||
|
------- |
||||
|
Affero General Public License v3.0 (AGPL v3) |
||||
|
(https://www.gnu.org/licenses/agpl-3.0-standalone.html) |
||||
|
|
||||
|
Credits |
||||
|
------- |
||||
|
* Developer: (V17) NIHALA KP, Contact: odoo@cybrosys.com |
||||
|
|
||||
|
|
||||
|
Contacts |
||||
|
-------- |
||||
|
* Mail Contact : odoo@cybrosys.com |
||||
|
* Website : https://cybrosys.com |
||||
|
|
||||
|
Bug Tracker |
||||
|
----------- |
||||
|
Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. |
||||
|
|
||||
|
Maintainer |
||||
|
-------- |
||||
|
This module is maintained by Cybrosys Technologies. |
||||
|
|
||||
|
For support and more information, please visit https://www.cybrosys.com |
||||
|
|
||||
|
.. image:: https://cybrosys.com/images/logo.png |
||||
|
:target: https://cybrosys.com" |
||||
|
|
||||
|
Further Information |
||||
|
----------- |
||||
|
HTML Description: `<static/description/index.html>`__ |
@ -0,0 +1,25 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Nihala KP(odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from . import controllers |
||||
|
from . import models |
||||
|
from . import report |
||||
|
from . import wizard |
@ -0,0 +1,55 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Nihala KP(odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
{ |
||||
|
'name': 'Stock Analysis By Location Report', |
||||
|
'version': '17.0.1.0.0', |
||||
|
'category': 'Warehouse', |
||||
|
'summary': 'To view each products stock in each location', |
||||
|
'description': """This module helps to get the stock positions in each """ |
||||
|
"""location. Also helps to get the details as a """ |
||||
|
"""PDF report or Excel Report.""", |
||||
|
'author': 'Cybrosys Techno Solutions', |
||||
|
'company': 'Cybrosys Techno Solutions', |
||||
|
'maintainer': 'Cybrosys Techno Solutions', |
||||
|
'website': 'https://www.cybrosys.com', |
||||
|
'depends': ['base', 'stock', 'product'], |
||||
|
'data': [ |
||||
|
'security/ir.model.access.csv', |
||||
|
'views/stock_location_product_views.xml', |
||||
|
'views/stock_location_product_variant_views.xml', |
||||
|
'views/product_template_views.xml', |
||||
|
'report/stock_location_report.xml', |
||||
|
'report/stock_location_report_templates.xml', |
||||
|
'wizard/stock_location_report_views.xml', |
||||
|
'views/menus.xml', |
||||
|
], |
||||
|
'assets': { |
||||
|
'web.assets_backend': [ |
||||
|
'stock_analysis_by_location_report/static/src/js/stock_report.js' |
||||
|
], |
||||
|
}, |
||||
|
'images': ['static/description/banner.jpg'], |
||||
|
'license': 'AGPL-3', |
||||
|
'installable': True, |
||||
|
'application': False, |
||||
|
'auto_install': False, |
||||
|
} |
@ -0,0 +1,22 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Nihala KP(odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from . import stock_analysis_by_location_report |
@ -0,0 +1,57 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Nihala KP(odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
import json |
||||
|
from odoo import http |
||||
|
from odoo.http import content_disposition, request |
||||
|
from odoo.tools import html_escape |
||||
|
|
||||
|
|
||||
|
class StockLocationXLSVReport(http.Controller): |
||||
|
"""To create the route for xlsx report""" |
||||
|
@http.route('/report_excel', type='http', auth='user', methods=['POST'], |
||||
|
csrf=False) |
||||
|
def get_report_xlsx(self, model, options, output_format, report_name): |
||||
|
"""To generate the response""" |
||||
|
report_obj = request.env[model].with_user(request.session.uid) |
||||
|
options = json.loads(options) |
||||
|
token = 'dummy-because-api-expects-one' |
||||
|
try: |
||||
|
if output_format == 'xlsx': |
||||
|
response = request.make_response( |
||||
|
None, |
||||
|
headers=[ |
||||
|
('Content-Type', 'application/vnd.ms-excel'), |
||||
|
('Content-Disposition', |
||||
|
content_disposition(report_name + '.xlsx')) |
||||
|
] |
||||
|
) |
||||
|
report_obj.get_xlsx_report(options, response) |
||||
|
response.set_cookie('fileToken', token) |
||||
|
return response |
||||
|
except Exception as e: |
||||
|
se = http.serialize_exception(e) |
||||
|
error = { |
||||
|
'code': 200, |
||||
|
'message': 'Odoo Server Error', |
||||
|
'data': se |
||||
|
} |
||||
|
return request.make_response(html_escape(json.dumps(error))) |
@ -0,0 +1,6 @@ |
|||||
|
## Module <stock_analysis_by_location_report> |
||||
|
|
||||
|
#### 23.05.2024 |
||||
|
#### Version 17.0.1.0.0 |
||||
|
#### ADD |
||||
|
- Initial commit for Stock Analysis By Location Report |
@ -0,0 +1,25 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Nihala KP(odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from . import product_product |
||||
|
from . import product_template |
||||
|
from . import stock_location_product |
||||
|
from . import stock_location_product_variant |
@ -0,0 +1,51 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Nihala KP(odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from odoo import fields, models, _ |
||||
|
|
||||
|
|
||||
|
class ProductProduct(models.Model): |
||||
|
"""Inherited product template to add additional fields and compute methods |
||||
|
for quantity computation""" |
||||
|
_inherit = 'product.product' |
||||
|
|
||||
|
qty_incoming = fields.Float(string='Incoming Qty', |
||||
|
compute='_compute_quantities', store=True) |
||||
|
qty_outgoing = fields.Float(string='Outgoing Qty', |
||||
|
compute='_compute_quantities', store=True) |
||||
|
qty_avail = fields.Float(string='Available Qty', |
||||
|
compute='_compute_quantities', store=True) |
||||
|
qty_virtual = fields.Float(string='Virtual Qty', |
||||
|
compute='_compute_quantities', store=True) |
||||
|
|
||||
|
def _compute_quantities_dict(self, lot_id, owner_id, package_id, |
||||
|
from_date=False, to_date=False): |
||||
|
"""Function for computing the incoming, outgoing,available, and virtual |
||||
|
quantities for the product""" |
||||
|
res = super()._compute_quantities_dict(lot_id, owner_id, package_id, |
||||
|
from_date=False, to_date=False) |
||||
|
for product in self.with_context(prefetch_fields=False): |
||||
|
product_id = product.id |
||||
|
product.qty_incoming = res[product_id]['incoming_qty'] |
||||
|
product.qty_outgoing = res[product_id]['outgoing_qty'] |
||||
|
product.qty_avail = res[product_id]['qty_available'] |
||||
|
product.qty_virtual = res[product_id]['virtual_available'] |
||||
|
return res |
@ -0,0 +1,52 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Nihala KP(odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from odoo import fields, models, _ |
||||
|
|
||||
|
|
||||
|
class ProductTemplate(models.Model): |
||||
|
"""Inherited product template to add additional fields and compute methods |
||||
|
for quantity computation""" |
||||
|
_inherit = 'product.template' |
||||
|
|
||||
|
qty_incoming = fields.Float(string='Incoming Qty', |
||||
|
compute='_compute_quantities', store=True, |
||||
|
help='Incoming quantity of the product') |
||||
|
qty_outgoing = fields.Float(string='Outgoing Qty', |
||||
|
compute='_compute_quantities', store=True, |
||||
|
help='Outgoing quantity of the product') |
||||
|
qty_avail = fields.Float(string='Available Qty', |
||||
|
compute='_compute_quantities', store=True, |
||||
|
help='Available quantity of the product') |
||||
|
qty_virtual = fields.Float(string='Virtual Qty', |
||||
|
compute='_compute_quantities', store=True, |
||||
|
help='Virtual quantity of the product') |
||||
|
|
||||
|
def _compute_quantities(self): |
||||
|
"""Function for computing the incoming, outgoing,available, and virtual |
||||
|
quantities for the product template""" |
||||
|
res = super()._compute_quantities() |
||||
|
for template in self: |
||||
|
template.qty_incoming = template.incoming_qty |
||||
|
template.qty_outgoing = template.outgoing_qty |
||||
|
template.qty_avail = template.qty_available |
||||
|
template.qty_virtual = template.virtual_available |
||||
|
return res |
@ -0,0 +1,65 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Nihala KP(odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from odoo import fields, models, tools |
||||
|
|
||||
|
|
||||
|
class StockLocationProduct(models.Model): |
||||
|
""" Model for generating pivot view based on product locations""" |
||||
|
_name = 'stock.location.product' |
||||
|
_description = "Product Location Report" |
||||
|
_auto = False |
||||
|
|
||||
|
product_id = fields.Many2one('product.template', string="Product", |
||||
|
help='Name of the product') |
||||
|
location_id = fields.Many2one('stock.location', string='Location', |
||||
|
help='Choose the location') |
||||
|
on_hand_qty = fields.Integer(string='On Hand Quantity', |
||||
|
help='On hand quantity of the product') |
||||
|
qty_incoming = fields.Integer(string='Incoming Quantity', |
||||
|
help='Incoming quantity of the product') |
||||
|
qty_outgoing = fields.Integer(string='Outgoing Quantity', |
||||
|
help='Outgoing quantity of the product') |
||||
|
forecast_qty = fields.Integer(string='Forecast Quantity', |
||||
|
help='Forecasted quantity of the product') |
||||
|
|
||||
|
def init(self): |
||||
|
"""Initialize the view. Drops the existing view if it exists and |
||||
|
creates a new view with the following columns for the Product model""" |
||||
|
tools.drop_view_if_exists(self._cr, self._table) |
||||
|
self._cr.execute(''' CREATE OR REPLACE VIEW %s AS ( |
||||
|
SELECT row_number() OVER () AS id, |
||||
|
product_template.id AS product_id, |
||||
|
stock_location.id AS location_id, |
||||
|
SUM(stock_quant.quantity) AS on_hand_qty, |
||||
|
SUM(stock_quant.quantity + |
||||
|
product_template.qty_incoming - product_template.qty_outgoing) |
||||
|
AS forecast_qty, |
||||
|
SUM(product_template.qty_incoming) AS qty_incoming, |
||||
|
SUM(product_template.qty_outgoing) AS qty_outgoing |
||||
|
FROM product_template |
||||
|
INNER JOIN product_product ON |
||||
|
product_product.product_tmpl_id = product_template.id |
||||
|
INNER JOIN stock_quant ON stock_quant.product_id = product_product.id |
||||
|
INNER JOIN stock_location ON |
||||
|
stock_quant.location_id = stock_location.id |
||||
|
WHERE stock_location.usage = 'internal' |
||||
|
GROUP BY product_template.id, stock_location.id)''' % (self._table,)) |
@ -0,0 +1,65 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Nihala KP(odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from odoo import fields, models, tools |
||||
|
|
||||
|
|
||||
|
class StockLocationProductVariant(models.Model): |
||||
|
""" Model for generating pivot view for product variants based on product |
||||
|
locations""" |
||||
|
_name = 'stock.location.product.variant' |
||||
|
_description = "Product Variant Location Report" |
||||
|
_auto = False |
||||
|
|
||||
|
product_id = fields.Many2one('product.product', string="Product", |
||||
|
help='Name of the product') |
||||
|
location_id = fields.Many2one('stock.location', string='Location', |
||||
|
help='Choose the location') |
||||
|
on_hand_qty = fields.Integer(string='On Hand Quantity', |
||||
|
help='On hand quantity of the product') |
||||
|
qty_incoming = fields.Integer(string='Incoming Quantity', |
||||
|
help='Incoming quantity of the product') |
||||
|
qty_outgoing = fields.Integer(string='Outgoing Quantity', |
||||
|
help='Outgoing quantity of the product') |
||||
|
forecast_qty = fields.Integer(string='Forecast Quantity', |
||||
|
help='Forecasted quantity of the product') |
||||
|
|
||||
|
def init(self): |
||||
|
"""Initialize the view. Drops the existing view if it exists and |
||||
|
creates a new view with the following columns for the Product variant |
||||
|
model""" |
||||
|
tools.drop_view_if_exists(self._cr, self._table) |
||||
|
self._cr.execute(''' CREATE OR REPLACE VIEW %s AS ( |
||||
|
select row_number() OVER () as id, |
||||
|
stock_quant.product_id, |
||||
|
stock_quant.location_id, |
||||
|
stock_quant.quantity on_hand_qty, |
||||
|
(stock_quant.quantity + |
||||
|
product_product.qty_incoming - product_product.qty_outgoing) |
||||
|
AS forecast_qty, |
||||
|
product_product.qty_incoming, |
||||
|
product_product.qty_outgoing from product_product |
||||
|
inner JOIN stock_quant on stock_quant.product_id = product_product.id |
||||
|
inner join product_template on |
||||
|
product_product.product_tmpl_id = product_template.id |
||||
|
inner join stock_location on |
||||
|
stock_quant.location_id = stock_location.id |
||||
|
where stock_location.usage = 'internal')''' % (self._table,)) |
@ -0,0 +1,22 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Nihala KP(odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from . import stock_location_report |
@ -0,0 +1,108 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Nihala KP(odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from odoo import api, models |
||||
|
from odoo.tools import groupby |
||||
|
|
||||
|
|
||||
|
class StockLocationReport(models.AbstractModel): |
||||
|
"""To generate report based on query and get report values""" |
||||
|
_name = "report.stock_analysis_by_location_report.report_stock_location" |
||||
|
|
||||
|
@api.model |
||||
|
def _get_report_values(self, docids, data=None): |
||||
|
""" To get the report values based on the user giving conditions""" |
||||
|
value = self.query_data(data['report_type'], data['product_id'], |
||||
|
data['product_variant_id']) |
||||
|
grouped_data = {} |
||||
|
for product_id, group in ( |
||||
|
groupby(value, key=lambda x: x['product']['en_US'])): |
||||
|
grouped_data[product_id] = list(group) |
||||
|
return { |
||||
|
'grouped_data': grouped_data, |
||||
|
'var': value |
||||
|
} |
||||
|
|
||||
|
def query_data(self, report_type, product_id, product_variant_id): |
||||
|
""" To fetch values from database using query""" |
||||
|
|
||||
|
if report_type == 'product': |
||||
|
query = """SELECT row_number() OVER () AS id, |
||||
|
product_template.name AS product, |
||||
|
stock_location.complete_name AS location, |
||||
|
SUM(stock_quant.quantity) AS on_hand_qty, |
||||
|
SUM(stock_quant.quantity + |
||||
|
product_template.qty_incoming - product_template.qty_outgoing) |
||||
|
AS forecast_qty, |
||||
|
SUM(product_template.qty_incoming) AS qty_incoming, |
||||
|
SUM(product_template.qty_outgoing) AS qty_outgoing |
||||
|
FROM product_template |
||||
|
INNER JOIN product_product ON |
||||
|
product_product.product_tmpl_id = product_template.id |
||||
|
INNER JOIN stock_quant ON |
||||
|
stock_quant.product_id = product_product.id |
||||
|
INNER JOIN stock_location ON |
||||
|
stock_quant.location_id = stock_location.id |
||||
|
WHERE stock_location.usage = 'internal' |
||||
|
GROUP BY product_template.id, stock_location.id""" |
||||
|
if product_id: |
||||
|
query = """SELECT row_number() OVER () AS id, |
||||
|
product_template.name AS product, |
||||
|
stock_location.complete_name AS location, |
||||
|
SUM(stock_quant.quantity) AS on_hand_qty, |
||||
|
SUM(stock_quant.quantity + |
||||
|
product_template.qty_incoming - product_template.qty_outgoing) |
||||
|
AS forecast_qty, |
||||
|
SUM(product_template.qty_incoming) AS qty_incoming, |
||||
|
SUM(product_template.qty_outgoing) AS qty_outgoing |
||||
|
FROM product_template |
||||
|
INNER JOIN product_product ON |
||||
|
product_product.product_tmpl_id = product_template.id |
||||
|
INNER JOIN stock_quant ON |
||||
|
stock_quant.product_id = product_product.id |
||||
|
INNER JOIN stock_location ON |
||||
|
stock_quant.location_id = stock_location.id |
||||
|
WHERE stock_location.usage = 'internal' |
||||
|
and product_template.id=%(product_id)s |
||||
|
GROUP BY product_template.id, stock_location.id""" |
||||
|
else: |
||||
|
query = """select product_template.name as Product, |
||||
|
stock_location.complete_name as Location, |
||||
|
stock_quant.quantity on_hand_qty, |
||||
|
(stock_quant.quantity + |
||||
|
product_product.qty_incoming - product_product.qty_outgoing) |
||||
|
AS forecast_qty, product_product.qty_incoming, |
||||
|
product_product.qty_outgoing from product_product |
||||
|
inner JOIN stock_quant on |
||||
|
stock_quant.product_id = product_product.id |
||||
|
inner join product_template |
||||
|
on product_product.product_tmpl_id = product_template.id |
||||
|
inner join stock_location on |
||||
|
stock_quant.location_id = stock_location.id |
||||
|
where stock_location.usage = 'internal'""" |
||||
|
if product_variant_id: |
||||
|
query += """ and product_id=%(product_variant_id)s""" |
||||
|
self.env.cr.execute(query, |
||||
|
{'report_type': report_type, |
||||
|
'product_id': product_id, |
||||
|
'product_variant_id': product_variant_id, |
||||
|
}) |
||||
|
return self.env.cr.dictfetchall() |
@ -0,0 +1,13 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<!--Report action for stock analysis by location--> |
||||
|
<record id="stock_by_location_report" model="ir.actions.report"> |
||||
|
<field name="name">Stock Location Report</field> |
||||
|
<field name="model">stock.move</field> |
||||
|
<field name="report_type">qweb-pdf</field> |
||||
|
<field name="report_name">stock_analysis_by_location_report.report_stock_location</field> |
||||
|
<field name="report_file">stock_analysis_by_location_report.report_stock_location</field> |
||||
|
<field name="print_report_name">'Stock Location Report - %s'</field> |
||||
|
<field name="binding_type">report</field> |
||||
|
</record> |
||||
|
</odoo> |
@ -0,0 +1,70 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<!--Templates for the stock location report--> |
||||
|
<template id="report_stock_location"> |
||||
|
<t t-call="web.html_container"> |
||||
|
<t t-call="web.external_layout"> |
||||
|
<div class="page"> |
||||
|
<h2>Stock Location Report</h2> |
||||
|
<div> |
||||
|
<strong>Report Date:</strong> |
||||
|
<span t-esc="datetime.datetime.now().strftime('%Y-%m-%d')"/> |
||||
|
</div> |
||||
|
<table class="table"> |
||||
|
<thead style="width:max-content"> |
||||
|
<tr> |
||||
|
<th>Product Name</th> |
||||
|
<th>Location</th> |
||||
|
<th>OnHand Quantity</th> |
||||
|
<th>Incoming Quantity</th> |
||||
|
<th>Outgoing Quantity</th> |
||||
|
<th>Forecast Quantity</th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
<tbody style="text-align:center;"> |
||||
|
<t t-foreach="grouped_data.items()" t-as="group"> |
||||
|
<t t-set="product_id" t-value="group[0]"/> |
||||
|
<t t-set="product_data" t-value="group[1]"/> |
||||
|
<t t-foreach="product_data" t-as="data"> |
||||
|
<tr> |
||||
|
<td t-esc="product_id"/> |
||||
|
<td t-esc="data['location']"/> |
||||
|
<td t-esc="data['on_hand_qty']"/> |
||||
|
<td t-esc="data['qty_incoming']"/> |
||||
|
<td t-esc="data['qty_outgoing']"/> |
||||
|
<td t-esc="data['forecast_qty']"/> |
||||
|
</tr> |
||||
|
</t> |
||||
|
<tr> |
||||
|
<td colspan="2" style="text-align: right;"> |
||||
|
<strong>Total:</strong> |
||||
|
</td> |
||||
|
<td> |
||||
|
<strong> |
||||
|
<t t-esc="sum([x['on_hand_qty'] for x in product_data])"/> |
||||
|
</strong> |
||||
|
</td> |
||||
|
<td> |
||||
|
<strong> |
||||
|
<t t-esc="sum([x['qty_incoming'] for x in product_data])"/> |
||||
|
</strong> |
||||
|
</td> |
||||
|
<td> |
||||
|
<strong> |
||||
|
<t t-esc="sum([x['qty_outgoing'] for x in product_data])"/> |
||||
|
</strong> |
||||
|
</td> |
||||
|
<td> |
||||
|
<strong> |
||||
|
<t t-esc="sum([x['forecast_qty'] for x in product_data])"/> |
||||
|
</strong> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</t> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
</div> |
||||
|
</t> |
||||
|
</t> |
||||
|
</template> |
||||
|
</odoo> |
|
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 310 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 576 B |
After Width: | Height: | Size: 733 B |
After Width: | Height: | Size: 911 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 673 B |
After Width: | Height: | Size: 878 B |
After Width: | Height: | Size: 653 B |
After Width: | Height: | Size: 905 B |
After Width: | Height: | Size: 839 B |
After Width: | Height: | Size: 427 B |
After Width: | Height: | Size: 627 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 988 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 80 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 589 B |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 565 B |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 967 B |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 43 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 47 KiB |
After Width: | Height: | Size: 46 KiB |
After Width: | Height: | Size: 85 KiB |
After Width: | Height: | Size: 85 KiB |
After Width: | Height: | Size: 49 KiB |
After Width: | Height: | Size: 90 KiB |
After Width: | Height: | Size: 42 KiB |
After Width: | Height: | Size: 96 KiB |
After Width: | Height: | Size: 111 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 99 KiB |
After Width: | Height: | Size: 104 KiB |
After Width: | Height: | Size: 114 KiB |
After Width: | Height: | Size: 106 KiB |
After Width: | Height: | Size: 98 KiB |
After Width: | Height: | Size: 107 KiB |
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 106 KiB |
After Width: | Height: | Size: 436 KiB |
After Width: | Height: | Size: 93 KiB |
After Width: | Height: | Size: 6.1 KiB |
@ -0,0 +1,768 @@ |
|||||
|
<!DOCTYPE html> |
||||
|
<html lang="en"> |
||||
|
<head> |
||||
|
<meta charset="UTF-8"> |
||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
|
<title>Odoo App 3 Index</title> |
||||
|
<!-- Bootstrap CSS --> |
||||
|
<link rel="stylesheet" |
||||
|
href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css" |
||||
|
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" |
||||
|
crossorigin="anonymous"> |
||||
|
<link rel="stylesheet" |
||||
|
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css"> |
||||
|
<link rel="preconnect" href="https://fonts.googleapis.com"> |
||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> |
||||
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" |
||||
|
rel="stylesheet"> |
||||
|
</head> |
||||
|
<body> |
||||
|
<section> |
||||
|
<div class="container" |
||||
|
style="font-family: 'Inter', sans-serif !important;background-color: #fff !important;"> |
||||
|
<div class="row"> |
||||
|
<div class="col-sm-12 col-md-12 col-lg-12 d-flex justify-content-between flex-wrap align-items-sm-center" |
||||
|
style="border-bottom:1px solid rgba(0, 0, 0, 0.22)"> |
||||
|
<div class="my-3"> |
||||
|
<img src="assets/misc/Cybrosys R.png" |
||||
|
style="width:auto !important; height:40px !important"> |
||||
|
</div> |
||||
|
<div class="my-3 d-flex align-items-center"> |
||||
|
<div class="text-center" |
||||
|
style="background-color:#017E84 !important;font-size: 0.8rem !important; color:#fff !important; font-weight:500 !important; padding:4px !important; margin:0 3px !important; border-radius:50px !important; min-width: 120px !important;"> |
||||
|
Community |
||||
|
</div> |
||||
|
<div class="text-center" |
||||
|
style="background-color:#875A7B !important; color:#fff !important;font-size: 0.8rem !important; font-weight:500 !important; padding:4px !important; margin:0 3px !important; border-radius:50px !important;min-width: 120px !important;"> |
||||
|
Enterprise |
||||
|
</div> |
||||
|
<div class="text-center" |
||||
|
style="background-color:#7C7BAD !important; color:#fff !important;font-size: 0.8rem !important; font-weight:500 !important; padding:4px !important; margin:0 3px !important; border-radius:50px !important; min-width: 120px !important;"> |
||||
|
Odoo.sh |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="row"> |
||||
|
<div class="col-sm-12 col-md-12 col-lg-12 text-center d-flex align-items-center flex-column" |
||||
|
style="margin: 80px 0px !important;"> |
||||
|
<h1 style="font-size: 2.8rem;font-weight: 700; color: |
||||
|
#1A202C;"> |
||||
|
Stock Analysis By Location Report </h1> |
||||
|
<p class="my-3 mb-4" |
||||
|
style="max-width: 80%; font-weight: 400 !important; line-height: 32px; color: #718096;"> |
||||
|
This Module Helps To Analyse The Product Quantities And |
||||
|
Movements Across Various Locations. </p> |
||||
|
<!-- END OF APP HERO --> |
||||
|
<div style="width: 80%; margin-top: 3rem;"> |
||||
|
<img src="assets/screenshots/hero-v17.gif" |
||||
|
class="img-responsive" width="100%" height="auto"> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="container mt-5 mb-5"> |
||||
|
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center mt-4"> |
||||
|
<p class="m-0" |
||||
|
style="font-weight: 600; font-size: 24px; color:#714b67 !important"> |
||||
|
Key Highlights |
||||
|
</p> |
||||
|
</div> |
||||
|
<div class="row py-4"> |
||||
|
<div class="col-md-12 col-sm-12 p-3"> |
||||
|
<div class="d-flex h-100" style="padding: 30px;border-radius: 12px; |
||||
|
background: #FFF; |
||||
|
box-shadow: 1px 2px 3px 0px rgba(0, 0, 0, 0.25); "> |
||||
|
<div style="width: 36px; height: 36px; border-radius: 50%; background: #714B67; |
||||
|
display: flex; justify-content: center; align-items: center; |
||||
|
margin-right: 10px; flex-shrink: 0;"> |
||||
|
<i class="fa-solid fa-star " |
||||
|
style="color: #fff;font-size:14px;"></i> |
||||
|
</div> |
||||
|
<div> |
||||
|
<p style="color: #1A202C;font-weight: 600; |
||||
|
font-size: 1.2rem; margin-bottom: 2px;"> |
||||
|
Overview</p> |
||||
|
<p class="m-0" style="color:#718096"> This module |
||||
|
helps to provide an overview of Inventory Levels |
||||
|
and Movements based on Locations.It enables |
||||
|
Stakeholders to Analyze Stock Availability, |
||||
|
Incoming and Outgoing Quantities, and Virtual |
||||
|
Quantities across various Stock Locations, |
||||
|
aiding in Strategic Decision-making regarding |
||||
|
Inventory Management, Replenishment, and |
||||
|
Distribution. </p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="container rounded"> |
||||
|
<ul class="nav nav-tabs d-flex" |
||||
|
style="width: fit-content;margin: 0 auto;gap: 1rem;"> |
||||
|
<li class="col text-center py-2 text-nowrap " |
||||
|
style="color: #fff; background-color: #714B67;border-radius: 6px 6px 0px 0px;"> |
||||
|
<a |
||||
|
class="active show" data-toggle="tab" href="#tab1" |
||||
|
style="color: #fff;font-weight: 500; background-color: #714B67; text-decoration: none;"> |
||||
|
<i class="fa-regular fa-image pr-2" |
||||
|
style="color: #fff;"></i> |
||||
|
Screenshots</a></li> |
||||
|
<li class="col text-center py-2 text-nowrap " |
||||
|
style="color: #fff; background-color: #714B67;border-radius: 6px 6px 0px 0px;"> |
||||
|
<a |
||||
|
data-toggle="tab" href="#tab2" |
||||
|
style="color: #fff;font-weight: 500; text-decoration: none;"><i |
||||
|
class="fa-solid fa-star pr-2" |
||||
|
style="color: #fff;"></i>Features</a></li> |
||||
|
<li class="col text-center py-2 text-nowrap " |
||||
|
style="color: #fff; background-color: #714B67;border-radius: 6px 6px 0px 0px;"> |
||||
|
<a |
||||
|
data-toggle="tab" href="#tab3" |
||||
|
style="color: #fff;font-weight: 500; text-decoration: none; background-color: #714B67;"><i |
||||
|
class="fa-solid fa-book-open pr-2" |
||||
|
style="color: #fff;"></i>Released Notes</a></li> |
||||
|
</ul> |
||||
|
<div class="tab-content" |
||||
|
style="background-color: rgba(121, 113, 119, 0.04);"> |
||||
|
<div id="tab1" class="tab-pane fade in active show"> |
||||
|
<div class="col-lg-12 py-2" |
||||
|
style="padding: 1rem 4rem !important;"> |
||||
|
<div |
||||
|
style="border: 1px solid #d8d6d6; border-radius: 4px; background: #fff; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<div class="row justify-content-center p-3 w-100 m-0"> |
||||
|
<img src="assets/screenshots/1.png" |
||||
|
class="img-responsive" width="100%" |
||||
|
height="auto"> |
||||
|
|
||||
|
</div> |
||||
|
<div class="px-3"> |
||||
|
<h4 class="mt-2" |
||||
|
style=" font-weight:600 !important; color:#282F33 !important; font-size:1.3rem !important"> |
||||
|
A new menu has been added to access the view of stock locations and reports.</h4> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-lg-12 py-2" |
||||
|
style="padding: 1rem 4rem !important;"> |
||||
|
<div |
||||
|
style="border: 1px solid #d8d6d6; border-radius: 4px; background: #fff; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<div class="row justify-content-center p-3 w-100 m-0"> |
||||
|
<img src="assets/screenshots/2.png" |
||||
|
class="img-responsive" width="100%" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
<div class="px-3"> |
||||
|
<h4 class="mt-2" |
||||
|
style=" font-weight:600 !important; color:#282F33 !important; font-size:1.3rem !important"> |
||||
|
By clicking on "Products," you can access the pivot view for product stock based on location. </h4> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-lg-12 py-2" |
||||
|
style="padding: 1rem 4rem !important;"> |
||||
|
<div |
||||
|
style="border: 1px solid #d8d6d6; border-radius: 4px; background: #fff; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<div class="row justify-content-center p-3 w-100 m-0"> |
||||
|
<img src="assets/screenshots/3.png" |
||||
|
class="img-responsive" width="100%" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
<div class="px-3"> |
||||
|
<h4 class="mt-2" |
||||
|
style=" font-weight:600 !important; color:#282F33 !important; font-size:1.3rem !important"> |
||||
|
By clicking on "Product Variants," you can access the pivot view for the stock of product variants based on location.</h4> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-lg-12 py-2" |
||||
|
style="padding: 1rem 4rem !important;"> |
||||
|
<div |
||||
|
style="border: 1px solid #d8d6d6; border-radius: 4px; background: #fff; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<div class="row justify-content-center p-3 w-100 m-0"> |
||||
|
<img src="assets/screenshots/4.png" |
||||
|
class="img-responsive" width="100%" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
<div class="row justify-content-center p-3 w-100 m-0"> |
||||
|
<img src="assets/screenshots/5.png" |
||||
|
class="img-responsive" width="100%" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
<div class="px-3"> |
||||
|
<h4 class="mt-2" |
||||
|
style=" font-weight:600 !important; color:#282F33 !important; font-size:1.3rem !important"> |
||||
|
When you click on the "Stock Location Reports" menu item, a wizard will open for selecting the required options.</h4> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-lg-12 py-2" |
||||
|
style="padding: 1rem 4rem !important;"> |
||||
|
<div |
||||
|
style="border: 1px solid #d8d6d6; border-radius: 4px; background: #fff; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<div class="row justify-content-center p-3 w-100 m-0"> |
||||
|
<img src="assets/screenshots/6.png" |
||||
|
class="img-responsive" width="100%" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
<div class="px-3"> |
||||
|
<h4 class="mt-2" |
||||
|
style=" font-weight:600 !important; color:#282F33 !important; font-size:1.3rem !important"> |
||||
|
By selecting "Product" as the report type and clicking on the "Print PDF" button, you can generate a PDF report of product information based on location. Below is a sample report. </h4> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-lg-12 py-2" |
||||
|
style="padding: 1rem 4rem !important;"> |
||||
|
<div |
||||
|
style="border: 1px solid #d8d6d6; border-radius: 4px; background: #fff; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<div class="row justify-content-center p-3 w-100 m-0"> |
||||
|
<img src="assets/screenshots/7.png" |
||||
|
class="img-responsive" width="100%" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
<div class="row justify-content-center p-3 w-100 m-0"> |
||||
|
<img src="assets/screenshots/8.png" |
||||
|
class="img-responsive" width="100%" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
<div class="px-3"> |
||||
|
<h4 class="mt-2" |
||||
|
style=" font-weight:600 !important; color:#282F33 !important; font-size:1.3rem !important"> |
||||
|
By selecting "Product" as the report type and choosing a specific product, then clicking on the "Print PDF" button, you can generate a PDF report of the specific product's information based on location. Below is a sample report. </h4> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-lg-12 py-2" |
||||
|
style="padding: 1rem 4rem !important;"> |
||||
|
<div |
||||
|
style="border: 1px solid #d8d6d6; border-radius: 4px; background: #fff; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<div class="row justify-content-center p-3 w-100 m-0"> |
||||
|
<img src="assets/screenshots/9.png" |
||||
|
class="img-responsive" width="100%" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
<div class="row justify-content-center p-3 w-100 m-0"> |
||||
|
<img src="assets/screenshots/10.png" |
||||
|
class="img-responsive" width="100%" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
<div class="px-3"> |
||||
|
<h4 class="mt-2" |
||||
|
style=" font-weight:600 !important; color:#282F33 !important; font-size:1.3rem !important"> |
||||
|
By clicking on the "Print XLSX" button, you can obtain the product's stock report based on location in Excel format. </h4> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-lg-12 py-2" |
||||
|
style="padding: 1rem 4rem !important;"> |
||||
|
<div |
||||
|
style="border: 1px solid #d8d6d6; border-radius: 4px; background: #fff; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<div class="row justify-content-center p-3 w-100 m-0"> |
||||
|
<img src="assets/screenshots/11.png" |
||||
|
class="img-responsive" width="100%" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
<div class="row justify-content-center p-3 w-100 m-0"> |
||||
|
<img src="assets/screenshots/12.png" |
||||
|
class="img-responsive" width="100%" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
<div class="px-3"> |
||||
|
<h4 class="mt-2" |
||||
|
style=" font-weight:600 !important; color:#282F33 !important; font-size:1.3rem !important"> |
||||
|
By selecting the specific product variant as the report type and clicking on the "Print XLSX" button, you can generate an XLSX report of the specific product variant's information based on location. Below is the sample report. </h4> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
<div id="tab2" class="tab-pane fade"> |
||||
|
<div class="col-mg-12" style="padding: 1rem 4rem;"> |
||||
|
<ul style="list-style: none; padding: 1rem 0;font-weight: 500;"> |
||||
|
<li class="py-3" |
||||
|
style="font-weight: 500;background-color: #fff; border-radius: 4px; padding: 1rem; margin-bottom: 1rem; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<span style="margin-right: 12px;"><img |
||||
|
src="assets/misc/star (1) 2.svg" |
||||
|
alt="" |
||||
|
width="16px"></span>Location wise |
||||
|
Inventory Analysis |
||||
|
</li> |
||||
|
<li class="py-3" |
||||
|
style="font-weight: 500;background-color: #fff; border-radius: 4px; padding: 1rem; margin-bottom: 1rem; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<span style="margin-right: 12px;"><img |
||||
|
src="assets/misc/star (1) 2.svg" |
||||
|
alt="" |
||||
|
width="16px"></span>Real Time |
||||
|
Updates |
||||
|
</li> |
||||
|
<li class="py-3" |
||||
|
style="font-weight: 500;background-color: #fff; border-radius: 4px; padding: 1rem; margin-bottom: 1rem; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<span style="margin-right: 12px;"><img |
||||
|
src="assets/misc/star (1) 2.svg" |
||||
|
alt="" |
||||
|
width="16px"></span> Generate |
||||
|
Reports of Stock based on Location |
||||
|
</li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div id="tab3" class="tab-pane fade"> |
||||
|
<div class="col-mg-12 active" style="padding: 1rem 4rem;"> |
||||
|
<div class="py-3" |
||||
|
style="font-weight: 500;background-color: #fff; border-radius: 4px; padding: 1rem; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<div class="d-flex mb-3" |
||||
|
style="font-size: 0.8rem; font-weight: 500;"><span>Version |
||||
|
17.0.1.0.0</span><span |
||||
|
class="px-2">|</span><span |
||||
|
style="color: #714B67;font-weight: 600;">Released on: 22nd April 2024</span> |
||||
|
</div> |
||||
|
<p class="m-0" |
||||
|
style=" color:#718096!important; font-size:1rem !important;line-height: 28px;"> |
||||
|
|
||||
|
Initial Commit for Stock Analysis By Location |
||||
|
Report</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="container mt-5"> |
||||
|
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center mt-5"> |
||||
|
<p class="m-0" |
||||
|
style="font-weight: 600; font-size: 24px; color:#000 !important"> |
||||
|
Related Products</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div id="myCarousel" class="carousel slide py-3" data-ride="carousel"> |
||||
|
<div class="carousel-inner"> |
||||
|
<div class="carousel-item active"> |
||||
|
<div class="row p-4"> |
||||
|
<div class="col"> |
||||
|
<div class="p-3"> |
||||
|
<a href="https://apps.odoo.com/apps/modules/17.0/invoice_stock_move/" |
||||
|
style="color: #000; text-decoration: none;"> |
||||
|
<div style="border:1px solid #CBCBCB !important;border-radius: 4px;"> |
||||
|
<div style="width: 300px; "> |
||||
|
<img src="assets/modules/1.png" |
||||
|
alt="" width="100%" |
||||
|
height="auto"> |
||||
|
<p class="text-center pt-2 text-black font-weight-bold"> |
||||
|
Stock Picking From Invoice</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col"> |
||||
|
<div class="p-3"> |
||||
|
<a href="https://apps.odoo.com/apps/modules/17.0/product_barcode/" |
||||
|
style="color: #000; text-decoration: none;"> |
||||
|
<div style="border:1px solid #CBCBCB !important;border-radius: 4px;"> |
||||
|
<div style="width: 300px; "> |
||||
|
<img src="assets/modules/2.png" |
||||
|
alt="" width="100%" |
||||
|
height="auto"> |
||||
|
|
||||
|
</div> |
||||
|
<p class="text-center pt-2 text-black font-weight-bold"> |
||||
|
Product Barcode Generator</p> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col"> |
||||
|
<div class="p-3"> |
||||
|
<a href="https://apps.odoo.com/apps/modules/17.0/low_stocks_product_alert/" |
||||
|
style="color: #000; text-decoration: none;"> |
||||
|
<div style="border:1px solid #CBCBCB !important;border-radius: 4px;"> |
||||
|
<div style="width: 300px; "> |
||||
|
<img src="assets/modules/3.jpg" |
||||
|
alt="" width="100%" |
||||
|
height="auto"> |
||||
|
|
||||
|
</div> |
||||
|
<p class="text-center pt-2 text-black font-weight-bold"> |
||||
|
Product Low Stock Alert</p> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="carousel-item"> |
||||
|
<div class="row p-4"> |
||||
|
<div class="col"> |
||||
|
<div class="p-3"> |
||||
|
<a href="https://apps.odoo.com/apps/modules/17.0/purchase_product_history/#" |
||||
|
style="color: #000; text-decoration: none;"> |
||||
|
<div style="border:1px solid #CBCBCB !important;border-radius: 4px;"> |
||||
|
<div style="width: 300px; "> |
||||
|
<img src="assets/modules/4.jpg" |
||||
|
alt="" width="100%" |
||||
|
height="auto"> |
||||
|
|
||||
|
</div> |
||||
|
<p class="text-center pt-2 text-black font-weight-bold"> |
||||
|
Purchase History Of Products</p> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col"> |
||||
|
<div class="p-3"> |
||||
|
<a href="https://apps.odoo.com/apps/modules/17.0/inventory_barcode_scanning/" |
||||
|
style="color: #000; text-decoration: none;"> |
||||
|
<div style="border:1px solid #CBCBCB !important;border-radius: 4px;"> |
||||
|
<div style="width: 300px;"> |
||||
|
<img src="assets/modules/5.png" |
||||
|
alt="" width="100%" |
||||
|
height="auto"> |
||||
|
|
||||
|
</div> |
||||
|
<p class="text-center pt-2 text-black font-weight-bold"> |
||||
|
Barcode scanning in Inventory</p> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col"> |
||||
|
<div class="p-3"> |
||||
|
<a href="https://apps.odoo.com/apps/modules/17.0/multiple_reference_per_product/" |
||||
|
style="color: #000; text-decoration: none;"> |
||||
|
<div style="border:1px solid #CBCBCB !important;border-radius: 4px;"> |
||||
|
<div style="width: 300px;"> |
||||
|
<img src="assets/modules/6.jpg" |
||||
|
alt="" width="100%" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
<p class="text-center pt-2 text-black font-weight-bold"> |
||||
|
Multiple Reference Per Product</p> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<a class="carousel-control-prev" href="#myCarousel" |
||||
|
data-slide="prev" style="width: 35px; color: #000;"> |
||||
|
<span class="carousel-control-prev-icon"> |
||||
|
<i class="fa fa-chevron-left" |
||||
|
style="font-size: 24px;"></i> |
||||
|
</span> |
||||
|
</a> |
||||
|
<a class="carousel-control-next" href="#myCarousel" |
||||
|
data-slide="next" style="width: 35px; color: #000;"> |
||||
|
<span class="carousel-control-next-icon"> |
||||
|
<i class="fa fa-chevron-right" |
||||
|
style="font-size: 24px;"></i> |
||||
|
</span> |
||||
|
</a> |
||||
|
</div> |
||||
|
<div class="container mt-5"> |
||||
|
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center mt-4"> |
||||
|
<p class="m-0" |
||||
|
style="font-weight: 600; font-size: 24px; color:#000 !important"> |
||||
|
Our Services</p> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="container my-5"> |
||||
|
<div class="row py-3"> |
||||
|
<div class="col-md-4 col-sm-6 px-4 py-4"> |
||||
|
<div |
||||
|
style="background-color: #fff; padding: 25px; text-align: center; box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 3px 0px, rgba(0, 0, 0, 0.06) 0px 1px 2px 0px; position: relative;border-radius: 4px;"> |
||||
|
<div style="position: absolute; top: 0%; left: 50%; transform: translate(-50%, -50%);"> |
||||
|
<div style="background-color:#13EA36 ; border-radius: 50%; padding: 15px; width: 68px; |
||||
|
height: 68px; display: inline-block; box-shadow:0px 4px 4px rgba(0, 0, 0, 0.25);"> |
||||
|
<img src="assets/icons/cogs.png" |
||||
|
alt="service-icon" width="38px" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<p style="margin-top: 20px; font-weight: bold;">Odoo |
||||
|
Customization</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-4 col-sm-6 px-4 py-4"> |
||||
|
<div |
||||
|
style="background-color: #fff; padding: 25px; text-align: center; box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 3px 0px, rgba(0, 0, 0, 0.06) 0px 1px 2px 0px; position: relative;border-radius: 4px;"> |
||||
|
<div style="position: absolute; top: 0%; left: 50%; transform: translate(-50%, -50%);"> |
||||
|
<div style="background-color:#DBC711; border-radius: 50%; padding: 15px; width: 68px; |
||||
|
height: 68px; display: inline-block; box-shadow:0px 4px 4px rgba(0, 0, 0, 0.25);"> |
||||
|
<img src="assets/icons/wrench.png" |
||||
|
alt="service-icon" width="38px" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<p style="margin-top: 20px; font-weight: bold;">Odoo |
||||
|
Implementation</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-4 col-sm-6 px-4 py-4"> |
||||
|
<div |
||||
|
style="background-color: #fff; padding: 25px; text-align: center; box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 3px 0px, rgba(0, 0, 0, 0.06) 0px 1px 2px 0px; position: relative; border-radius: 4px;"> |
||||
|
<div style="position: absolute; top: 0%; left: 50%; transform: translate(-50%, -50%);"> |
||||
|
<div style="background-color:#FF6B6B ; border-radius: 50%; padding: 15px; width: 68px; |
||||
|
height: 68px; display: inline-block; box-shadow:0px 4px 4px rgba(0, 0, 0, 0.25);"> |
||||
|
<img src="assets/icons/lifebuoy.png" |
||||
|
alt="service-icon" width="38px" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<p style="margin-top: 20px; font-weight: bold;">Odoo |
||||
|
Support</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-4 col-sm-6 px-4 py-4"> |
||||
|
<div |
||||
|
style="background-color: #fff; padding: 25px; text-align: center; box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 3px 0px, rgba(0, 0, 0, 0.06) 0px 1px 2px 0px; position: relative; border-radius: 4px;"> |
||||
|
<div style="position: absolute; top: 0%; left: 50%; transform: translate(-50%, -50%);"> |
||||
|
<div style="background-color:#FFA801 ; border-radius: 50%; padding: 15px; width: 68px; |
||||
|
height: 68px; display: inline-block; box-shadow:0px 4px 4px rgba(0, 0, 0, 0.25);"> |
||||
|
<img src="assets/icons/user.png" |
||||
|
alt="service-icon" width="38px" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<p style="margin-top: 20px; font-weight: bold;">Hire |
||||
|
Odoo Developer</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-4 col-sm-6 px-4 py-4"> |
||||
|
<div |
||||
|
style="background-color: #fff; padding: 25px; text-align: center; box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 3px 0px, rgba(0, 0, 0, 0.06) 0px 1px 2px 0px; position: relative; border-radius: 4px;"> |
||||
|
|
||||
|
<div style="position: absolute; top: 0%; left: 50%; transform: translate(-50%, -50%);"> |
||||
|
<div style="background-color:#54A0FF; border-radius: 50%; padding: 15px; width: 68px; |
||||
|
height: 68px; display: inline-block; box-shadow:0px 4px 4px rgba(0, 0, 0, 0.25);"> |
||||
|
<img src="assets/icons/puzzle.png" |
||||
|
alt="service-icon" width="38px" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<p style="margin-top: 20px; font-weight: bold;">Odoo |
||||
|
Integration</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-4 col-sm-6 px-4 py-4"> |
||||
|
<div |
||||
|
style="background-color: #fff; padding: 25px; text-align: center; box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 3px 0px, rgba(0, 0, 0, 0.06) 0px 1px 2px 0px; position: relative;border-radius: 4px;"> |
||||
|
<div style="position: absolute; top: 0%; left: 50%; transform: translate(-50%, -50%);"> |
||||
|
<div style="background-color:#6D7680 ; border-radius: 50%; padding: 15px; width: 68px; |
||||
|
height: 68px; display: inline-block; box-shadow:0px 4px 4px rgba(0, 0, 0, 0.25);"> |
||||
|
<img src="assets/icons/update.png" |
||||
|
alt="service-icon" width="38px" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<p style="margin-top: 20px; font-weight: bold;">Odoo |
||||
|
Migration</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-4 col-sm-6 px-4 py-4"> |
||||
|
<div |
||||
|
style="background-color: #fff; padding: 25px; text-align: center; box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 3px 0px, rgba(0, 0, 0, 0.06) 0px 1px 2px 0px; position: relative;border-radius: 4px;"> |
||||
|
<div style="position: absolute; top: 0%; left: 50%; transform: translate(-50%, -50%);"> |
||||
|
<div style="background-color:#786FA6 ; border-radius: 50%; padding: 15px; width: 68px; |
||||
|
height: 68px; display: inline-block; box-shadow:0px 4px 4px rgba(0, 0, 0, 0.25);"> |
||||
|
<img src="assets/icons/consultation.png" |
||||
|
alt="service-icon" width="38px" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<p style="margin-top: 20px; font-weight: bold;">Odoo |
||||
|
Consultancy</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-4 col-sm-6 px-4 py-4"> |
||||
|
<div |
||||
|
style="background-color: #fff; padding: 25px; text-align: center; box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 3px 0px, rgba(0, 0, 0, 0.06) 0px 1px 2px 0px;position: relative;border-radius: 4px;"> |
||||
|
<div style="position: absolute; top: 0%; left: 50%; transform: translate(-50%, -50%);"> |
||||
|
<div style="background-color:#F8A5C2 ; border-radius: 50%; padding: 15px; width: 68px; |
||||
|
height: 68px; display: inline-block; box-shadow:0px 4px 4px rgba(0, 0, 0, 0.25);"> |
||||
|
<img src="assets/icons/training.png" |
||||
|
alt="service-icon" width="38px" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<p style="margin-top: 20px; font-weight: bold;">Odoo |
||||
|
Implementation</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-4 col-sm-6 px-4 py-4"> |
||||
|
<div |
||||
|
style="background-color: #fff; padding: 25px; text-align: center; box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 3px 0px, rgba(0, 0, 0, 0.06) 0px 1px 2px 0px; position: relative;border-radius: 4px;"> |
||||
|
<div style="position: absolute; top: 0%; left: 50%; transform: translate(-50%, -50%);"> |
||||
|
<div style="background-color:#E6BE26; border-radius: 50%; padding: 15px; width: 68px; |
||||
|
height: 68px; display: inline-block; box-shadow:0px 4px 4px rgba(0, 0, 0, 0.25);"> |
||||
|
<img src="assets/icons/license.png" |
||||
|
alt="service-icon" width="38px" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<p style="margin-top: 20px; font-weight: bold;">Odoo |
||||
|
Licensing Consultancy</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="container mt-5"> |
||||
|
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center mt-4"> |
||||
|
<p class="m-0" |
||||
|
style="font-weight: 600; font-size: 24px; color:#000 !important"> |
||||
|
Our Industries</p> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="container"> |
||||
|
<div class="row my-5 py-4"> |
||||
|
<div class="col-md-3 col-sm-6 p-0"> |
||||
|
<div class="d-flex flex-column h-100 " |
||||
|
style="border-right: 1px solid rgb(209, 209, 209); border-bottom: 1px solid rgb(209, 209, 209); padding: 30px; box-shadow: 6px 0 10px rgba(228, 227, 227, 0.373);"> |
||||
|
<img src="assets/icons/trading-black.png" width="42px" |
||||
|
height="auto" alt=""> |
||||
|
<p style="color: #714B67;font-weight: 600; margin-top: 10px; |
||||
|
font-size: 1.2rem; margin-bottom: 2px;">Trading</p> |
||||
|
<p>Easily procure and sell your products</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-3 col-sm-6 p-0"> |
||||
|
<div class="d-flex flex-column h-100" |
||||
|
style="border-right: 1px solid rgb(209, 209, 209);border-bottom: 1px solid rgb(209, 209, 209); padding: 30px;"> |
||||
|
<img src="assets/icons/pos-black.png" width="42px" |
||||
|
height="auto" alt=""> |
||||
|
<p style="color: #714B67;font-weight: 600; margin-top: 10px; |
||||
|
font-size: 1.2rem; margin-bottom: 2px;">POS</p> |
||||
|
<p>Easy configuration and convivial experience</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-3 col-sm-6 p-0"> |
||||
|
<div class="d-flex flex-column h-100" |
||||
|
style="border-right: 1px solid rgb(209, 209, 209);border-bottom: 1px solid rgba(0, 0, 0, 0.2); padding: 30px; box-shadow: 0 5px 10px rgba(228, 227, 227, 0.373)"> |
||||
|
<img src="assets/icons/education-black.png" width="42px" |
||||
|
height="auto" alt=""> |
||||
|
<p style="color: #714B67;font-weight: 600; margin-top: 10px; |
||||
|
font-size: 1.2rem; margin-bottom: 2px;"> |
||||
|
Education</p> |
||||
|
<p>A platform for educational management</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-3 col-sm-6 p-0"> |
||||
|
<div class="d-flex flex-column h-100" |
||||
|
style="border-bottom: 1px solid rgb(209, 209, 209); padding: 30px; "> |
||||
|
<img src="assets/icons/manufacturing-black.png" |
||||
|
width="42px" height="auto" alt=""> |
||||
|
<p style="color: #714B67;font-weight: 600; margin-top: 10px; |
||||
|
font-size: 1.2rem; margin-bottom: 2px;"> |
||||
|
Manufacturing</p> |
||||
|
<p>Plan, track and schedule your operations</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-3 col-sm-6 p-0"> |
||||
|
<div class="d-flex flex-column h-100" |
||||
|
style="border-right: 1px solid rgb(209, 209, 209); padding: 30px;"> |
||||
|
<img src="assets/icons/ecom-black.png" width="42px" |
||||
|
height="auto" alt=""> |
||||
|
<p style="color: #714B67;font-weight: 600; margin-top: 10px; |
||||
|
font-size: 1.2rem; margin-bottom: 2px;">E-commerce & |
||||
|
Website</p> |
||||
|
<p>Mobile friendly, awe-inspiring product pages</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-3 col-sm-6 p-0"> |
||||
|
<div class="d-flex flex-column h-100" |
||||
|
style="border-right: 1px solid rgb(209, 209, 209); padding: 30px;box-shadow: 0 -5px 10px rgba(228, 227, 227, 0.373);"> |
||||
|
<img src="assets/icons/service-black.png" width="42px" |
||||
|
height="auto" alt=""> |
||||
|
<p style="color: #714B67;font-weight: 600; margin-top: 10px; |
||||
|
font-size: 1.2rem; margin-bottom: 2px;">Service |
||||
|
Management</p> |
||||
|
<p>Keep track of services and invoice</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-3 col-sm-6 p-0"> |
||||
|
<div class="d-flex flex-column h-100" |
||||
|
style="border-right: 1px solid rgb(209, 209, 209); padding: 30px; "> |
||||
|
<img src="assets/icons/restaurant-black.png" |
||||
|
width="42px" height="auto" alt=""> |
||||
|
<p style="color: #714B67;font-weight: 600; margin-top: 10px; |
||||
|
font-size: 1.2rem; margin-bottom: 2px;"> |
||||
|
Restaurant</p> |
||||
|
<p>Run your bar or restaurant methodically</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-3 col-sm-6 p-0"> |
||||
|
<div class="d-flex flex-column h-100" |
||||
|
style=" padding: 30px;box-shadow: -5px 0 10px rgba(228, 227, 227, 0.373);"> |
||||
|
<img src="assets/icons/hotel-black.png" width="42px" |
||||
|
height="auto" alt=""> |
||||
|
<p style="color: #714B67;font-weight: 600; margin-top: 10px; |
||||
|
font-size: 1.2rem; margin-bottom: 2px;">Hotel |
||||
|
Management</p> |
||||
|
<p>An all-inclusive hotel management application</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="container mt-5"> |
||||
|
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center mt-5"> |
||||
|
<p class="m-0" |
||||
|
style="font-weight: 600; font-size: 24px; color:#000 !important"> |
||||
|
Support</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="container my-5"> |
||||
|
<div class="row" style="background-color: #FFFAFE;"> |
||||
|
<div class="col-md-6 pb-4 d-flex align-items-center justify-content-center" |
||||
|
style="border-right: 1px solid #D9D9D9;"> |
||||
|
<div style="padding: 30px;"> |
||||
|
<div class="d-flex align-items-center"> |
||||
|
<img src="assets/misc/support (1) 1.svg" alt="" |
||||
|
width="60px" style="margin-right: 12px;"> |
||||
|
<div style="padding: 0px 8px;"> |
||||
|
<span |
||||
|
style="color: #714B67;font-size: 24px;font-weight: 600;padding-bottom: 1rem;">Need |
||||
|
Help?</span> |
||||
|
<p class="m-0" style="color:#718096;">Got |
||||
|
questions or need help? Get in touch.</p> |
||||
|
<div style="font-weight: 400;"><span><img |
||||
|
src="assets/misc/support-email.svg" |
||||
|
alt="" |
||||
|
width="18px" |
||||
|
style="filter: invert(1);margin-right: 0.8rem;"></span>odoo@cybrosys.com |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-6 pb-4 d-flex align-items-center justify-content-center"> |
||||
|
<div style="padding: 30px;"> |
||||
|
<div class="d-flex align-items-center"> |
||||
|
<img src="assets/misc/whatsapp 1.svg" alt="" |
||||
|
width="60px" style="margin-right: 12px;"> |
||||
|
<div> |
||||
|
<span style="color: #714B67;font-size: 24px;font-weight: 600;">WhatsApp</span> |
||||
|
<p class="m-0" style="color:#718096;">Say hi to |
||||
|
us on WhatsApp!</p> |
||||
|
<div style="font-weight: 400; font-size: 16px;"><span><img |
||||
|
src="assets/misc/phone.svg" |
||||
|
alt="" width="14px" |
||||
|
style="filter: invert(1); margin-right: 0.8rem;"></span>+91 |
||||
|
99456767686 |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
<!-- Optional JavaScript --> |
||||
|
<!-- jQuery first, then Popper.js, then Bootstrap JS --> |
||||
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> |
||||
|
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script> |
||||
|
</body> |
||||
|
</html> |
@ -0,0 +1,22 @@ |
|||||
|
/** @odoo-module */ |
||||
|
/** |
||||
|
* registers a new handler to generate xlsx report |
||||
|
*/ |
||||
|
import { registry } from "@web/core/registry"; |
||||
|
import { BlockUI } from "@web/core/ui/block_ui"; |
||||
|
import { session } from "@web/session"; |
||||
|
import { download } from "@web/core/network/download"; |
||||
|
registry.category("ir.actions.report handlers").add("xlsx", async (action) => { |
||||
|
if (action.report_type === 'xlsx') { |
||||
|
BlockUI; |
||||
|
var def = $.Deferred(); |
||||
|
await download({ |
||||
|
url: '/report_excel', |
||||
|
data: action.data, |
||||
|
success: def.resolve.bind(def), |
||||
|
error: (error) => this.call('crash_manager', 'rpc_error', error), |
||||
|
complete: this.unblockUI, |
||||
|
}); |
||||
|
return def; |
||||
|
} |
||||
|
}); |
@ -0,0 +1,26 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<!-- created menu in inventory for stock location reports --> |
||||
|
<menuitem id="menu_stock_location_report" |
||||
|
name="Stock Location Reports" |
||||
|
sequence="5" |
||||
|
parent="stock.menu_stock_root" |
||||
|
/> |
||||
|
<menuitem id="menu_product_variant_pivot_report" |
||||
|
name="Product Variant" |
||||
|
sequence="1" |
||||
|
action="product_variant_pivot_view_action" |
||||
|
parent="menu_stock_location_report" |
||||
|
/> |
||||
|
<menuitem id="menu_product_pivot_report" |
||||
|
name="Products" |
||||
|
sequence="0" |
||||
|
action="product_pivot_view_action" |
||||
|
parent="menu_stock_location_report" |
||||
|
/> |
||||
|
<menuitem id="menu_stock_location_report_pdf_excel" |
||||
|
name="Stock Location Reports" |
||||
|
parent="menu_stock_location_report" |
||||
|
action="stock_location_report_menu_action" |
||||
|
sequence="2"/> |
||||
|
</odoo> |
@ -0,0 +1,31 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<!-- Inherited Form view for product template to add the field in the view--> |
||||
|
<record id="product_template_form_view" model="ir.ui.view"> |
||||
|
<field name="name">product.template.view.form.inherit.stock.analysis.by.location.report</field> |
||||
|
<field name="model">product.template</field> |
||||
|
<field name="inherit_id" ref="product.product_template_form_view"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<xpath expr="//group//field[@name='list_price']" position="after"> |
||||
|
<field name="qty_incoming" invisible="1"/> |
||||
|
<field name="qty_outgoing" invisible="1"/> |
||||
|
<field name="qty_avail" invisible="1"/> |
||||
|
<field name="qty_virtual" invisible="1"/> |
||||
|
</xpath> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- Inherited Form view for product to add the field in the view--> |
||||
|
<record id="product_normal_form_view" model="ir.ui.view"> |
||||
|
<field name="name">product.product.view.form.inherit.stock.analysis.by.location.report</field> |
||||
|
<field name="model">product.product</field> |
||||
|
<field name="inherit_id" ref="product.product_normal_form_view"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<xpath expr="//field[@name='default_code']" position="after"> |
||||
|
<field name="qty_incoming" invisible="1"/> |
||||
|
<field name="qty_outgoing" invisible="1"/> |
||||
|
<field name="qty_avail" invisible="1"/> |
||||
|
<field name="qty_virtual" invisible="1"/> |
||||
|
</xpath> |
||||
|
</field> |
||||
|
</record> |
||||
|
</odoo> |
@ -0,0 +1,41 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<!-- Pivot view for product variants--> |
||||
|
<record id="stock_location_product_variant_view_pivot" model="ir.ui.view"> |
||||
|
<field name="name">stock.location.product.variant.view.pivot</field> |
||||
|
<field name="model">stock.location.product.variant</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<pivot string="Stock Location Report"> |
||||
|
<field name="product_id" type="row"/> |
||||
|
<field name="location_id" type="row"/> |
||||
|
<field name="on_hand_qty" type="measure"/> |
||||
|
<field name="qty_incoming" type="measure"/> |
||||
|
<field name="qty_outgoing" type="measure"/> |
||||
|
<field name="forecast_qty" type="measure"/> |
||||
|
</pivot> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- Tree view for product variants--> |
||||
|
<record id="product_variant_report_tree_view" model="ir.ui.view"> |
||||
|
<field name="name">stock_location_product_variant_view_tree</field> |
||||
|
<field name="model">stock.location.product.variant</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree sample="1"> |
||||
|
<field name="product_id"/> |
||||
|
<field name="location_id"/> |
||||
|
<field name="on_hand_qty"/> |
||||
|
<field name="qty_incoming"/> |
||||
|
<field name="qty_outgoing"/> |
||||
|
<field name="forecast_qty"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- Action for the pivot view for Product variants --> |
||||
|
<record model="ir.actions.act_window" |
||||
|
id="product_variant_pivot_view_action"> |
||||
|
<field name="name">Product Variants: Stock Location Report</field> |
||||
|
<field name="res_model">stock.location.product.variant</field> |
||||
|
<field name="view_mode">tree,form,pivot</field> |
||||
|
<field name="view_id" ref="stock_location_product_variant_view_pivot"/> |
||||
|
</record> |
||||
|
</odoo> |
@ -0,0 +1,40 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<!-- Pivot view for Products--> |
||||
|
<record id="stock_location_product_view_pivot" model="ir.ui.view"> |
||||
|
<field name="name">stock.location.product.view.pivot</field> |
||||
|
<field name="model">stock.location.product</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<pivot string="Stock Location Report"> |
||||
|
<field name="product_id" type="row"/> |
||||
|
<field name="location_id" type="row"/> |
||||
|
<field name="on_hand_qty" type="measure"/> |
||||
|
<field name="qty_incoming" type="measure"/> |
||||
|
<field name="qty_outgoing" type="measure"/> |
||||
|
<field name="forecast_qty" type="measure"/> |
||||
|
</pivot> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- Tree view for product report view--> |
||||
|
<record id="product_report_tree_view" model="ir.ui.view"> |
||||
|
<field name="name">stock_location_product_view_tree</field> |
||||
|
<field name="model">stock.location.product</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree sample="1"> |
||||
|
<field name="product_id"/> |
||||
|
<field name="location_id"/> |
||||
|
<field name="on_hand_qty"/> |
||||
|
<field name="qty_incoming"/> |
||||
|
<field name="qty_outgoing"/> |
||||
|
<field name="forecast_qty"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- Action for the pivot view for Products--> |
||||
|
<record model="ir.actions.act_window" id="product_pivot_view_action"> |
||||
|
<field name="name">Product: Stock Location Report</field> |
||||
|
<field name="res_model">stock.location.product</field> |
||||
|
<field name="view_mode">tree,form,pivot</field> |
||||
|
<field name="view_id" ref="stock_location_product_view_pivot"/> |
||||
|
</record> |
||||
|
</odoo> |
@ -0,0 +1,22 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Nihala KP(odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from . import stock_location_report |
@ -0,0 +1,147 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Nihala KP(odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
import io |
||||
|
import json |
||||
|
from odoo import fields, models, _ |
||||
|
from odoo.tools import date_utils, groupby |
||||
|
|
||||
|
try: |
||||
|
from odoo.tools.misc import xlsxwriter |
||||
|
except ImportError: |
||||
|
import xlsxwriter |
||||
|
|
||||
|
|
||||
|
class StockLocation(models.TransientModel): |
||||
|
"""Transient model to give the input values for the |
||||
|
generation of report values""" |
||||
|
_name = "stock.location.report" |
||||
|
_description = "Stock Location Report Wizard" |
||||
|
|
||||
|
report_type = fields.Selection([ |
||||
|
('product', 'Products'), |
||||
|
('product_variant', 'Product Variant') |
||||
|
], string="Report Type", default='product', |
||||
|
help="Choose the product type") |
||||
|
product_variant_id = fields.Many2one('product.product', |
||||
|
string="Product Variant", |
||||
|
help="choose the product variant of " |
||||
|
"which the detail should be" |
||||
|
" known") |
||||
|
product_id = fields.Many2one('product.template', string="Product", |
||||
|
help="choose the product of which the detail " |
||||
|
"should be known") |
||||
|
|
||||
|
def action_pdf_report(self): |
||||
|
""" To pass values in wizard""" |
||||
|
data = { |
||||
|
'model_id': self.id, |
||||
|
'report_type': self.report_type, |
||||
|
'product_id': self.product_id.id, |
||||
|
'product_variant_id': self.product_variant_id.id, |
||||
|
} |
||||
|
return self.env.ref( |
||||
|
'stock_analysis_by_location_report.stock_by_location_report').report_action( |
||||
|
None, data=data) |
||||
|
|
||||
|
def action_xlsx_report(self): |
||||
|
""" To print the XLSX report type""" |
||||
|
query = self.env[ |
||||
|
'report.stock_analysis_by_location_report.report_stock_location' |
||||
|
].query_data( |
||||
|
self.report_type, self.product_id.id, self.product_variant_id.id) |
||||
|
data = { |
||||
|
'report_type': self.report_type, |
||||
|
'product_id': self.product_id.id, |
||||
|
'product_variant_id': self.product_variant_id.id, |
||||
|
'var': query |
||||
|
} |
||||
|
return { |
||||
|
'type': 'ir.actions.report', |
||||
|
'data': {'model': 'stock.location.report', |
||||
|
'options': json.dumps(data, |
||||
|
default=date_utils.json_default), |
||||
|
'output_format': 'xlsx', |
||||
|
'report_name': 'Stock Location Report', |
||||
|
}, |
||||
|
'report_type': 'xlsx', |
||||
|
} |
||||
|
|
||||
|
def get_xlsx_report(self, data, response): |
||||
|
"""To get the report values for xlsx report""" |
||||
|
query_result = data['var'] |
||||
|
grouped_data = {} |
||||
|
for product_id, group in groupby(query_result, |
||||
|
key=lambda x: x['product']['en_US']): |
||||
|
grouped_data[product_id] = list(group) |
||||
|
output = io.BytesIO() |
||||
|
workbook = xlsxwriter.Workbook(output, {'in_memory': True}) |
||||
|
sheet = workbook.add_worksheet() |
||||
|
cell_format = workbook.add_format( |
||||
|
{'font_size': '12px', 'bold': True, 'align': 'center'}) |
||||
|
grey_cell_format = workbook.add_format( |
||||
|
{'bold': True, 'bg_color': '#D3D3D3', 'align': 'center'}) |
||||
|
head = workbook.add_format( |
||||
|
{'align': 'center', 'bold': True, 'font_size': '20px', |
||||
|
'bg_color': 'gray', }) |
||||
|
txt = workbook.add_format({'font_size': '10px', 'align': 'left'}) |
||||
|
txt_head = workbook.add_format({'font_size': '10px', 'align': 'left', |
||||
|
'bold': True}) |
||||
|
sheet.set_column(0, 0, 25) |
||||
|
sheet.set_column(1, 1, 25) |
||||
|
sheet.set_column(2, 2, 15) |
||||
|
sheet.set_column(3, 3, 15) |
||||
|
sheet.set_column(4, 4, 15) |
||||
|
sheet.set_column(5, 5, 15) |
||||
|
sheet.merge_range('A1:B1', 'Report Date:' + str(fields.Date.today()), |
||||
|
txt_head) |
||||
|
sheet.merge_range('A2:F3', 'STOCK LOCATION REPORT', head) |
||||
|
sheet.write('A6', 'Product', grey_cell_format) |
||||
|
sheet.write('B6', 'Location', grey_cell_format) |
||||
|
sheet.write('C6', 'Onhand Qty', grey_cell_format) |
||||
|
sheet.write('D6', 'Incoming Qty', grey_cell_format) |
||||
|
sheet.write('E6', 'Outgoing Qty', grey_cell_format) |
||||
|
sheet.write('F6', 'Forecast Qty', grey_cell_format) |
||||
|
row = 6 |
||||
|
for product_id, product_data in grouped_data.items(): |
||||
|
for data in product_data: |
||||
|
sheet.write(row, 0, product_id) |
||||
|
sheet.write(row, 1, data['location']) |
||||
|
sheet.write(row, 2, data['on_hand_qty']) |
||||
|
sheet.write(row, 3, data['qty_incoming']) |
||||
|
sheet.write(row, 4, data['qty_outgoing']) |
||||
|
sheet.write(row, 5, data['forecast_qty']) |
||||
|
row += 1 |
||||
|
sheet.write(row, 0, 'Total:', grey_cell_format) |
||||
|
sheet.write(row, 1, '', grey_cell_format) |
||||
|
sheet.write(row, 2, sum(x['on_hand_qty'] for x in product_data), |
||||
|
grey_cell_format) |
||||
|
sheet.write(row, 3, sum(x['qty_incoming'] for x in product_data), |
||||
|
grey_cell_format) |
||||
|
sheet.write(row, 4, sum(x['qty_outgoing'] for x in product_data), |
||||
|
grey_cell_format) |
||||
|
sheet.write(row, 5, sum(x['forecast_qty'] for x in product_data), |
||||
|
grey_cell_format) |
||||
|
row += 1 |
||||
|
workbook.close() |
||||
|
output.seek(0) |
||||
|
response.stream.write(output.read()) |
||||
|
output.close() |
@ -0,0 +1,35 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<!--Form view of wizard that opens to generate report--> |
||||
|
<record id="stock_location_report_view_form" model="ir.ui.view"> |
||||
|
<field name="name">stock.location.report.view</field> |
||||
|
<field name="model">stock.location.report</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="Stock Location Report"> |
||||
|
<group class="oe_title"> |
||||
|
<group> |
||||
|
<field name="report_type" widget="radio"/> |
||||
|
<field name="product_variant_id" invisible="report_type == 'product'"/> |
||||
|
<field name="product_id" invisible="report_type == 'product_variant'"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
<footer> |
||||
|
<button name="action_pdf_report" string="Print PDF" |
||||
|
type="object" class="btn-primary"/> |
||||
|
<button name="action_xlsx_report" string="PRINT XLSX" |
||||
|
type="object" class="btn-primary" disabled="0"/> |
||||
|
<button string="Cancel" class="btn-secondary" |
||||
|
special="cancel"/> |
||||
|
</footer> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!--Window action of stock location report--> |
||||
|
<record id="stock_location_report_menu_action" model="ir.actions.act_window"> |
||||
|
<field name="name">Stock Location PDF & Excel Report</field> |
||||
|
<field name="res_model">stock.location.report</field> |
||||
|
<field name="view_mode">form</field> |
||||
|
<field name="view_id" ref="stock_location_report_view_form"/> |
||||
|
<field name="target">new</field> |
||||
|
</record> |
||||
|
</odoo> |