Browse Source

Dec 21 : [ADD] Initial Commit 'pos_product_create_edit'

pull/254/merge
RisvanaCybro 1 year ago
parent
commit
91eba224de
  1. 46
      pos_product_create_edit/README.rst
  2. 21
      pos_product_create_edit/__init__.py
  3. 51
      pos_product_create_edit/__manifest__.py
  4. 6
      pos_product_create_edit/doc/RELEASE_NOTES.md
  5. BIN
      pos_product_create_edit/static/description/assets/icons/check.png
  6. BIN
      pos_product_create_edit/static/description/assets/icons/chevron.png
  7. BIN
      pos_product_create_edit/static/description/assets/icons/cogs.png
  8. BIN
      pos_product_create_edit/static/description/assets/icons/consultation.png
  9. BIN
      pos_product_create_edit/static/description/assets/icons/ecom-black.png
  10. BIN
      pos_product_create_edit/static/description/assets/icons/education-black.png
  11. BIN
      pos_product_create_edit/static/description/assets/icons/hotel-black.png
  12. BIN
      pos_product_create_edit/static/description/assets/icons/license.png
  13. BIN
      pos_product_create_edit/static/description/assets/icons/lifebuoy.png
  14. BIN
      pos_product_create_edit/static/description/assets/icons/manufacturing-black.png
  15. BIN
      pos_product_create_edit/static/description/assets/icons/pos-black.png
  16. BIN
      pos_product_create_edit/static/description/assets/icons/puzzle.png
  17. BIN
      pos_product_create_edit/static/description/assets/icons/restaurant-black.png
  18. BIN
      pos_product_create_edit/static/description/assets/icons/service-black.png
  19. BIN
      pos_product_create_edit/static/description/assets/icons/trading-black.png
  20. BIN
      pos_product_create_edit/static/description/assets/icons/training.png
  21. BIN
      pos_product_create_edit/static/description/assets/icons/update.png
  22. BIN
      pos_product_create_edit/static/description/assets/icons/user.png
  23. BIN
      pos_product_create_edit/static/description/assets/icons/wrench.png
  24. BIN
      pos_product_create_edit/static/description/assets/misc/categories.png
  25. BIN
      pos_product_create_edit/static/description/assets/misc/check-box.png
  26. BIN
      pos_product_create_edit/static/description/assets/misc/compass.png
  27. BIN
      pos_product_create_edit/static/description/assets/misc/corporate.png
  28. BIN
      pos_product_create_edit/static/description/assets/misc/customer-support.png
  29. BIN
      pos_product_create_edit/static/description/assets/misc/cybrosys-logo.png
  30. BIN
      pos_product_create_edit/static/description/assets/misc/features.png
  31. BIN
      pos_product_create_edit/static/description/assets/misc/logo.png
  32. BIN
      pos_product_create_edit/static/description/assets/misc/pictures.png
  33. BIN
      pos_product_create_edit/static/description/assets/misc/pie-chart.png
  34. BIN
      pos_product_create_edit/static/description/assets/misc/right-arrow.png
  35. BIN
      pos_product_create_edit/static/description/assets/misc/star.png
  36. BIN
      pos_product_create_edit/static/description/assets/misc/support.png
  37. BIN
      pos_product_create_edit/static/description/assets/misc/whatsapp.png
  38. BIN
      pos_product_create_edit/static/description/assets/modules/1.png
  39. BIN
      pos_product_create_edit/static/description/assets/modules/2.png
  40. BIN
      pos_product_create_edit/static/description/assets/modules/3.png
  41. BIN
      pos_product_create_edit/static/description/assets/modules/4.png
  42. BIN
      pos_product_create_edit/static/description/assets/modules/5.gif
  43. BIN
      pos_product_create_edit/static/description/assets/modules/5.png
  44. BIN
      pos_product_create_edit/static/description/assets/modules/6.png
  45. BIN
      pos_product_create_edit/static/description/assets/screenshots/1.jpg
  46. BIN
      pos_product_create_edit/static/description/assets/screenshots/2.png
  47. BIN
      pos_product_create_edit/static/description/assets/screenshots/3.png
  48. BIN
      pos_product_create_edit/static/description/assets/screenshots/4.png
  49. BIN
      pos_product_create_edit/static/description/assets/screenshots/hero.gif
  50. BIN
      pos_product_create_edit/static/description/banner.png
  51. BIN
      pos_product_create_edit/static/description/icon.png
  52. 648
      pos_product_create_edit/static/description/index.html
  53. 37
      pos_product_create_edit/static/src/css/ProductList.css
  54. 121
      pos_product_create_edit/static/src/js/ProductCreatePopup.js
  55. 140
      pos_product_create_edit/static/src/js/ProductEditPopup.js
  56. 25
      pos_product_create_edit/static/src/js/ProductLine.js
  57. 57
      pos_product_create_edit/static/src/js/pos_product_screen.js
  58. 91
      pos_product_create_edit/static/src/js/productScreen.js
  59. 11
      pos_product_create_edit/static/src/xml/pos_product_button_templates.xml
  60. 100
      pos_product_create_edit/static/src/xml/product_create_popup_templates.xml
  61. 97
      pos_product_create_edit/static/src/xml/product_edit_popup_templates.xml
  62. 47
      pos_product_create_edit/static/src/xml/product_line_templates.xml
  63. 93
      pos_product_create_edit/static/src/xml/product_list_screen_templates.xml

46
pos_product_create_edit/README.rst

