Browse Source

Jan 16 [ADD] : Initial Commit 'laundry_management_pos'

pull/254/merge
AjmalCybro 1 year ago
parent
commit
f433ca738c
  1. 50
      laundry_management_pos/README.rst
  2. 24
      laundry_management_pos/__init__.py
  3. 63
      laundry_management_pos/__manifest__.py
  4. 21
      laundry_management_pos/controllers/__init__.py
  5. 46
      laundry_management_pos/controllers/laundry_management_pos.py
  6. 6
      laundry_management_pos/doc/RELEASE_NOTES.md
  7. 24
      laundry_management_pos/models/__init__.py
  8. 226
      laundry_management_pos/models/laundry_order.py
  9. 34
      laundry_management_pos/models/pos_config.py
  10. 166
      laundry_management_pos/models/pos_order.py
  11. BIN
      laundry_management_pos/static/description/assets/icons/check.png
  12. BIN
      laundry_management_pos/static/description/assets/icons/chevron.png
  13. BIN
      laundry_management_pos/static/description/assets/icons/cogs.png
  14. BIN
      laundry_management_pos/static/description/assets/icons/consultation.png
  15. BIN
      laundry_management_pos/static/description/assets/icons/ecom-black.png
  16. BIN
      laundry_management_pos/static/description/assets/icons/education-black.png
  17. BIN
      laundry_management_pos/static/description/assets/icons/hotel-black.png
  18. BIN
      laundry_management_pos/static/description/assets/icons/license.png
  19. BIN
      laundry_management_pos/static/description/assets/icons/lifebuoy.png
  20. BIN
      laundry_management_pos/static/description/assets/icons/manufacturing-black.png
  21. BIN
      laundry_management_pos/static/description/assets/icons/pos-black.png
  22. BIN
      laundry_management_pos/static/description/assets/icons/puzzle.png
  23. BIN
      laundry_management_pos/static/description/assets/icons/restaurant-black.png
  24. BIN
      laundry_management_pos/static/description/assets/icons/service-black.png
  25. BIN
      laundry_management_pos/static/description/assets/icons/trading-black.png
  26. BIN
      laundry_management_pos/static/description/assets/icons/training.png
  27. BIN
      laundry_management_pos/static/description/assets/icons/update.png
  28. BIN
      laundry_management_pos/static/description/assets/icons/user.png
  29. BIN
      laundry_management_pos/static/description/assets/icons/wrench.png
  30. BIN
      laundry_management_pos/static/description/assets/misc/categories.png
  31. BIN
      laundry_management_pos/static/description/assets/misc/check-box.png
  32. BIN
      laundry_management_pos/static/description/assets/misc/compass.png
  33. BIN
      laundry_management_pos/static/description/assets/misc/corporate.png
  34. BIN
      laundry_management_pos/static/description/assets/misc/customer-support.png
  35. BIN
      laundry_management_pos/static/description/assets/misc/cybrosys-logo.png
  36. BIN
      laundry_management_pos/static/description/assets/misc/features.png
  37. BIN
      laundry_management_pos/static/description/assets/misc/logo.png
  38. BIN
      laundry_management_pos/static/description/assets/misc/pictures.png
  39. BIN
      laundry_management_pos/static/description/assets/misc/pie-chart.png
  40. BIN
      laundry_management_pos/static/description/assets/misc/right-arrow.png
  41. BIN
      laundry_management_pos/static/description/assets/misc/star.png
  42. BIN
      laundry_management_pos/static/description/assets/misc/support.png
  43. BIN
      laundry_management_pos/static/description/assets/misc/whatsapp.png
  44. BIN
      laundry_management_pos/static/description/assets/modules/barcode.png
  45. BIN
      laundry_management_pos/static/description/assets/modules/custom_receipts_for_pos.jpg
  46. BIN
      laundry_management_pos/static/description/assets/modules/low_stocks_product_alert.png
  47. BIN
      laundry_management_pos/static/description/assets/modules/mrp_pos.png
  48. BIN
      laundry_management_pos/static/description/assets/modules/pos_order.jpg
  49. BIN
      laundry_management_pos/static/description/assets/modules/pos_order_line_image.png
  50. BIN
      laundry_management_pos/static/description/assets/screenshots/hero.gif
  51. BIN
      laundry_management_pos/static/description/assets/screenshots/pos0.png
  52. BIN
      laundry_management_pos/static/description/assets/screenshots/pos1.png
  53. BIN
      laundry_management_pos/static/description/assets/screenshots/pos10.png
  54. BIN
      laundry_management_pos/static/description/assets/screenshots/pos11.png
  55. BIN
      laundry_management_pos/static/description/assets/screenshots/pos12.png
  56. BIN
      laundry_management_pos/static/description/assets/screenshots/pos13.png
  57. BIN
      laundry_management_pos/static/description/assets/screenshots/pos14.png
  58. BIN
      laundry_management_pos/static/description/assets/screenshots/pos15.png
  59. BIN
      laundry_management_pos/static/description/assets/screenshots/pos2.png
  60. BIN
      laundry_management_pos/static/description/assets/screenshots/pos3.png
  61. BIN
      laundry_management_pos/static/description/assets/screenshots/pos4.png
  62. BIN
      laundry_management_pos/static/description/assets/screenshots/pos5.png
  63. BIN
      laundry_management_pos/static/description/assets/screenshots/pos6.png
  64. BIN
      laundry_management_pos/static/description/assets/screenshots/pos7.png
  65. BIN
      laundry_management_pos/static/description/assets/screenshots/pos8.png
  66. BIN
      laundry_management_pos/static/description/assets/screenshots/pos9.png
  67. BIN
      laundry_management_pos/static/description/assets/screenshots/wage.png
  68. BIN
      laundry_management_pos/static/description/banner.png
  69. BIN
      laundry_management_pos/static/description/icon.png
  70. 793
      laundry_management_pos/static/description/index.html
  71. 112
      laundry_management_pos/static/src/css/pos.css
  72. 69
      laundry_management_pos/static/src/js/button/product_create_button.js
  73. 52
      laundry_management_pos/static/src/js/button/washing_type_button.js
  74. 61
      laundry_management_pos/static/src/js/models.js
  75. 36
      laundry_management_pos/static/src/js/order_line.js
  76. 16
      laundry_management_pos/static/src/js/pos_receipt.js
  77. 15
      laundry_management_pos/static/src/js/product_img.js
  78. 51
      laundry_management_pos/static/src/js/screen/product_create_popup.js
  79. 40
      laundry_management_pos/static/src/js/screen/washing_type_popup.js
  80. 13
      laundry_management_pos/static/src/xml/button/product_create_button.xml
  81. 23
      laundry_management_pos/static/src/xml/button/washing_type_button.xml
  82. 57
      laundry_management_pos/static/src/xml/pos_receipt.xml
  83. 11
      laundry_management_pos/static/src/xml/product_img.xml
  84. 95
      laundry_management_pos/static/src/xml/screen/product_create_popup.xml
  85. 42
      laundry_management_pos/static/src/xml/screen/washing_type_popup.xml
  86. 39
      laundry_management_pos/views/laundry_order_views.xml
  87. 26
      laundry_management_pos/views/pos_config_views.xml
  88. 27
      laundry_management_pos/views/pos_order_views.xml