@ -0,0 +1,46 @@
.. image:: https://img.shields.io/badge/license-LGPL--3-green.svg
:target: https://www.gnu.org/licenses/lgpl-3.0-standalone.html
:alt: License: LGPL-3
Product Create Or Edit From Point of Sale
==========================================
This module helps you create products directly from POS, or you can edit the products from point of sale.
Configuration
=============
* No additional configurations needed
Company
-------
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__
License
-------
General Public License, Version 3 (LGPL v3).
(https://www.gnu.org/licenses/lgpl-3.0-standalone.html)
Credits
-------
* Developers: (V15) Mruthul Raj,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
==========
.. image:: https://cybrosys.com/images/logo.png
:target: https://cybrosys.com
This module is maintained by Cybrosys Technologies.
For support and more information, please visit `Our Website <https://cybrosys.com/>`__
Further information
===================
HTML Description: `<static/description/index.html>`__

21
pos_product_create_edit/__init__.py

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Mruthul Raj (<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################

51
pos_product_create_edit/__manifest__.py

@ -0,0 +1,51 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Mruthul Raj (<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
{
'name': 'Product Create Or Edit From Point of Sale',
'version': '15.0.1.0.0',
'category': 'Point of Sale',
'summary': 'Create or edit products directly from the Point'
' of Sale interface.',
'description': 'This module allows users to create or edit products '
'directly from the Point of Sale (POS) interface.'
' It provides a convenient way to manage products'
' on the fly without navigating to the backend.',
'author': 'Cybrosys Techno Solutions',
'company': 'Cybrosys Techno Solutions',
'maintainer': 'Cybrosys Techno Solutions',
'website': 'https://www.cybrosys.com',
'depends': ['point_of_sale'],
'assets': {
'point_of_sale.assets': [
'pos_product_create_edit/static/src/js/*',
'pos_product_create_edit/static/src/css/*',
],
'web.assets_qweb': [
'pos_product_create_edit/static/src/xml/*',
]
},
'images': ['static/description/banner.png'],
'license': 'LGPL-3',
'installable': True,
'application': False,
'auto_install': False,
}

6
pos_product_create_edit/doc/RELEASE_NOTES.md

@ -0,0 +1,6 @@
## Module <pos_product_create_edit>
#### 18.11.2023
#### Version 15.0.1.0.0
#### ADD
- Initial Commit Product Create Or Edit From Point of Sale

BIN
pos_product_create_edit/static/description/assets/icons/check.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
pos_product_create_edit/static/description/assets/icons/chevron.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

BIN
pos_product_create_edit/static/description/assets/icons/cogs.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
pos_product_create_edit/static/description/assets/icons/consultation.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
pos_product_create_edit/static/description/assets/icons/ecom-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

BIN
pos_product_create_edit/static/description/assets/icons/education-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

BIN
pos_product_create_edit/static/description/assets/icons/hotel-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

BIN
pos_product_create_edit/static/description/assets/icons/license.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
pos_product_create_edit/static/description/assets/icons/lifebuoy.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
pos_product_create_edit/static/description/assets/icons/manufacturing-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

BIN
pos_product_create_edit/static/description/assets/icons/pos-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 B

BIN
pos_product_create_edit/static/description/assets/icons/puzzle.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

BIN
pos_product_create_edit/static/description/assets/icons/restaurant-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

BIN
pos_product_create_edit/static/description/assets/icons/service-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 839 B

BIN
pos_product_create_edit/static/description/assets/icons/trading-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

BIN
pos_product_create_edit/static/description/assets/icons/training.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

BIN
pos_product_create_edit/static/description/assets/icons/update.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
pos_product_create_edit/static/description/assets/icons/user.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 988 B

BIN
pos_product_create_edit/static/description/assets/icons/wrench.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
pos_product_create_edit/static/description/assets/misc/categories.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
pos_product_create_edit/static/description/assets/misc/check-box.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
pos_product_create_edit/static/description/assets/misc/compass.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
pos_product_create_edit/static/description/assets/misc/corporate.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
pos_product_create_edit/static/description/assets/misc/customer-support.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
pos_product_create_edit/static/description/assets/misc/cybrosys-logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
pos_product_create_edit/static/description/assets/misc/features.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 B

BIN
pos_product_create_edit/static/description/assets/misc/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
pos_product_create_edit/static/description/assets/misc/pictures.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
pos_product_create_edit/static/description/assets/misc/pie-chart.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
pos_product_create_edit/static/description/assets/misc/right-arrow.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 967 B

BIN
pos_product_create_edit/static/description/assets/misc/star.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
pos_product_create_edit/static/description/assets/misc/support.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
pos_product_create_edit/static/description/assets/misc/whatsapp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
pos_product_create_edit/static/description/assets/modules/1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

BIN
pos_product_create_edit/static/description/assets/modules/2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
pos_product_create_edit/static/description/assets/modules/3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

BIN
pos_product_create_edit/static/description/assets/modules/4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

BIN
pos_product_create_edit/static/description/assets/modules/5.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

BIN
pos_product_create_edit/static/description/assets/modules/5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
pos_product_create_edit/static/description/assets/modules/6.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

BIN
pos_product_create_edit/static/description/assets/screenshots/1.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

BIN
pos_product_create_edit/static/description/assets/screenshots/2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

BIN
pos_product_create_edit/static/description/assets/screenshots/3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

BIN
pos_product_create_edit/static/description/assets/screenshots/4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

BIN
pos_product_create_edit/static/description/assets/screenshots/hero.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB

BIN
pos_product_create_edit/static/description/banner.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

BIN
pos_product_create_edit/static/description/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

648
pos_product_create_edit/static/description/index.html

@ -0,0 +1,648 @@
<div style="background-color: #714B67; height: 810px; width: 100%; padding: 15px; position: relative;">
<!-- TITLE BAR -->
<div class="d-flex align-items-center justify-content-between"
style="border-bottom: 1px solid #875A7B; padding: 15px; display: flex; justify-content: space-between; align-items: center;">
<img src="assets/misc/cybrosys-logo.png" width="42" height="42"
style="width: 42px; height: 42px;"/>
<div>
<div
style="color: #7C7BAD; font-size: 14px; font-family: 'Montserrat', sans-serif; font-weight: bold; background-color: white; display: inline-block; padding: 3px 10px; border-radius: 50px;"
class="mr-2">
<i class="fa fa-check mr-1"></i>Community
</div>
<div
style="color: #875A7B; font-size: 14px; font-family: 'Montserrat', sans-serif; font-weight: bold; background-color: white; display: inline-block; padding: 3px 10px; border-radius: 50px;"
class="mr-2">
<i class="fa fa-check mr-1"></i>Enterprise
</div>
<div style="color: #017E84; font-size: 14px; font-family: 'Montserrat', sans-serif; font-weight: bold; background-color: white; display: inline-block; padding: 3px 10px; border-radius: 50px;"
class="mr-2">
<i class="fa fa-check mr-1"></i>Odoo.sh
</div>
</div>
</div>
<!-- END OF TITLE BAR -->
<div class="container">
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-12">
<!-- APP HERO -->
<h1 style="color: #FFFFFF; font-weight: bolder; font-size: 50px; text-align: center; margin-top: 50px;">
Product Create Or Edit From Point of Sale</h1>
<p style="color:#FFFFFF; padding: 8px 15px; text-align: center; font-size: 24px;">
You Can Directly Edit Or Create a New Product From the Point Of
Sale.</p>
<!-- END OF APP HERO -->
<img src="assets/screenshots/hero.gif" class="img-responsive"
style="width: 100%; margin-left: auto; margin-right: auto;"/>
</div>
</div>
</div>
</div>
<!-- NAVIGATION SECTION -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px; margin-top: 300px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/compass.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Explore This
Module</h2>
</div>
<div class="row my-4" style="font-family: 'Montserrat', sans-serif;">
<div class="col-sm-12 col-md-6 my-3">
<a href="#overview">
<div class="d-flex justify-content-between align-items-center"
style="background-color: #f5f5f5; padding: 30px; width: 100%;">
<div>
<span style="color: #714B67; font-size: 24px; font-weight: 500; display: block;">Overview</span>
<span style="color: #714B67; font-size: 16px; font-weight: 400; color:#282F33; display: block;">Learn
more about this
module</span>
</div>
<img src="assets/misc/right-arrow.png" width="36" height="36"/>
</div>
</a>
</div>
<div class="col-sm-12 col-md-6 my-3">
<a href="#features">
<div class="d-flex justify-content-between align-items-center"
style="background-color: #f5f5f5; padding: 30px; width: 100%;">
<div>
<span style="color: #714B67; font-size: 24px; font-weight: 500; display: block;">Features</span>
<span style="color: #714B67; font-size: 16px; font-weight: 400; color:#282F33; display: block;">View
features of this
module</span>
</div>
<img src="assets/misc/right-arrow.png" width="36" height="36"/>
</div>
</a>
</div>
<div class="col-sm-12 col-md-6 my-3">
<a href="#screenshots">
<div class="d-flex justify-content-between align-items-center"
style="background-color: #f5f5f5; padding: 30px; width: 100%;">
<div>
<span style="color: #714B67; font-size: 24px; font-weight: 500; display: block;">Screenshots</span>
<span style="color: #714B67; font-size: 16px; font-weight: 400; color:#282F33; display: block;">View
screenshots for this
module</span>
</div>
<img src="assets/misc/right-arrow.png" width="36" height="36"/>
</div>
</a>
</div>
</div>
<!-- END OF NAVIGATION SECTION -->
<!-- OVERVIEW SECTION -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;" id="overview">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/pie-chart.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Overview
</h2>
</div>
<div class="row"
style="font-family: 'Montserrat', sans-serif; font-weight: 400; font-size: 14px; line-height: 200%;">
<div class="col-sm-12 py-4">
This Module Helps to Create and Edit Products Directly from the POS
</div>
</div>
<!-- END OF OVERVIEW SECTION -->
<!-- FEATURES SECTION -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;" id="features">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/features.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Features
</h2>
</div>
<div class="row"
style="font-family: 'Montserrat', sans-serif; font-weight: 400; font-size: 14px; line-height: 200%;">
<div class="col-sm-12 col-md-6">
<div class="d-flex align-items-center"
style="margin-top: 40px; margin-bottom: 40px">
<img src="assets/misc/check-box.png" class="mr-2"/>
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Available in Odoo 15.0
Community and Enterprise.</span>
</div>
<div class="d-flex align-items-center"
style="margin-top: 30px; margin-bottom: 30px">
<img src="assets/misc/check-box.png" class="mr-2"/>
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Create new products directly from point of sale.</span>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div class="d-flex align-items-center"
style="margin-top: 30px; margin-bottom: 30px">
<img src="assets/misc/check-box.png" class="mr-2"/>
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Edit products directly from point of sale.</span>
</div>
</div>
</div>
<!-- END OF FEATURES SECTION -->
<!-- SCREENSHOTS SECTION -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;"
id="screenshots">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/pictures.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Screenshots
</h2>
</div>
<div class="row">
<div class="col-sm-12">
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
New Product Screen Button
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
This button will show All products.Form this screen you can
Create new product, or you can Edit already existing product.
</p>
<img src="assets/screenshots/1.jpg" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Product Edit Button
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;"></p>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
On the product screen you can see All products Listed. Each
product has an Edit button on the right side. By clicking on
the button, you can Edit the product directly from POS.</p>
<img src="assets/screenshots/2.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Product Edit popup
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
When you click on the Edit button of any product, product
details will show as a popup.</p>
<img src="assets/screenshots/3.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Create New Product</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
On the product screen we have a dedicated creation button.
Clicking on the button will show a popup to fill with details of
new product.</p>
<img src="assets/screenshots/4.png" class="img-thumbnail">
</div>
</div>
</div>
<!-- END OF SCREENSHOTS SECTION -->
<!-- SUGGESTED PRODUCTS -->
<div class="row">
<div class="col-lg-12 d-flex flex-column justify-content-center"
style="text-align: center; padding: 2.5rem 1rem !important;">
<h2 style="color: #212529 !important;">Suggested Products</h2>
<hr
style="border: 3px solid #714B67 !important; background-color: #714B67 !important; width: 80px !important; margin-bottom: 2rem !important;"/>
<div id="demo1" class="row carousel slide" data-ride="carousel">
<!-- The slideshow -->
<div class="carousel-inner">
<div class="carousel-item active" style="min-height:0px">
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16"
style="float:left">
<a href="https://apps.odoo.com/apps/modules/15.0/pos_order_types/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-top-left-radius:10px; border-top-right-radius:10px"
src="./assets/modules/1.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16"
style="float:left">
<a href="https://apps.odoo.com/apps/modules/15.0/pos_product_addons/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-top-left-radius:10px; border-top-right-radius:10px"
src="./assets/modules/2.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16"
style="float:left">
<a href="https://apps.odoo.com/apps/modules/15.0/dashboard_pos/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-top-left-radius:10px; border-top-right-radius:10px"
src="./assets/modules/3.png">
</div>
</a>
</div>
</div>
<div class="carousel-item" style="min-height:0px">
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16"
style="float:left">
<a href="https://apps.odoo.com/apps/modules/15.0/product_return_pos/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-top-left-radius:10px; border-top-right-radius:10px"
src="./assets/modules/4.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16"
style="float:left">
<a href="https://apps.odoo.com/apps/modules/15.0/point_of_sale_logo"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-top-left-radius:10px; border-top-right-radius:10px"
src="./assets/modules/5.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16"
style="float:left">
<a href="https://apps.odoo.com/apps/modules/15.0/pos_chatter/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-top-left-radius:10px; border-top-right-radius:10px"
src="./assets/modules/6.png">
</div>
</a>
</div>
</div>
</div>
<!-- Left and right controls -->
<a class="carousel-control-prev" href="#demo1" data-slide="prev"
style="left:-25px;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="#demo1"
data-slide="next"
style="right:-25px;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>
</div>
<!-- END OF SUGGESTED PRODUCTS -->
<!-- OUR SERVICES -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/star.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Our Services
</h2>
</div>
<div class="container my-5">
<div class="row">
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #1dd1a1 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/cogs.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Customization</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #ff6b6b !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/wrench.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Implementation</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #6462CD !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/lifebuoy.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Support</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #ffa801 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/user.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Hire
Odoo
Developer</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #54a0ff !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/puzzle.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Integration</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #6d7680 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/update.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Migration</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #786fa6 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/consultation.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Consultancy</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #f8a5c2 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/training.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Implementation</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #e6be26 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/license.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Licensing Consultancy</h6>
</div>
</div>
</div>
<!-- END OF OUR SERVICES -->
<!-- OUR INDUSTRIES -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/corporate.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Our
Industries
</h2>
</div>
<div class="container my-5">
<div class="row">
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/trading-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Trading
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Easily procure
and
sell your products</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/pos-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
POS
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Easy
configuration
and convivial experience</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/education-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Education
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
A platform for
educational management</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/manufacturing-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Manufacturing
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Plan, track and
schedule your operations</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/ecom-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
E-commerce &amp; Website
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Mobile
friendly,
awe-inspiring product pages</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/service-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Service Management
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Keep track of
services and invoice</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/restaurant-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Restaurant
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Run your bar or
restaurant methodically</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/hotel-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Hotel Management
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
An
all-inclusive
hotel management application</p>
</div>
</div>
</div>
</div>
<!-- END OF OUR INDUSTRIES -->
<!-- SUPPORT -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/customer-support.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Support
</h2>
</div>
<div class="container mt-5">
<div class="row">
<div class="col-sm-12 col-md-6">
<div style="background-color: #F6F8F9; padding: 30px; display: flex; align-items: center;">
<div class="mr-4 d-flex justify-content-center align-items-center"
style="background-color: #714B67; display: inline-block; height: 70px; width: 70px; display: flex; align-items: center; justify-content: center;">
<img src="assets/misc/support.png" height="48" width="48"
style="width: 42px; height: 42px;"/>
</div>
<div>
<h4>Need Help?</h4>
<p style="line-height: 100%;">Got questions or need help?
Get in touch.</p>
<a href="mailto:odoo@cybrosys.com">
<p style="font-weight: 400; font-size: 28px; line-height: 80%; color: #714B67;">
odoo@cybrosys.com</p>
</a>
</div>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div style="background-color: #F6F8F9; padding: 30px; display: flex; align-items: center;">
<div class="mr-4 d-flex justify-content-center align-items-center"
style="background-color: #2AC44D; display: inline-block; height: 70px; width: 70px; display: flex; align-items: center; justify-content: center;">
<img src="assets/misc/whatsapp.png" height="52" width="52"
style="width: 52px; height: 52px;"/>
</div>
<div>
<h4>WhatsApp</h4>
<p style="line-height: 100%;">Say hi to us on WhatsApp!</p>
<a href="https://api.whatsapp.com/send?phone=918606827707">
<p style="font-weight: 400; font-size: 28px; line-height: 80%; color: #714B67;">
+91 86068
27707</p>
</a>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12 my-5 d-flex justify-content-center align-items-center">
<img src="assets/misc/logo.png" width="144" height="31"
style="width:144px; height: 31px; margin-top: 40px;"/>
</div>
</div>
</div>
<!-- END OF SUPPORT -->

37
pos_product_create_edit/static/src/css/ProductList.css

@ -0,0 +1,37 @@
button.edit_product{
border-radius:5px;
}
i.fa.fa-pencil{
font-size:20px;
}
.full-content{
overflow:scroll;
}
img.product_img {
max-width:60px;
}
label.field_label{
padding:3%;
}
.field_div{
margin-bottom:5px;
}
select.form-control{
text-align: left;
display: inline-block;
overflow: hidden;
background: white;
min-height: 44px;
font-family: "Lato";
font-size: 20px;
color: #444;
padding: 10px;
border-radius: 3px;
border: none;
box-shadow: 0px 0px 0px 1px gainsboro inset;
box-sizing: border-box;
width: 85%;
}
i.fa.fa-plus.create_btn{
margin-right:5px;
}

121
pos_product_create_edit/static/src/js/ProductCreatePopup.js

@ -0,0 +1,121 @@
/**@odoo-module **/
import AbstractAwaitablePopup from "point_of_sale.AbstractAwaitablePopup";
import Registries from "point_of_sale.Registries";
import { isConnectionError } from "point_of_sale.utils";
import {useListener} from "@web/core/utils/hooks";
const { Gui } = require('point_of_sale.Gui');
let img = "";
let base64_img = "";
class CreateProductPopup extends AbstractAwaitablePopup {
/**
* Set up the component and attach the change event listener to the image field.
*/
setup() {
super.setup();
useListener("change", "#img_field", this._onChangeImgField);
}
/**
* Handle the change event of the image field.
* @param {Event} ev - The change event object.
*/
async _onChangeImgField(ev) {
// This function will work when adding image to the image field
try {
let current = ev.target.files[0];
const reader = new FileReader();
reader.readAsDataURL(current);
reader.onload = await
function() {
img = reader.result;
base64_img = reader.result.toString().replace(/^data:(.*,)?/, "");
const myTimeout = setTimeout(() => {
$(ev.target.parentElement.previousElementSibling.childNodes[0]).hide();
let element =
"<img src=" + img + " style='max-width: 150px;max-height: 150px;'/>";
$(ev.target.parentElement.previousElementSibling.childNodes[0].parentElement).append($(element));
}, 100);
};
reader.onerror = (error) =>
reject(() => {
console.log("error", error);
});
} catch (error) {
if (isConnectionError(error)) {
this.showPopup("ErrorPopup", {
title: this.env._t("Network Error"),
body: this.env._t("Cannot access Product screen if offline."),
});
} else {
throw error;
}
}
}
/**
* Function for validating number.
*/
async _numberCheck(ev){
ev.target.value = ev.target.value.replace(/[^0-9.]/g, '');
}
/**
* Confirm the creation of the product.
*/
async confirm(ev) {
let img = $(ev.target.parentElement.parentElement.previousElementSibling.firstChild.firstElementChild.childNodes[2].children[1]).val();
let name = $(ev.target.parentElement.parentElement.previousElementSibling.firstChild.firstElementChild.childNodes[3].children[1]).val();
let price = $(ev.target.parentElement.parentElement.previousElementSibling.firstChild.firstElementChild.childNodes[4].children[1]).val();
let cost = $(ev.target.parentElement.parentElement.previousElementSibling.firstChild.firstElementChild.childNodes[5].children[1]).val();
let category = $(ev.target.parentElement.parentElement.previousElementSibling.firstChild.firstElementChild.childNodes[8].children[1]).val();
let barcode = $(ev.target.parentElement.parentElement.previousElementSibling.firstChild.firstElementChild.childNodes[6].children[1]).val();
let default_code = $(ev.target.parentElement.parentElement.previousElementSibling.firstChild.firstElementChild.childNodes[7].children[1]).val();
let values = {};
if (base64_img) {
values["image_1920"] = base64_img;
}
if (name) {
values["name"] = name;
}
if (cost) {
values["standard_price"] = cost;
}
if (price) {
values["lst_price"] = price;
}
if (category) {
if (category == 0){
Gui.showPopup('ErrorPopup', {
title: this.env._t('Mismatch Category'),
body: this.env._t('You cannot add to root category.'),
});
}else{
values["pos_categ_id"] = category;
}
}
if (barcode) {
values["barcode"] = barcode;
}
if (default_code) {
values["default_code"] = default_code;
}
values["available_in_pos"] = true;
await this.rpc({
model: "product.product",
method: "create",
args: [values],
}).then((result) => {
if (result) {
this.showNotification(_.str.sprintf(this.env._t('%s - Product Created'), values["name"]), 3000);
window.location.reload();
} else {
this.showNotification(_.str.sprintf(this.env._t('%s - Product Creation Failed'), values["name"]), 3000);
}
this.props.resolve({
confirmed: false,
payload: null
});
this.trigger('close-popup');
});
}
}
CreateProductPopup.template = "CreateProductPopup";
Registries.Component.add(CreateProductPopup);

140
pos_product_create_edit/static/src/js/ProductEditPopup.js

@ -0,0 +1,140 @@
/**@odoo-module **/
import AbstractAwaitablePopup from "point_of_sale.AbstractAwaitablePopup";
import Registries from "point_of_sale.Registries";
import { useListener } from "@web/core/utils/hooks";
const { Gui } = require('point_of_sale.Gui');
let base64_img = "";
let img = "";
class EditProductPopup extends AbstractAwaitablePopup {
setup() {
super.setup();
useListener("change", "#img_field", this._onChangeImgField);
}
/**
* Handle the change event of the image field.
* @param {Event} ev - The change event object.
*/
async _onChangeImgField(ev) {
try {
// This function will work when adding image to the image field
var self = this;
let current = ev.target.files[0];
const reader = new FileReader();
reader.readAsDataURL(current);
reader.onload = await
function() {
img = reader.result;
base64_img = reader.result.toString().replace(/^data:(.*,)?/, "");
const myTimeout = setTimeout(() => {
$(ev.target.parentElement.previousElementSibling.childNodes[0]).hide();
let element =
"<img src=" +
img +
" style='max-width: 150px;max-height: 150px;'/>";
$(ev.target.parentElement.previousElementSibling.childNodes[0].parentElement).append($(element));
}, 100);
};
reader.onerror = (error) =>
reject(() => {
console.log("error", error);
});
} catch (error) {
if (isConnectionError(error)) {
this.showPopup("ErrorPopup", {
title: this.env._t("Network Error"),
body: this.env._t("Cannot access Product screen if offline."),
});
} else {
throw error;
}
}
}
/**
* Function for validating number.
*/
async _numberCheck(ev){
ev.target.value = ev.target.value.replace(/[^0-9.]/g, '');
}
/**
* Confirm the updates to the product.
*/
confirm(ev) {
let values = {};
if (base64_img) {
values["image_1920"] = base64_img;
}
if ($(ev.target.parentElement.parentElement.previousElementSibling.firstChild.firstElementChild.childNodes[3].childNodes[1]).val() != this.props.product.display_name) {
values["name"] = $(ev.target.parentElement.parentElement.previousElementSibling.firstChild.firstElementChild.childNodes[3].childNodes[1]).val();
}
if ($(ev.target.parentElement.parentElement.previousElementSibling.firstChild.firstElementChild.childNodes[4].childNodes[1]).val() != this.props.product.list_price) {
values["lst_price"] = $(ev.target.parentElement.parentElement.previousElementSibling.firstChild.firstElementChild.childNodes[4].childNodes[1]).val();
}
if ($(ev.target.parentElement.parentElement.previousElementSibling.firstChild.firstElementChild.childNodes[7].childNodes[1]).val()) {
values["pos_categ_id"] = parseInt($(ev.target.parentElement.parentElement.previousElementSibling.firstChild.firstElementChild.childNodes[7].childNodes[1]).val());
}
if ($(ev.target.parentElement.parentElement.previousElementSibling.firstChild.firstElementChild.childNodes[6].childNodes[1]).val()) {
values["barcode"] = $(ev.target.parentElement.parentElement.previousElementSibling.firstChild.firstElementChild.childNodes[6].childNodes[1]).val();
}
if ($(ev.target.parentElement.parentElement.previousElementSibling.firstChild.firstElementChild.childNodes[5].childNodes[1]).val()) {
values["default_code"] = $(ev.target.parentElement.parentElement.previousElementSibling.firstChild.firstElementChild.childNodes[5].childNodes[1]).val();
}
if (values["pos_categ_id"] == 0) {
Gui.showPopup('ErrorPopup', {
title: this.env._t('Mismatch Category'),
body: this.env._t('You cannot add to root category.'),
});
}
this.rpc({
model: "product.product",
method: "write",
args: [this.props.product.id, values],
}).then((result) => {
if (result) {
if (values['name']) {
this.props.product.display_name = values['name'];
}
if (values['lst_price']) {
this.props.product.lst_price = values['lst_price'];
}
if (values['barcode']) {
this.props.product.lst_price = values['barcode'];
}
if (values['default_code']) {
this.props.product.lst_price = values['default_code'];
}
if (values['pos_categ_id']) {
if (values['pos_categ_id'] == 0) {
Gui.showPopup('ErrorPopup', {
title: this.env._t('Mismatch Category'),
body: this.env._t('You cannot add to root category.'),
});
} else {
this.props.product.pos_categ_id = [
values["pos_categ_id"],
];
}
}
Gui.setSyncStatus(_.str.sprintf(this.env._t('%s - Product Created'), values['name']), 3000);
window.location.reload();
} else {
this.showNotification(_.str.sprintf(this.env._t("%s - Product Updation Failed"), values['name']), 3000);
}
this.props.resolve({
confirmed: false,
payload: null
});
this.trigger('close-popup');
});
}
/**
* Get the URL for the product image.
* @returns {string} The URL of the product image.
*/
get imageUrl() {
const product = this.props.product;
return `/web/image?model=product.product&field=image_128&id=${product.id}&unique=${product.write_date}`;
}
}
EditProductPopup.template = "EditProductPopup";
Registries.Component.add(EditProductPopup);

25
pos_product_create_edit/static/src/js/ProductLine.js

@ -0,0 +1,25 @@
/**@odoo-module **/
import PosComponent from "point_of_sale.PosComponent";
import Registries from "point_of_sale.Registries";
import { Gui } from 'point_of_sale.Gui';
class ProductLine extends PosComponent {
/**
* Get the URL for the product image.
* @returns {string} The URL of the product image.
*/
get imageUrl() {
const product = this.props.product;
return `/web/image?model=product.product&field=image_128&id=${product.id}&unique=${product.write_date}`;
}
/**
* Edit the current product by showing the EditProductPopup.
*/
async editCurrentProduct() {
await this.showPopup("EditProductPopup", {
product: this.props.product,
});
}
}
ProductLine.template = "ProductLine";
Registries.Component.add(ProductLine);

57
pos_product_create_edit/static/src/js/pos_product_screen.js

@ -0,0 +1,57 @@
/**@odoo-module **/
import PosComponent from "point_of_sale.PosComponent";
import ProductScreen from "point_of_sale.ProductScreen";
import { useListener } from "@web/core/utils/hooks";
import Registries from "point_of_sale.Registries";
import { Gui } from "point_of_sale.Gui";
import { isConnectionError } from "point_of_sale.utils";
export class SetProductListButton extends PosComponent {
/**
* Set up the component and attach the click event listener.
*/
setup() {
super.setup();
useListener("click", this.onClick);
}
/**
* Get the list of products filtered by the selected category.
* @returns {Array} The sorted list of products.
*/
get productsList() {
let list = [];
list = this.env.pos.db.get_product_by_category(
this.env.pos.selectedCategoryId
);
return list.sort(function(a, b) {
return a.display_name.localeCompare(b.display_name);
});
}
/**
* Handle the click event of the button.
*/
async onClick() {
try {
let list = this.productsList;
const screen = "ProductListScreen";
this.showScreen(screen);
} catch (error) {
if (isConnectionError(error)) {
this.showPopup("ErrorPopup", {
title: this.env._t("Network Error"),
body: this.env._t("Cannot access Product screen if offline."),
});
} else {
throw error;
}
}
}
}
SetProductListButton.template = "SetProductListButton";
ProductScreen.addControlButton({
component: SetProductListButton,
condition: function() {
return true;
},
});
Registries.Component.add(SetProductListButton);

91
pos_product_create_edit/static/src/js/productScreen.js

@ -0,0 +1,91 @@
/**@odoo-module **/
import ControlButtonsMixin from "point_of_sale.ControlButtonsMixin";
import Registries from "point_of_sale.Registries";
import IndependentToOrderScreen from "point_of_sale.IndependentToOrderScreen";
import { useListener } from "@web/core/utils/hooks";
import PosComponent from "point_of_sale.PosComponent";
import { Gui } from "point_of_sale.Gui";
const { useRef } = owl.hooks;
class ProductListScreen extends PosComponent {
setup() {
super.setup();
this.searchWordInputRef = useRef("search-word-input-product");
this.state = {
search: null,
};
}
/**
* Create a new product by showing the CreateProductPopup.
*/
createProduct() {
this.showPopup("CreateProductPopup", {
product: this.props.product,
});
}
/**
* Get the list of products to display.
* @returns {Array} The list of products.
*/
get products() {
let list;
if (this.state.search && this.state.search.trim() !== "") {
list = this.env.pos.db.search_product_in_category(
0,
this.state.search.trim()
);
} else {
list = this.env.pos.db.get_product_by_category(0);
}
return list.sort(function (a, b) {
return a.display_name.localeCompare(b.display_name);
});
}
/**
* Update the product list based on the search input.
* @param {Event} event - The event object.
*/
async updateProductList(event) {
this.state.search = event.target.value;
if (event.code === "Enter") {
this._onPressEnterKey();
} else {
this.render(true);
}
}
/**
* Handle the Enter key press event.
*/
async _onPressEnterKey() {
if (!this.state.search) return;
if (!this.env.pos.isEveryProductLoaded) {
const result = await this.products;
this.showNotification(
_.str.sprintf(
this.env._t('%s Product(s) found for "%s".'),
result.length,
this.state.search
),
3000
);
if (!result.length) this._clearSearch();
}
}
/**
* Clear the search input and reset the search state.
*/
_clearSearch() {
this.searchWordInputRef.el.value = "";
this.state.search = "";
this.render(true);
}
/**
* Navigate back to the ProductScreen.
*/
back() {
this.showScreen('ProductScreen');
}
}
ProductListScreen.template = "ProductListScreen";
Registries.Component.add(ProductListScreen);

11
pos_product_create_edit/static/src/xml/pos_product_button_templates.xml

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<!-- Template for the SetProductListButton component -->
<t t-name="SetProductListButton" owl="1">
<div class="control-button o_product_list_button">
<i class="fa fa-pencil-square" role="img" aria-label="Products"
title="Products"/>
Products
</div>
</t>
</templates>

100
pos_product_create_edit/static/src/xml/product_create_popup_templates.xml

@ -0,0 +1,100 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-name="CreateProductPopup" owl="1">
<!-- Template for the CreateProductPopup component -->
<div role="dialog" class="modal-dialog">
<div class="popup product-line-popup" style="max-width: 684px;">
<main class="body">
<div>
<header>
<h3>
<span>Create Product</span>
<i class="fa fa-times" style="float:right"
t-on-click="cancel"/>
<hr/>
</h3>
<div class="product-img-create-popup">
<!-- Product image -->
<img t-att-src="imageUrl"
id="img_url_tag_create"/>
</div>
<div class="field_div"
style="display:flex; margin-bottom: 15px;">
<label for="img_field" class="field_label"
style="margin-right:10px; margin-top: 10px; width: 120px; display: inline-block; text-align: left;">Image</label>
<input type="file" id="img_field"
class="field_input" name="img_field"
accept="image/*"/>
</div>
<div class="field_div"
style="display:flex; margin-bottom: 15px;">
<label for="display_name" class="field_label"
style="margin-right:10px; margin-top: 10px; width: 120px; display: inline-block; text-align: left;">Name</label>
<input type="text" name="display_name"
class="field_input" id="display_name"/>
</div>
<div class="field_div"
style="display:flex; margin-bottom: 15px;">
<label for="list_price" class="field_label"
style="margin-right:10px; margin-top: 10px; width: 120px; display: inline-block; text-align: left;">Price</label>
<input type="text" name="list_price"
t-on-keyup="_numberCheck"
class="field_input" id="list_price"/>
<span class="warning"/>
</div>
<div class="field_div"
style="display:flex; margin-bottom: 15px;">
<label for="list_price" class="field_label"
style="margin-right:10px; margin-top: 10px; width: 120px; display: inline-block; text-align: left;">Cost</label>
<input type="text" name="cost_price"
t-on-keyup="_numberCheck"
class="field_input" id="cost_price"/>
</div>
<div class="field_div"
style="display:flex; margin-bottom: 15px;">
<label for="barcode" class="field_label"
style="margin-right:10px; margin-top: 10px; width: 120px; display: inline-block; text-align: left;">Barcode</label>
<input type="text" name="barcode"
class="field_input" id="barcode"/>
</div>
<div class="field_div"
style="display:flex; margin-bottom: 15px;">
<label for="default_code" class="field_label"
style="margin-right:10px; margin-top: 10px; width: 120px; display: inline-block; text-align: left;">Default Code</label>
<input type="text" name="default_code"
class="field_input" id="default_code"/>
</div>
<div class="field_div"
style="display:flex; margin-bottom: 15px;">
<label for="category" class="field_label"
style="margin-right:10px; margin-top: 10px; width: 120px; display: inline-block; text-align: left;">Category</label>
<select name="category" class="form-control"
id="product_category">
<t t-foreach="env.pos.db.category_by_id"
t-as="category"
t-key="env.pos.db.category_by_id[category].id">
<option t-att-value="env.pos.db.category_by_id[category].id"
t-att-title="env.pos.db.category_by_id[category].name">
<t t-esc="env.pos.db.category_by_id[category].name"/>
</option>
</t>
</select>
</div>
</header>
</div>
</main>
<footer class="footer cash-move">
<div>
<a class="button confirm disable highlight"
t-on-click="confirm">
Confirm
</a>
<a class="button cancel" t-on-click="cancel">
Cancel
</a>
</div>
</footer>
</div>
</div>
</t>
</templates>

97
pos_product_create_edit/static/src/xml/product_edit_popup_templates.xml

@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<!-- Template for the EditProductPopup component -->
<t t-name="EditProductPopup" owl="1">
<div role="dialog" class="modal-dialog">
<div class="popup product-line-popup" style="max-width: 684px;">
<main class="body">
<div>
<header>
<h3>
<span t-esc="props.product.display_name"/>
<i class="fa fa-times" style="float:right"
t-on-click="cancel"/>
<hr/>
</h3>
<div class="product-img-edit-popup">
<img t-att-src="imageUrl"
t-att-alt="props.product.display_name"
id="img_url_tag_edit"/>
</div>
<div class="field_div"
style="display:flex; margin-bottom: 15px;">
<label for="img_field" class="field_label"
style="margin-right:10px; margin-top: 10px; width: 120px; display: inline-block; text-align: left;">Image</label>
<input type="file" id="img_field"
class="field_input" name="img_field"
accept="image/*"/>
</div>
<div class="field_div"
style="display:flex; margin-bottom: 15px;">
<label for="display_name" class="field_label"
style="margin-right:10px; margin-top: 10px; width: 120px; display: inline-block; text-align: left;">Name</label>
<input type="text" name="display_name"
class="field_input" id="display_name"
t-att-value="props.product.display_name"/>
</div>
<div class="field_div"
style="display:flex; margin-bottom: 15px;">
<label for="list_price" class="field_label"
style="margin-right:10px; margin-top: 10px; width: 120px; display: inline-block; text-align: left;">Price</label>
<input type="text" name="list_price"
t-on-keyup="_numberCheck"
class="field_input" id="list_price"
t-att-value="props.product.lst_price"/>
</div>
<div class="field_div"
style="display:flex; margin-bottom: 15px;">
<label for="default_code" class="field_label"
style="margin-right:10px; margin-top: 10px; width: 120px; display: inline-block; text-align: left;">Default Code</label>
<input type="text" name="default_code"
class="field_input" id="default_code"
t-att-value="props.product.default_code"/>
</div>
<div class="field_div"
style="display:flex; margin-bottom: 15px;">
<label for="barcode" class="field_label"
style="margin-right:10px; margin-top: 10px; width: 120px; display: inline-block; text-align: left;">Barcode</label>
<input type="text" name="barcode"
class="field_input" id="barcode"
t-att-value="props.product.barcode"/>
</div>
<div class="field_div"
style="display:flex; margin-bottom: 15px;">
<label for="category" class="field_label"
style="margin-right:10px; margin-top: 10px; width: 120px; display: inline-block; text-align: left;">Category</label>
<select name="category" class="form-control"
id="product_category">
<t t-foreach="env.pos.db.category_by_id"
t-as="category"
t-key="env.pos.db.category_by_id[category].id">
<option t-att-value="env.pos.db.category_by_id[category].id"
t-att-title="env.pos.db.category_by_id[category].name"
t-att-selected="env.pos.db.category_by_id[category] ? ((env.pos.db.category_by_id[category].id === props.product.pos_categ_id[0]) ? true : undefined):undefined">
<t t-esc="env.pos.db.category_by_id[category].name"/>
</option>
</t>
</select>
</div>
</header>
</div>
</main>
<footer class="footer cash-move">
<div>
<a class="button confirm disable highlight"
t-on-click="confirm">
Confirm
</a>
<a class="button cancel" t-on-click="cancel">
Cancel
</a>
</div>
</footer>
</div>
</div>
</t>
</templates>

47
pos_product_create_edit/static/src/xml/product_line_templates.xml

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<!-- Template for the ProductLine component -->
<t t-name="ProductLine" owl="1">
<tr t-attf-class="client-line" t-att-data-id="props.product.id">
<td>
<div class="product-img">
<img t-att-src="imageUrl" class="product_img"
t-att-alt="props.product.display_name"/>
</div>
</td>
<td>
<div>
<t t-esc="props.product.display_name or ''"/>
</div>
</td>
<td t-if="!env.isMobile">
<div>
<t t-esc="props.product.default_code or ''"/>
</div>
</td>
<td t-if="!env.isMobile">
<div>
<t t-esc="props.product.pos_categ_id[1] or ''"/>
</div>
</td>
<td t-if="!env.isMobile">
<div>
<t t-esc="props.product.lst_price or ''"/>
</div>
</td>
<td t-if="!env.isMobile">
<div>
<t t-esc="props.product.barcode or ''"/>
</div>
</td>
<td>
<div>
<button class="edit_product"
t-on-click="editCurrentProduct">
<i class="fa fa-pencil" aria-hidden="true"/>
</button>
</div>
</td>
</tr>
</t>
</templates>

93
pos_product_create_edit/static/src/xml/product_list_screen_templates.xml

@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-name="ProductListScreen" owl="1">
<!-- Template for the ProductListScreen component -->
<div class="clientlist-screen screen">
<div class="screen-content">
<div class="top-content">
<div class="button new-customer highlight" role="img"
aria-label="Create"
t-on-click="createProduct"
title="Create">
<i class="fa fa-plus create_btn"/>
<t t-if="!env.isMobile"> Create</t>
</div>
<div class="button back" t-on-click="back">
<i t-if="env.isMobile" class="fa fa-angle-double-left"/>
<t t-if="!env.isMobile"> Discard</t>
</div>
<div class="top-right-buttons">
<div class="searchbox-client top-content-center">
<div class="pos-search-bar">
<i class="fa fa-search"
t-on-click="_onPressEnterKey"/>
<input t-ref="search-word-input-product"
placeholder="SearchProducts..." size="1"
t-on-keyup="updateProductList"/>
<i class="fa fa-times"
t-on-click="_clearSearch"/>
</div>
</div>
</div>
</div>
<section class="full-content">
<div class="client-window">
<section class="subwindow list">
<div class="subwindow-container">
<div class="subwindow-container-fix scrollable-y">
<table class="client-list">
<thead>
<tr>
<th> </th>
<th>Name</th>
<th t-if="!env.isMobile">Default Code</th>
<th t-if="!env.isMobile"
class="client-line-category">Category</th>
<th t-if="!env.isMobile"
class="client-line-price">List Price</th>
<th t-if="!env.isMobile"
class="client-line-price">Barcode</th>
<th>Edit</th>
</tr>
</thead>
<tbody class="client-list-contents">
<t t-foreach="products"
t-as="product"
t-key="product.id">
<ProductLine product="product"/>
</t>
</tbody>
</table>
<div t-if="!products.length"
class="no-results-message">
<p t-if="env.pos.isEveryProductLoaded and state.search">
No Product found for <b>"<t
t-esc="state.search"/>"</b>
.
</p>
<p t-elif="env.pos.isEveryProductLoaded and !state.search">
There are no products.
</p>
<p t-elif="!env.pos.isEveryProductLoaded and !state.search">
There are no loaded products.
</p>
<t t-elif="!env.pos.isEveryProductLoaded and state.search">
<p> No product found for <b>"<t
t-esc="state.query"/>"</b>
. </p>
<div class="button highlight"
t-on-click="_onPressEnterKey">
<i class="fa fa-search"/>
Search database
</div>
</t>
</div>
</div>
</div>
</section>
</div>
</section>
</div>
</div>
</t>
</templates>
Loading…
Cancel
Save