50
laundry_management_pos/README.rst

@ -0,0 +1,50 @@
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.svg
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
POS Laundry Management
======================
* From the POS we need to generate Laundry orders in the back end with out close the current window.
* Automatically create Laundry order form POS sale.
* We can assign which products make Laundry order Automatically.
* We can assign which Service type make Laundry order.
Configuration
=============
* No additional configurations needed
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: (V15) Risvana A R, Contact: odoo@cybrosys.com
Contacts
--------
* Mail Contact : odoo@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>`__

24
laundry_management_pos/__init__.py

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# Author: Risvana A R (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
# GENERAL PUBLIC LICENSE (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from . import controllers
from . import models

63
laundry_management_pos/__manifest__.py

@ -0,0 +1,63 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# Author: Risvana A R (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
# GENERAL PUBLIC LICENSE (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
'name': "POS Laundry Management",
'version': '15.0.1.0.0',
'category': 'Point of Sale',
'summary': """Launch Automatic Laundry Orders After selling Through POS.""",
'description': """Launch automatic Laundry Orders after selling through POS""",
'author': 'Cybrosys Techno Solutions',
'company': 'Cybrosys Techno Solutions',
'maintainer': 'Cybrosys Techno Solutions',
'website': 'https://www.cybrosys.com',
'depends': ['point_of_sale', 'laundry_management'],
'data': [
'views/pos_config_views.xml',
'views/laundry_order_views.xml',
'views/pos_order_views.xml',
],
'assets': {
'point_of_sale.assets': [
'laundry_management_pos/static/src/css/pos.css',
'laundry_management_pos/static/src/js/product_img.js',
'laundry_management_pos/static/src/js/models.js',
'laundry_management_pos/static/src/js/order_line.js',
'laundry_management_pos/static/src/js/pos_receipt.js',
'laundry_management_pos/static/src/js/button/product_create_button.js',
'laundry_management_pos/static/src/js/button/washing_type_button.js',
'laundry_management_pos/static/src/js/screen/product_create_popup.js',
'laundry_management_pos/static/src/js/screen/washing_type_popup.js',
],
'web.assets_qweb': [
'laundry_management_pos/static/src/xml/product_img.xml',
'laundry_management_pos/static/src/xml/pos_receipt.xml',
'laundry_management_pos/static/src/xml/button/product_create_button.xml',
'laundry_management_pos/static/src/xml/button/washing_type_button.xml',
'laundry_management_pos/static/src/xml/screen/product_create_popup.xml',
'laundry_management_pos/static/src/xml/screen/washing_type_popup.xml',
],
},
'images': ['static/description/banner.png'],
'license': 'AGPL-3',
'installable': True,
'auto_install': False,
'application': False,
}

21
laundry_management_pos/controllers/__init__.py

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# Author: Risvana A R (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
# GENERAL PUBLIC LICENSE (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from . import laundry_management_pos

46
laundry_management_pos/controllers/laundry_management_pos.py

@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# Author: Risvana A R (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
# GENERAL PUBLIC LICENSE (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from odoo import http
from odoo.http import request
class PosProductCreation(http.Controller):
"""Class PosProductCreation is used to create a product from the POS Screen"""
@http.route('/create_product', type="json", auth="none")
def create_product(self, category, name, price, product_reference,
unit_measure, product_categories):
"""Used for creating product from the point of sale view
that easily create a new product from the point of sale"""
categories = {
'Consumable': 'consu',
'Service': 'service',
'Storable': 'product'
}
request.env['product.template'].sudo().create({
'name': name,
'detailed_type': categories.get(category, ''),
'default_code': product_reference,
'list_price': float(price),
'uom_id': int(unit_measure),
'uom_po_id': int(unit_measure),
'categ_id': int(product_categories),
'available_in_pos': True,
})

6
laundry_management_pos/doc/RELEASE_NOTES.md

@ -0,0 +1,6 @@
## Module <laundry_management_pos>
#### 16.10.2023
#### Version 15.0.1.0.0
#### ADD
- Initial commit for POS Laundry Management

24
laundry_management_pos/models/__init__.py

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# Author: Risvana A R (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
# GENERAL PUBLIC LICENSE (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from . import laundry_order
from . import pos_config
from . import pos_order

226
laundry_management_pos/models/laundry_order.py

@ -0,0 +1,226 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# Author: Risvana A R (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
# GENERAL PUBLIC LICENSE (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import json
from odoo import api, fields, models, _
class LaundryOrder(models.Model):
""" This class is inherited for model laundry_order.
It contains fields and the functions for the model
Methods:
_compute_amount_all(self):
Action perform to computing the total amounts of the LaundryOrder.
_compute_tax_totals_json(self):
Action perform to computing the total tax amount using the order-lines tax and amount.
_invoice_count(self):
Action perform to computing the invoice count based on the particular Laundry order.
_work_count(self):
Action perform to computing the work count based on the particular Laundry order.
action_view_laundry_works(self):
Action perform to works details of the LaundryOrder , the laundry work smart button views are displayed.
action_view_invoice(self):
Action perform to Invoice details of the LaundryOrder when opening the smart button we can view the invoice details.
"""
_inherit = 'laundry.order'
order_ref = fields.Char(string='Order Ref',
help='Reference field for order')
pos_reference = fields.Char(string='Receipt Number',
help='Reference field for POS')
is_invoiced = fields.Boolean(string='Is Invoiced', invisible=1,
help='Boolean field for checking and '
'adding the invoices')
pos_order = fields.Boolean(string='Is POS order',
help='Boolean field for pos order '
'identification')
pos_order_id = fields.Many2one('pos.order', string='POS order',
help='Relating the many2one field for pos.order')
tax_totals_json = fields.Char(compute='_compute_tax_totals_json',
help='For computing the tax ')
amount_untaxed = fields.Monetary(string='Untaxed Amount',
compute='_compute_amount_all',
help='For computing the untaxed amount')
amount_tax = fields.Monetary(string='Taxes', compute='_compute_amount_all',
help='Compute the tax amounts')
total_amount = fields.Monetary(string='Total', store=True,
compute='_compute_amount_all',
help='Compute the total amount')
@api.depends('order_lines')
def _compute_amount_all(self):
"""
Compute the total amounts of the LaundryOrder.
"""
for order in self:
amount_untaxed = amount_tax = 0.0
for line in order.order_lines:
amount_untaxed += line.amount
amount_tax += line.price_tax
order.update({
'amount_untaxed': amount_untaxed,
'amount_tax': amount_tax,
'total_amount': amount_untaxed + amount_tax,
})
@api.depends('order_lines.tax_ids', 'order_lines.amount',
'total_amount')
def _compute_tax_totals_json(self):
""" computing the total tax amount using the order-lines
tax and amount"""
def compute_taxes(order_lines):
price = order_lines.amount
orders = order_lines.laundry_obj
return order_lines.tax_ids._origin.compute_all(price,
orders.currency_id,
product=
order_lines.product_id,
partner=
orders.partner_shipping_id)
for order in self:
tax_lines_data = self.env['account.move']._prepare_tax_lines_data_for_totals_from_object(
order.order_lines, compute_taxes)
tax_totals = self.env['account.move']._get_tax_totals(
order.partner_id, tax_lines_data, order.order_lines.amount,
order.total_amount, order.currency_id)
order.tax_totals_json = json.dumps(tax_totals)
def _invoice_count(self):
"""Computing the invoice count based on the particular Laundry order
override the _invoice_count function"""
work = self.env['pos.order'].search(
[('name', '=', self.order_ref)])
if not work:
wrk_ordr_ids = self.env['account.move'].search([('invoice_origin', '=',
self.sale_obj.name)])
self.invoice_count = len(wrk_ordr_ids)
else:
work_orders = self.env['account.move'].search([('invoice_origin',
'=', work.name)])
self.invoice_count = len(work_orders)
self.is_invoiced = True
def _work_count(self):
"""Computing the work count based on the particular Laundry order
override the _work_count function"""
work = self.env['pos.order'].search(
[('name', '=', self.order_ref)])
if not work:
if self.id:
wrk_ordr_ids = self.env['washing.washing'].search([('laundry_obj.laundry_obj.id', '=', self.id)])
self.work_count = len(wrk_ordr_ids)
else:
self.work_count = False
else:
self.work_count = len(work.lines)
def action_view_laundry_works(self):
"""
works details of the LaundryOrder , the laundry work
smart button views are displayed here.
"""
result = super().action_view_laundry_works()
pos_orders = self.env['pos.order'].search(
[('name', '=', self.order_ref)])
pos_order_ids = pos_orders.mapped('id')
view_id = self.env.ref('laundry_management.washing_form_view').id
if pos_orders and len(pos_orders.lines) <= 1:
return {
'view_type': 'form',
'view_mode': 'form',
'res_model': 'washing.washing',
'view_id': view_id,
'type': 'ir.actions.act_window',
'name': _('Works'),
'res_id': pos_order_ids and pos_order_ids[0]
}
return result
def action_view_invoice(self):
"""
Invoice details of the LaundryOrder when opening the smart button
we can view the invoice details.
"""
result = super(LaundryOrder, self).action_view_invoice()
work = self.env['pos.order'].search(
[('name', '=', self.order_ref)])
invoice = self.env['account.move'].search(
[('invoice_origin', '=', work.name)])
invoice_ids = invoice.mapped('id')
view_id = self.env.ref('account.view_move_form').id
if invoice and len(invoice_ids) <= 1:
return {
'view_type': 'form',
'view_mode': 'form',
'res_model': 'account.move',
'view_id': view_id,
'type': 'ir.actions.act_window',
'name': _('Invoice'),
'res_id': invoice_ids and invoice_ids[0]
}
return result
class LaundryOrderLine(models.Model):
""" This class is inherited for model laundry_order_line.
It contains fields and the functions for the model
Methods:
_compute_price_tax(self):
Action perform to compute the subtotal amounts of the LaundryOrder line.
"""
_inherit = 'laundry.order.line'
# washing_type field is updated with the module Laundry Management
washing_type = fields.Many2one('washing.type', string='Washing Type',
required=False,
help='The many2one field for relating'
' to the washing type')
tax_ids = fields.Many2many('account.tax', string='Taxes',
help='The many2one field for relating to '
'the account tax')
price_tax = fields.Float(compute='_compute_price_tax', string='Total Tax',
help='The compute field for calculating price '
'tax')
@api.depends('qty', 'washing_type', 'extra_work', 'tax_ids')
def _compute_price_tax(self):
"""
Compute the amounts of the LaundryOrder line ie used to calculate subtotal amount with the quantity of product and the washing types.
"""
for line in self:
price = line.washing_type.amount
taxes = line.tax_ids.compute_all(price,
line.laundry_obj.currency_id,
line.qty,
product=line.product_id,
partner=line.laundry_obj.partner_shipping_id)
line.update({
'price_tax': taxes['total_included'] - taxes['total_excluded'],
})

34
laundry_management_pos/models/pos_config.py

@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# Author: Risvana A R (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
# GENERAL PUBLIC LICENSE (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from odoo import fields, models
class PosConfig(models.Model):
""" This class is inherited for model pos_config.
It contains field for the model
"""
_inherit = 'pos.config'
orderline_washing_type = fields.Boolean(string='Washing Type',
help='Allow to add Washing type'
' for customer on OrderLines')

166
laundry_management_pos/models/pos_order.py

@ -0,0 +1,166 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# Author: Risvana A R (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
# GENERAL PUBLIC LICENSE (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from datetime import datetime
from odoo import api, fields, models, _
from odoo.tools import float_repr
class PosOrderLine(models.Model):
""" This class is inherited for model pos_order_line.
It contains field and the functions for the model
Methods:
_export_for_ui(self, orderline):
Supering the export_for_ui function for generating the washing type in the order line for the model.
_order_line_fields(self, line, session_id):
Action perform to adding order-line details in the pos orders.
"""
_inherit = 'pos.order.line'
washing_type_id = fields.Many2one('washing.type',
String='Washing Type',
help='The many2one filed that related'
' to the washing type')
def _export_for_ui(self, orderline):
"""super the exporting function in the pos order line"""
result = super()._export_for_ui(orderline)
result['washing_type_id'] = \
orderline.washing_type.read(fields=['name'])[0]
return result
def _order_line_fields(self, line, session_id):
"""
Adding order-line details in the pos orders
"""
result = super()._order_line_fields(line, session_id)
vals = result[2]
washing_type_id = line[2].get('washingType_id')
new_values = {'washing_type_id': int(washing_type_id)}
vals.update(new_values)
return result
class PosOrder(models.Model):
""" This class is inherited for model pos_order.
It contains fields and the functions for the model
Methods:
create_from_ui(self, orders, draft=False):
Supering the create_from_ui that create and update Orders from the frontend PoS application line for the model.
_prepare_invoice_lines(self):
Action perform to create Invoice for the corresponding POS order
"""
_inherit = "pos.order"
orderline_washing_type = fields.Boolean(string='Washing Type in orderline',
related='session_id.config_id.orderline_washing_type',
help='Related to the type in the pos session washing type id')
laundry_order = fields.Boolean('Laundry',
help='Field for calling the invoice'
' functionality')
@api.model
def create_from_ui(self, orders, draft=False):
""" Create and update Orders from the frontend PoS application.
"""
order = super(PosOrder, self).create_from_ui(orders=orders,
draft=draft)
order_id = order[0]['id']
values = self.env['pos.order'].browse(order_id)
values.write({
'laundry_order': True,
})
if values.laundry_order:
values.action_pos_order_invoice()
lines = []
for rec in values.lines:
vals = (0, 0, {
'product_id': rec.product_id.id,
'description': rec.full_product_name,
'qty': rec.qty,
'state': 'done',
'tax_ids': [(6, 0, rec.tax_ids.ids)],
'washing_type': rec.washing_type_id.id,
'amount': rec.price_subtotal_incl,
})
lines.append(vals)
laundry_order = self.env['laundry.order'].sudo().create({
'order_ref': values.name,
'pos_order_id': values.id,
'pos_reference': values.pos_reference,
'partner_id': values.partner_id.id,
'partner_invoice_id': values.partner_id.id,
'partner_shipping_id': values.partner_id.id,
'laundry_person': values.user_id.id,
'state': 'done',
'order_lines': lines,
})
for each in laundry_order:
for obj in each.order_lines:
self.env['washing.washing'].create(
{'name': obj.product_id.name + '-Washing',
'user_id': obj.washing_type.assigned_person.id,
'description': obj.description,
'laundry_obj': obj.id,
'state': 'done',
'washing_date': datetime.now().strftime(
'%Y-%m-%d %H:%M:%S')})
return order
def _prepare_invoice_lines(self):
"""
Invoice for the corresponding POS order
"""
invoice_lines = []
for line in self.lines:
invoice_lines.append((0, None, self._prepare_invoice_line(line)))
if line.order_id.pricelist_id.discount_policy == 'without_discount'\
and line.price_unit != line.product_id.lst_price:
invoice_lines.append((0, None, {
'name': _('Price discount from %s -> %s',
float_repr(line.product_id.lst_price,
self.currency_id.decimal_places),
float_repr(line.price_unit,
self.currency_id.decimal_places)),
'display_type': 'line_note',
}))
if line.customer_note:
invoice_lines.append((0, None, {
'name': line.customer_note,
'display_type': 'line_note',
}))
if line.washing_type_id:
invoice_lines.append((0, None, {
'name': line.washing_type_id.name,
'display_type': 'line_note',
}))
return invoice_lines

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 839 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 988 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 967 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
laundry_management_pos/static/description/assets/modules/barcode.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

BIN
laundry_management_pos/static/description/assets/modules/custom_receipts_for_pos.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

BIN
laundry_management_pos/static/description/assets/modules/low_stocks_product_alert.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

BIN
laundry_management_pos/static/description/assets/modules/mrp_pos.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
laundry_management_pos/static/description/assets/modules/pos_order.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

BIN
laundry_management_pos/static/description/assets/modules/pos_order_line_image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 503 KiB

BIN
laundry_management_pos/static/description/assets/screenshots/pos0.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

BIN
laundry_management_pos/static/description/assets/screenshots/pos1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

BIN
laundry_management_pos/static/description/assets/screenshots/pos10.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

BIN
laundry_management_pos/static/description/assets/screenshots/pos11.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

BIN
laundry_management_pos/static/description/assets/screenshots/pos12.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

BIN
laundry_management_pos/static/description/assets/screenshots/pos13.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
laundry_management_pos/static/description/assets/screenshots/pos14.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 KiB

BIN
laundry_management_pos/static/description/assets/screenshots/pos15.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

BIN
laundry_management_pos/static/description/assets/screenshots/pos2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 KiB

BIN
laundry_management_pos/static/description/assets/screenshots/pos3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

BIN
laundry_management_pos/static/description/assets/screenshots/pos4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

BIN
laundry_management_pos/static/description/assets/screenshots/pos5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

BIN
laundry_management_pos/static/description/assets/screenshots/pos6.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

BIN
laundry_management_pos/static/description/assets/screenshots/pos7.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
laundry_management_pos/static/description/assets/screenshots/pos8.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

BIN
laundry_management_pos/static/description/assets/screenshots/pos9.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

BIN
laundry_management_pos/static/description/assets/screenshots/wage.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

BIN
laundry_management_pos/static/description/banner.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

BIN
laundry_management_pos/static/description/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

793
laundry_management_pos/static/description/index.html

@ -0,0 +1,793 @@
<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;">
POS Laundry Management</h1>
<p style="color:#FFFFFF; padding: 8px 15px; text-align: center; font-size: 24px;">
A Module For Configuring the Point of Sale in Laundry
Management.</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">
In the POS Laundry Management App, It manages the Point of sale laundry
process with assigning works to workers.We can create Laundry orders
with the help of POS. Before installing this module, Install the <a
href="https://apps.odoo.com/apps/modules/15.0/laundry_management/">Laundry
management module </a> in the Odoo App Store
</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: 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;">Display Laundry Service in the POS Screen.</span>
</div>
<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;">Create Product from the POS Screen.</span>
</div>
<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;">Display Washing Type in the Order lines and Order Receipts</span>
</div>
<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;">Recording Laundry Order.</span>
</div>
<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;">Make Invoices Based on the Laundry Orders.</span>
</div>
<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;">Configuration for Washing Type.</span>
</div>
<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;">Assigning Laundry Works.</span>
</div>
<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;">Separate View for Works.</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;">
Enable Washing Type in the configuration Settings.
</h3>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
Go to Point of Sale >> Configuration >> Point of Sale and
choose one Point of Sale. Enable washing type.</p>
<img src="assets/screenshots/pos0.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;">
POS Screen view.
</h3>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
User can start the session and display the POS screen with a
Button Laundry service and create product.</p>
<img src="assets/screenshots/pos1.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;">
Choose product.
</h3>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
Choose Service Product and you can Use the Custom button for selection the services.</p>
<img src="assets/screenshots/pos2.png" class="img-thumbnail">
<img src="assets/screenshots/pos3.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;">
Select Laundry Service.
</h3>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
Users can select the laundry service for the product and set
the corresponding price. If we are setting up the entire order
to get the same service, we can use the laundry service button
or we can use the plus button on each of the order lines it can
provide the different products have different Service.
</p>
<img src="assets/screenshots/pos4.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;">
Orderline View.
</h3>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
we can add the Laundry service name in the order lines and also
there has a remove option in the order lines.
</p>
<img src="assets/screenshots/pos5.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;">
Validate Payment With Invoice.
</h3>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
Make the payment with invoice.Also created a laundry order with
invoices
</p>
<img src="assets/screenshots/pos15.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;">
POS Receipt.
</h3>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
Laundry Service Mentioned in the POS Receipt
</p>
<img src="assets/screenshots/pos6.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;">
POS Invoice.
</h3>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
Print POS Invoice with Laundry Service
</p>
<img src="assets/screenshots/pos7.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;">
POS Orders.
</h3>
<img src="assets/screenshots/pos8.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;">
POS Product Creation.
</h3>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
We can Create a product using a custom button "Create Product" in the pos screen
</p>
<img src="assets/screenshots/pos9.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;">
Created Products.
</h3>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
The Newly created Product has displayed in the Product
Screen.</p>
<img src="assets/screenshots/pos10.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;">
Laundry Management Order.
</h3>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
When created a Laundry Management Order from the POS Order
</p>
<img src="assets/screenshots/pos11.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;">
Laundry Management Order Form view.
</h3>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
You can see all the Works and Invoice through the smart button
"Works" and "Invoice" from the Laundry Order form.
</p>
<img src="assets/screenshots/pos12.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;">
Work Order View.
</h3>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
In the form view shows the work details, assigned persons and
work status .
</p>
<img src="assets/screenshots/pos13.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;">
Invoice View.
</h3>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
In the Invoice form view shows the Invoice details and status.
</p>
<img src="assets/screenshots/pos14.png" class="img-thumbnail">
</div>
</div>
</div>
<!-- END OF SCREENSHOTS SECTION -->
<!-- RELATED 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_book_order/"
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/pos_order.jpg">
</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/low_stocks_product_alert/"
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/low_stocks_product_alert.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_mrp_order/"
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/mrp_pos.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/pos_order_line_image/"
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/pos_order_line_image.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/custom_receipts_for_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/custom_receipts_for_pos.jpg">
</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_add_product_webcam_barcode/"
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/barcode.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>
<!-- 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 -->

112
laundry_management_pos/static/src/css/pos.css

@ -0,0 +1,112 @@
.pos .numpad button {
color: #2F4F4F;
background: #D3D6D6;
border-color: #2F4F4F;
}
.pos .control-button {
display: none;
}
.pos button.button.set-customer{
padding-left: 0px;
padding-right: 0px;
color: black;
}
.pos .actionpad .button.set-customer.decentered{
padding-left: 0px;
padding-right: 0px;
color: black;
}
.pos .button-control {
background: #A9A9A9;
color: black;
border: none;
border-radius: 0;
border-top: 1px solid;
border-left: 1px solid;
border-bottom: 1px solid;
border-right: 1px solid;
border-color: white;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
flex-grow: 1;
height: 60px;
}
.pos .order .orderline .pos_product_image{
float:left;
margin:auto;
}
.pos .order {
padding-top: 0px !important;
}
.pos .order .orderline .product-name {
padding-top: 5px;
}
.pos .order .orderline .info-list {
margin-left: 15px;
padding-bottom: 10px;
font-weight: bold;
font-family: Verdana;
}
.pos .order .orderline .product-name{
padding:0;
display:inline-block;
font-weight: bold;
font-family: Verdana;
width:80%;
overflow:hidden;
text-overflow: ellipsis;
}
.pos .actionpad .button.pay {
height: calc(var(--btn-height-size) * 3);
color: black;
}
.pos .order .orderline .price{
padding:0;
font-weight: bold;
font-family: Verdana;
float:right;
}
.salesperson-scroll{
height: 270px;
overflow: auto;
}
.salesperson {
border-collapse: collapse;
width: 100%;
}
.salesperson td{
text-align: left;
border: 1px solid #ddd;
padding: 8px;
}
.salesperson tr:nth-child(even){background-color: #f2f2f2;}
.salesperson tr:hover {background-color: #ddd;}
.orderline-salesperson{
padding:5;
float:right;
}
.orderline-laundry{
padding:5;
float:left;
}
.pos .products-widget .products-widget-control{
display: none;
}
.pos button, .pos a.button {
display: inline-block;
cursor: pointer;
padding: 4px 10px;
font-size: 11px;
border: 1px solid #cacaca;
background: #A9A9A9;
border-radius: 3px;
}
.button-control:hover {
background: #efefef;
}

69
laundry_management_pos/static/src/js/button/product_create_button.js

@ -0,0 +1,69 @@
odoo.define('laundry_management_pos.product_create_button', function(require) {
'use strict';
const PosComponent = require('point_of_sale.PosComponent');
const ProductScreen = require('point_of_sale.ProductScreen');
const { useListener } = require('web.custom_hooks');
const Registries = require('point_of_sale.Registries');
const ajax = require('web.ajax');
// Extending the PosComponent that used to create a button in the POS View
class ProductCreateButton extends PosComponent {
constructor() {
super(...arguments);
useListener('click', this.onClick);
}
async onClick() {
var self = this;
const {
confirmed,
payload
} = await this.showPopup('ProductCreatePopup', {
title: this.env._t('POS Product Creation'),
body: this.env._t('You can Create The product.'),
});
if (confirmed) {
console.log(payload, 'payload')
var product_category = payload[0];
var product_name = payload[1];
var product_reference = payload[2];
var product_price = payload[3];
var unit_measure = payload[4];
var product_categories = payload[5];
var pos_categories = payload[6];
if (!product_name){
return this.showPopup('ErrorPopup', {
title: _('A Unit Of Measure Is Required'),
});
}
if (!unit_measure){
return this.showPopup('ErrorPopup', {
title: _('A Unit Of Measure Is Required'),
});
}
ajax.jsonRpc('/create_product', 'call', {
'category': product_category,
'name': product_name,
'price': product_price,
'product_reference': product_reference,
'unit_measure': unit_measure,
'product_categories': product_categories,
'pos_categories': pos_categories
}).then(function(response) {});
}
}
}
// Create a new Button that used to Display the Product Information
ProductCreateButton.template = 'ProductCreateButton';
ProductScreen.addControlButton({
component: ProductCreateButton,
condition: function() {
return true;
},
position: ['before', 'SetPricelistButton'],
});
Registries.Component.add(ProductCreateButton);
return ProductCreateButton;
});

52
laundry_management_pos/static/src/js/button/washing_type_button.js

@ -0,0 +1,52 @@
odoo.define('laundry_management_pos.LaundryServiceType', function (require) {
"use strict";
const { Gui } = require('point_of_sale.Gui');
const { useListener } = require('web.custom_hooks');
const PosComponent = require('point_of_sale.PosComponent');
const AbstractAwaitablePopup = require('point_of_sale.AbstractAwaitablePopup');
const Registries = require('point_of_sale.Registries');
const ProductItem = require('point_of_sale.ProductItem');
const ProductScreen = require('point_of_sale.ProductScreen');
var models = require('point_of_sale.models');
var rpc = require('web.rpc');
models.load_models({
model: 'washing.type',
fields: ['name','assigned_person', 'amount'],
loaded: function(self, washing_type) {
self.washing_type = washing_type;
}
})
class LaundryServiceButton extends PosComponent{
constructor() {
super(...arguments);
useListener('click', this.onClick);
}
//Generate popup
async onClick() {
var core = require('web.core');
var _t = core._t;
this.showPopup("LaundryServiceTypePopup", {
title : _t("Laundry Service"),
confirmText: _t("Exit"),
service: this.env.pos.washing_type,
pos: this.env.pos,
});
}
}
LaundryServiceButton.template = 'LaundryServiceButton';
//Add popup button and set visibility
ProductScreen.addControlButton({
component: LaundryServiceButton,
condition: function() {
return this.env.pos.config.orderline_washing_type;
},
});
Registries.Component.add(LaundryServiceButton);
return LaundryServiceButton;
});

61
laundry_management_pos/static/src/js/models.js

@ -0,0 +1,61 @@
odoo.define('laundry_management_pos.modelsorderline', function (require) {
"use strict";
var models = require('point_of_sale.models');
var rpc = require('web.rpc');
var _super_orderline = models.Orderline.prototype;
models.Orderline = models.Orderline.extend({
initialize: function(attr, options) {
// It is possible that this orderline is initialized using `init_from_JSON`,
_super_orderline.initialize.call(this,attr,options);
this.washingType = this.washingType || options.washingType;
this.washingType_id = this.washingType_id || 0.0;
this.washingType_price = this.washingType_id.amount || 0.0;
},
// Function to set the service type of the Washing
set_washingType: function(service) {
this.washingType = service.value;
this.washingType_id = service.id;
this.washingType_price = service.id.amount;
this.trigger('change',this);
},
// Function to get the service type of the Washing
get_washingType: function(service) {
return this.washingType;
},
// Used to merge the services with Order-line
can_be_merged_with: function(orderline) {
if (orderline.get_washingType() !== this.get_washingType()) {
return false;
} else {
return _super_orderline.can_be_merged_with.apply(this,arguments);
}
},
// clone the service with order-lines
clone: function(){
var orderline = _super_orderline.clone.call(this);
orderline.washingType = this.washingType;
orderline.washingType_id = this.washingType_id;
orderline.washingType_price = this.washingType_price;
return orderline;
},
export_as_JSON: function(){
var json = _super_orderline.export_as_JSON.call(this);
json.washingType = this.washingType;
json.washingType_id = this.washingType_id;
json.washingType_price = this.washingType_price;
return json;
},
init_from_JSON: function(json){
_super_orderline.init_from_JSON.apply(this,arguments);
this.washingType = json.washingType;
this.washingType_id = json.washingType_id;
this.washingType_price = json.washingType_price;
},
});
});

36
laundry_management_pos/static/src/js/order_line.js

@ -0,0 +1,36 @@
odoo.define('laundry_management_pos.orderline', function(require) {
'use strict';
const Orderline = require('point_of_sale.Orderline');
const Registries = require('point_of_sale.Registries');
var models = require('point_of_sale.models');
// Extend the order-line used to add popup items
const PosResOrderline = Orderline =>
class extends Orderline {
click(){
this.showPopup("LaundryServiceTypePopup", {
title : this.env._t("Laundry Service"),
service: this.env.pos.washing_type,
pos: this.env.pos,
orderline: this.props.line,
});
}
// function to remove the service from the Laundry Process
remove_laundry(){
this.props.line.washingType = '';
this.props.line.washingType_id = 0.0;
this.props.line.trigger('change',this.props.line);
}
};
Registries.Component.extend(Orderline, PosResOrderline);
return Orderline;
});

16
laundry_management_pos/static/src/js/pos_receipt.js

@ -0,0 +1,16 @@
odoo.define('laundry_management_pos.receipt', function(require){
"use strict";
var models = require('point_of_sale.models');
var _super_orderline = models.Orderline.prototype;
// Extends the order-line used to add the Washing Details in the order receipts
models.Orderline = models.Orderline.extend({
// Used to add the Washing Details in the order receipt
export_for_printing: function(){
var line = _super_orderline.export_for_printing.apply(this, arguments);
line.service_type = this.get_washingType();
return line;
}
});
});

15
laundry_management_pos/static/src/js/product_img.js

@ -0,0 +1,15 @@
odoo.define('laundry_management_pos.pos_order_line', function(require) {
"use strict";
var models = require('point_of_sale.models');
// Extend the order lines for getting the product images
models.Orderline = models.Orderline.extend({
// Product images uploading to the particular field
get_product_image: function(){
const product = this.product;
return `/web/image?model=product.product&field=image_128&id=${product.id}&write_date=${product.write_date}&unique=1`;
},
});
});

51
laundry_management_pos/static/src/js/screen/product_create_popup.js

@ -0,0 +1,51 @@
odoo.define('laundry_management_pos.product_create_popup', function(require) {
'use strict';
const { useState, useRef } = owl.hooks;
const AbstractAwaitablePopup = require('point_of_sale.AbstractAwaitablePopup');
const Registries = require('point_of_sale.Registries');
// Extension of AbstractAwaitablePopup that allows to create a product Create popup
class ProductCreatePopup extends AbstractAwaitablePopup {
constructor() {
super(...arguments);
this.state = useState({
typeValue: this.props.startingValue,
productValue: this.props.startingValue,
priceValue: this.props.priceValue,
productRef: this.props.startingValue
});
}
getPayload() {
var selected_vals = [];
var category = this.state.typeValue;
var product = this.state.productValue;
var product_reference = this.state.productRef;
var price = this.state.priceValue;
var unit = this.state.unitValue;
var product_category = this.state.categoryValue;
selected_vals.push(category);
selected_vals.push(product);
selected_vals.push(product_reference);
selected_vals.push(price);
selected_vals.push(unit);
selected_vals.push(product_category);
return selected_vals
}
}
ProductCreatePopup.template = 'ProductCreatePopup';
ProductCreatePopup.defaultProps = {
confirmText: 'Ok',
cancelText: 'Cancel',
array: [],
title: 'Create ?',
body: '',
startingValue: '',
priceValue: 1,
list: [],
};
Registries.Component.add(ProductCreatePopup);
return ProductCreatePopup;
});

40
laundry_management_pos/static/src/js/screen/washing_type_popup.js

@ -0,0 +1,40 @@
odoo.define('laundry_management_pos.LaundryServiceTypePopup', function(require) {
'use strict';
const AbstractAwaitablePopup = require('point_of_sale.AbstractAwaitablePopup');
const Registries = require('point_of_sale.Registries');
const PosComponent = require('point_of_sale.PosComponent');
const ControlButtonsMixin = require('point_of_sale.ControlButtonsMixin');
const NumberBuffer = require('point_of_sale.NumberBuffer');
const { useListener } = require('web.custom_hooks');
const { onChangeOrder, useBarcodeReader } = require('point_of_sale.custom_hooks');
const { useState, useRef } = owl.hooks;
class LaundryServiceTypePopup extends AbstractAwaitablePopup {
constructor() {
super(...arguments);
}
// Create a new Popup instance
laundryPopup(event){
var order = this.props.pos.get_order();
if (!this.props.orderline) {
order.selected_orderline.set_washingType(event.currentTarget.dataset);
}
else{
this.props.orderline.set_washingType(event.currentTarget.dataset);
this.props.orderline.trigger('change',this.props.orderline);
}
this.trigger('close-popup');
}
}
//Create Service popup
LaundryServiceTypePopup.template = 'LaundryServiceTypePopup';
LaundryServiceTypePopup.defaultProps = {
confirmText: 'Ok',
cancelText: 'Cancel',
};
Registries.Component.add(LaundryServiceTypePopup);
return LaundryServiceTypePopup;
});

13
laundry_management_pos/static/src/xml/button/product_create_button.xml

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<!-- Template for the Product create Button-->
<t t-name="ProductCreateButton" owl="1">
<button class="button-control">
<h2>
<i class="fa fa-plus" style="padding:10px;" role="img" aria-label="Create Product" title="Create Product"/>
<span>Create Product</span>
</h2>
</button>
</t>
</templates>

23
laundry_management_pos/static/src/xml/button/washing_type_button.xml

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<!-- Inherits the order-lines for adding the laundry details into the lines-->
<t t-name="Orderline" t-inherit="point_of_sale.Orderline" t-inherit-mode="extension" owl="1">
<xpath expr="//ul[hasclass('info-list')]/t[1]/li" position="inside">
<span class="orderline-laundry" t-if="env.pos.config.orderline_washing_type">
<i t-on-click="click" class="oe_link_icon fa fa-user oe_icon line-salesperson-icon oe_green" t-if="props.line.get_washingType()" role="img"/>
<i t-on-click="click" class="oe_link_icon fa fa-user-plus oe_icon line-salesperson-icon oe_red" t-if="!props.line.get_washingType()" role="img"/>
<t t-esc="props.line.get_washingType()" />
<i t-on-click="remove_laundry" class="oe_link_icon fa fa-remove oe_icon oe_red" t-if="props.line.get_washingType()" role="img"/>
</span>
</xpath>
</t>
<!-- Laundry Service Button-->
<t t-name="LaundryServiceButton" owl="1">
<button class="button-control">
<h2>
<i class="fa fa-shopping-basket" style="padding:10px;" role="img" aria-label="Laundry Service" title="Laundry Service"/>
<span>Laundry Service</span>
</h2>
</button>
</t>
</templates>

57
laundry_management_pos/static/src/xml/pos_receipt.xml

@ -0,0 +1,57 @@
<templates id="template" xml:space="preserve">
<!-- Inherits the order lines Receipt for adding the service details-->
<t t-name="OrderLinesReceipt" t-inherit="point_of_sale.OrderLinesReceipt"
t-inherit-mode="extension" owl="1">
<xpath expr="//div[hasclass('responsive-price')]" position="before">
<t t-if="line.service_type">
<div>
<h3><i><b><t t-esc="line.service_type"/></b></i></h3>
</div>
</t>
</xpath>
<xpath expr="//t[@t-foreach='receipt.orderlines']" position="inside">
<t t-if="line.person">
<br/>
<span>Assigned person:</span><br/>
<t t-esc="line.person"/><br/>
</t>
</xpath>
</t>
<!-- Inheirited the Order Receipt for dding laundry details-->
<t t-name="OrderReceipt" t-inherit="point_of_sale.OrderReceipt"
t-inherit-mode="extension" owl="1">
<xpath expr="//t[@t-if='receipt.company.logo']" position="replace"/>
<xpath expr="//t[@t-if='receipt.company.contact_address']" position="replace" />
<xpath expr="//t[@t-if='receipt.company.phone']" position="replace" />
<xpath expr="//t[@t-if='receipt.company.vat']" position="replace" />
<xpath expr="//t[@t-if='receipt.company.email']" position="replace">
<span>
<h2 class="pos-receipt-center-align">Laundry Service</h2>
</span>
</xpath>
<xpath expr="//t[@t-if='receipt.company.website']" position="replace">
<t t-esc="receipt.company.name"/>
</xpath>
<xpath expr="//t[@t-if='receipt.cashier']" position="replace">
<div class="cashier">
<div>--------------------------------</div>
<div>Laundry Person <t t-esc="receipt.cashier" /></div>
</div>
</xpath>
<xpath expr="//div[hasclass('orderlines')]" position="before">
<div>
<div>
<t t-esc="receipt.client.name" /><br/>
<t t-esc="receipt.client.street"/><br/>
<t t-esc="receipt.client.address"/><br/>
</div>
</div><br/>
</xpath>
</t>
</templates>

11
laundry_management_pos/static/src/xml/product_img.xml

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<template id="template" xml:space="preserve">
<t t-name="Productimage" t-inherit="point_of_sale.Orderline" t-inherit-mode="extension" owl="1">
<xpath expr="//span[hasclass('product-name')]" position="before">
<span class="product-img">
<img t-att-src="props.line.get_product_image()" style="padding: 5px; height: 50px; width:40px;"/>
</span>
</xpath>
</t>
</template>

95
laundry_management_pos/static/src/xml/screen/product_create_popup.xml

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<!-- Template for Product creation popup-->
<t t-name="ProductCreatePopup" owl="1">
<div role="dialog" class="modal-dialog">
<Draggable>
<div class="popup popup-text">
<header class="title">
<div class="row">
<t t-esc="props.title"/>
</div>
</header>
<main class="body product_configurator_attributes col-lg-4 col-md-6 col-sm-12">
<div class="row">
<div>
<span>Product Name</span>
</div>
<div style="margin-top: 10px;">
<input class="name" type="text" t-model="state.productValue" required=""/>
</div>
</div>
<br/>
<div class="row">
<div>
<span>Internal Reference</span>
</div>
<div style="margin-top: 10px;">
<input class="name" type="text" t-model="state.productRef" required=""/>
</div>
</div>
<br/>
<div class="row">
<div>
<span>Product Price</span>
</div>
<div style="margin-top: 10px;">
<input class="price" type="text" t-model="state.priceValue" required=""/>
</div>
</div>
<br/>
<div class="row">
<div>
<span>Product Type</span>
</div>
<div style="margin-top: 10px;">
<select class="type" style="width: 233px;height:46px" t-model="state.typeValue" required="">
<option>Consumable</option>
<option>Storable</option>
<option>Service</option>
</select>
</div>
</div>
<br/>
<div class="row">
<div>
<span>Unit Of Measure</span>
</div>
<div style="margin-top: 10px;">
<select class="type" style="width: 233px;height:46px" t-model="state.unitValue" required="">
<t t-foreach="env.pos.units" t-as="item" t-key="item.name">
<option t-att-value="item.id" t-esc="item.name"/>
</t>
</select>
</div>
</div>
<br/>
<div class="row">
<div>
<span>Product Category</span>
</div>
<div style="margin-top: 10px;">
<select class="type" style="width: 233px;height:46px" t-model="state.categoryValue" required="">
<t t-foreach="env.pos.product_categories" t-as="item" t-key="item.name">
<option t-att-value="item.id" t-esc="item.name"/>
</t>
</select>
</div>
</div>
<br/>
</main>
<footer class="footer">
<div style="color: white;background: #6EC89B;border-color: transparent;" class="button confirm"
t-on-click="confirm">
Create Product
</div>
<div style="color:white;background:#D25B5B;border-color: transparent;" class="button cancel"
t-on-click="cancel">
Cancel
</div>
</footer>
</div>
</Draggable>
</div>
</t>
</templates>

42
laundry_management_pos/static/src/xml/screen/washing_type_popup.xml

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<!-- Create the template for the Washing type popup-->
<t t-name="LaundryServiceTypePopup" owl="1">
<div role="dialog" class="modal-dialog">
<div class="popup popup-text">
<header class="title"><t t-esc="props.title || '' " /></header>
<t t-if="props.service">
<div class='salesperson-scroll'>
<table class='salesperson'>
<tbody>
<tr t-on-click="laundryPopup"
class="salesperson-selected"
t-foreach="props.service"
t-as="service"
t-key="service['name']"
t-att-data-value="service['name']"
t-att-data-id="service['id']">
<td>
<div>
<span t-esc="service['name']" />
</div>
<div>
<span t-esc="service['amount']" />
</div>
</td>
</tr>
</tbody>
</table>
</div>
</t>
<footer class="footer">
<div class="button cancel" t-on-click="cancel">
Cancel
</div>
</footer>
</div>
</div>
</t>
</templates>

39
laundry_management_pos/views/laundry_order_views.xml

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Inherits the laundry order form view also the id inherits from
the depend module Laundry_management-->
<record id="laundry_order_form_view" model="ir.ui.view">
<field name="name">laundry.order.view.form.inherit.laundry</field>
<field name="inherit_id" ref="laundry_management.laundry_order_form_view"/>
<field name="model">laundry.order</field>
<field name="arch" type="xml">
<xpath expr="//field[@name='partner_id']" position="before">
<field name="order_ref"
attrs="{'invisible':[('is_invoiced', '=', False)]}"/>
</xpath>
<xpath expr="//field[@name='order_date']" position="before">
<field name="pos_reference"
attrs="{'invisible':[('is_invoiced', '=', False)]}"/>
</xpath>
<xpath expr="//field[@name='pos_reference']" position="before">
<field name="is_invoiced" invisible="1"/>
</xpath>
<xpath expr="//field[@name='order_lines']/tree/field[@name='extra_work']"
position="after">
<field name="tax_ids" widget="many2many_tags"/>
</xpath>
<xpath expr="//button[@name='create_invoice']"
position="attributes">
<attribute name="attrs">{'invisible': ['|', ('is_invoiced', '=', True), ('state', 'in', ('draft', 'order', 'process'))]}</attribute>
</xpath>
<xpath expr="//field[@name='order_ref']" position="after">
<field name="pos_order_id"
attrs="{'invisible':[('is_invoiced', '=', False)]}"/>
</xpath>
</field>
</record>
</odoo>

26
laundry_management_pos/views/pos_config_views.xml

@ -0,0 +1,26 @@
<odoo>
<!-- Inherits the Pos Configuration form view-->
<record id="pos_config_view_form_inherits_washing_types" model="ir.ui.view">
<field name="name">pos.config.view.form.inherits.washing.types</field>
<field name="inherit_id"
ref="point_of_sale.pos_config_view_form"/>
<field name="model">pos.config</field>
<field name="arch" type="xml">
<xpath expr="//div[@id='iface_orderline_customer_notes']"
position="after">
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane">
<field name="orderline_washing_type"/>
</div>
<div class="o_setting_right_pane">
<label for="orderline_washing_type"/>
<div class="text-muted">
Add Types on order lines to be printed on
receipt and invoice
</div>
</div>
</div>
</xpath>
</field>
</record>
</odoo>

27
laundry_management_pos/views/pos_order_views.xml

@ -0,0 +1,27 @@
<odoo>
<!-- Inherits the pos order form view -->
<record id="pos_order_view_form_inherits_order_lines" model="ir.ui.view">
<field name="name">pos.order.view.form.inherit.order.lines</field>
<field name="inherit_id" ref="point_of_sale.view_pos_pos_form"/>
<field name="model">pos.order</field>
<field name="arch" type="xml">
<xpath expr="//field[@name='fiscal_position_id']"
position="before">
<field name="laundry_order" invisible="1"/>
</xpath>
<xpath expr="//field[@name='fiscal_position_id']"
position="after">
<field name="orderline_washing_type" invisible="1"/>
</xpath>
<xpath expr="//field[@name='lines']/tree/field[@name='price_subtotal_incl']"
position="after">
<field name="washing_type_id"
attrs="{'column_invisible':
[('parent.orderline_washing_type','=', False)]}"/>
</xpath>
</field>
</record>
</odoo>
Loading…
Cancel
Save