Browse Source

Merge branch 'CybroOdoo:14.0' into 14.0

pull/298/head
Eric Fairon 3 years ago
committed by GitHub
parent
commit
dded021d7d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      account_payment_approval/__manifest__.py
  2. 4
      account_payment_approval/doc/RELEASE_NOTES.md
  3. 103
      account_payment_approval/models/account_payment.py
  4. 23
      digital_signature/__init__.py
  5. 45
      digital_signature/__manifest__.py
  6. 7
      digital_signature/doc/RELEASE_NOTES.md
  7. 26
      digital_signature/models/__init__.py
  8. 72
      digital_signature/models/inventory.py
  9. 82
      digital_signature/models/invoice.py
  10. 67
      digital_signature/models/purchase_order.py
  11. 46
      digital_signature/models/res_config_settings.py
  12. BIN
      digital_signature/static/description/assets/arrow-circle-black.png
  13. BIN
      digital_signature/static/description/assets/arrow-circle-magenta.png
  14. BIN
      digital_signature/static/description/assets/hero.png
  15. BIN
      digital_signature/static/description/assets/icons/check.png
  16. BIN
      digital_signature/static/description/assets/icons/cogs.png
  17. BIN
      digital_signature/static/description/assets/icons/consultation.png
  18. BIN
      digital_signature/static/description/assets/icons/ecom-black.png
  19. BIN
      digital_signature/static/description/assets/icons/education-black.png
  20. BIN
      digital_signature/static/description/assets/icons/hotel-black.png
  21. BIN
      digital_signature/static/description/assets/icons/license.png
  22. BIN
      digital_signature/static/description/assets/icons/lifebuoy.png
  23. BIN
      digital_signature/static/description/assets/icons/logo.png
  24. BIN
      digital_signature/static/description/assets/icons/manufacturing-black.png
  25. BIN
      digital_signature/static/description/assets/icons/pos-black.png
  26. BIN
      digital_signature/static/description/assets/icons/puzzle.png
  27. BIN
      digital_signature/static/description/assets/icons/restaurant-black.png
  28. BIN
      digital_signature/static/description/assets/icons/service-black.png
  29. BIN
      digital_signature/static/description/assets/icons/trading-black.png
  30. BIN
      digital_signature/static/description/assets/icons/training.png
  31. BIN
      digital_signature/static/description/assets/icons/update.png
  32. BIN
      digital_signature/static/description/assets/icons/user.png
  33. BIN
      digital_signature/static/description/assets/icons/wrench.png
  34. BIN
      digital_signature/static/description/assets/modules/barcode_scanning.png
  35. BIN
      digital_signature/static/description/assets/modules/barcode_scanning_support.png
  36. BIN
      digital_signature/static/description/assets/modules/dynamic_financial_report.jpg
  37. BIN
      digital_signature/static/description/assets/modules/invoice.jpg
  38. BIN
      digital_signature/static/description/assets/modules/support_package.jpg
  39. BIN
      digital_signature/static/description/assets/modules/whatsapp-mail-messaging.jpg
  40. BIN
      digital_signature/static/description/assets/respnsive-img.png
  41. BIN
      digital_signature/static/description/assets/screenshots/hero.gif
  42. BIN
      digital_signature/static/description/assets/screenshots/settings_purchase.png
  43. BIN
      digital_signature/static/description/assets/screenshots/sticky_header.png
  44. BIN
      digital_signature/static/description/banner.png
  45. BIN
      digital_signature/static/description/icon.png
  46. BIN
      digital_signature/static/description/images/bill.png
  47. BIN
      digital_signature/static/description/images/delivery.png
  48. BIN
      digital_signature/static/description/images/invoice.png
  49. BIN
      digital_signature/static/description/images/picking.png
  50. BIN
      digital_signature/static/description/images/purchase_option.png
  51. BIN
      digital_signature/static/description/images/purchase_order.png
  52. BIN
      digital_signature/static/description/images/settings_inventory.png
  53. BIN
      digital_signature/static/description/images/settings_invoice.png
  54. BIN
      digital_signature/static/description/images/settings_purchase.png
  55. BIN
      digital_signature/static/description/images/signature_purchase.png
  56. BIN
      digital_signature/static/description/images/warning_purchase.png
  57. 627
      digital_signature/static/description/index.html
  58. 31
      digital_signature/views/inventory.xml
  59. 52
      digital_signature/views/invoice.xml
  60. 27
      digital_signature/views/invoice_report.xml
  61. 31
      digital_signature/views/purchase_order.xml
  62. 29
      digital_signature/views/purchase_report_inherit.xml
  63. 217
      digital_signature/views/res_config_settings.xml
  64. 61
      digital_signature/views/stock_picking_report.xml
  65. 2
      invoice_format_editor/__manifest__.py
  66. 11
      invoice_format_editor/doc/RELEASE_NOTES.md
  67. 8
      invoice_format_editor/reports/custom_invoice_template.xml
  68. 113
      invoice_format_editor/reports/default_invoice_template.xml
  69. 42
      pos_report_generator/README.rst
  70. 24
      pos_report_generator/__init__.py
  71. 50
      pos_report_generator/__manifest__.py
  72. 22
      pos_report_generator/controllers/__init__.py
  73. 56
      pos_report_generator/controllers/controllers.py
  74. 6
      pos_report_generator/doc/RELEASE_NOTES.md
  75. 22
      pos_report_generator/models/__init__.py
  76. 567
      pos_report_generator/models/pos_report.py
  77. 22
      pos_report_generator/report/__init__.py
  78. 37
      pos_report_generator/report/pos_order_report.py
  79. 478
      pos_report_generator/report/pos_order_report.xml
  80. 2
      pos_report_generator/security/ir.model.access.csv
  81. BIN
      pos_report_generator/static/description/assets/icons/check.png
  82. BIN
      pos_report_generator/static/description/assets/icons/chevron.png
  83. BIN
      pos_report_generator/static/description/assets/icons/cogs.png
  84. BIN
      pos_report_generator/static/description/assets/icons/consultation.png
  85. BIN
      pos_report_generator/static/description/assets/icons/ecom-black.png
  86. BIN
      pos_report_generator/static/description/assets/icons/education-black.png
  87. BIN
      pos_report_generator/static/description/assets/icons/hotel-black.png
  88. BIN
      pos_report_generator/static/description/assets/icons/license.png
  89. BIN
      pos_report_generator/static/description/assets/icons/lifebuoy.png
  90. BIN
      pos_report_generator/static/description/assets/icons/logo.png
  91. BIN
      pos_report_generator/static/description/assets/icons/manufacturing-black.png
  92. BIN
      pos_report_generator/static/description/assets/icons/pos-black.png
  93. BIN
      pos_report_generator/static/description/assets/icons/puzzle.png
  94. BIN
      pos_report_generator/static/description/assets/icons/restaurant-black.png
  95. BIN
      pos_report_generator/static/description/assets/icons/service-black.png
  96. BIN
      pos_report_generator/static/description/assets/icons/trading-black.png
  97. BIN
      pos_report_generator/static/description/assets/icons/training.png
  98. BIN
      pos_report_generator/static/description/assets/icons/update.png
  99. BIN
      pos_report_generator/static/description/assets/icons/user.png
  100. BIN
      pos_report_generator/static/description/assets/icons/wrench.png

2
account_payment_approval/__manifest__.py

@ -22,7 +22,7 @@
{
'name': 'Payment Approvals',
'version': '14.0.1.0.0',
'version': '14.0.1.0.1',
'category': 'Accounting',
'summary': """ This modules enables approval feature in the payment.""",
'description': """This modules enables approval feature in the payment. """,

4
account_payment_approval/doc/RELEASE_NOTES.md

@ -5,3 +5,7 @@
##### ADD
- Initial commit for Payment Approval
#### 29.06.2022
#### Version 14.0.1.0.1
##### ADD
- Solved Payment Issue

103
account_payment_approval/models/account_payment.py

@ -37,6 +37,9 @@ class AccountPayment(models.Model):
_inherit = "account.payment"
_inherits = {'account.move': 'move_id'}
origin_invoice_ids = fields.Many2many('account.move', string='Invoice Origin')
to_reconcile_inv = fields.Many2one('account.move.line', string='Reconcile Move Line')
def _check_is_approver(self):
approval = self.env['ir.config_parameter'].sudo().get_param(
'account_payment_approval.payment_approval')
@ -50,16 +53,62 @@ class AccountPayment(models.Model):
"""Overwrites the _post() to validate the payment in the 'approved' stage too.
Currently Odoo allows payment posting only in draft stage.
"""
if self._context.get('active_model') == 'account.move':
if self._context.get('active_ids'):
if len(self._context.get('active_ids')) == 1:
self.write({
'origin_invoice_ids': [(4, self._context.get('active_ids')[0])]
})
validation = self._check_payment_approval()
if not validation:
if self.state in ('waiting_approval'):
return True
if self.state not in ('draft', 'approved'):
raise UserError(_("Only a draft or approved payment can be posted."))
if any(inv.state != 'posted' for inv in self.reconciled_invoice_ids):
raise ValidationError(_("The payment cannot be processed because the invoice is not open!"))
self.move_id._post(soft=False)
else:
self.move_id._post(soft=False)
if len(self._context.get('active_ids')) > 1:
for rec in self:
validation = rec._check_payment_approval()
else:
validation = self._check_payment_approval()
if validation:
if not validation:
if self.state in ('waiting_approval'):
return True
if self.state not in ('draft', 'approved'):
raise UserError(_("Only a draft or approved payment can be posted."))
if any(inv.state != 'posted' for inv in self.reconciled_invoice_ids):
raise ValidationError(_("The payment cannot be processed because the invoice is not open!"))
self.move_id._post(soft=False)
self.reconcile_move_payment()
else:
self.move_id._post(soft=False)
self.reconcile_move_payment()
def reconcile_move_payment(self):
if self.to_reconcile_inv:
domain = [('account_internal_type', 'in', ('receivable', 'payable')), ('reconciled', '=', False)]
payment_lines = self.line_ids.filtered_domain(domain)
lines = self.to_reconcile_inv
for account in payment_lines.account_id:
(payment_lines + lines) \
.filtered_domain([('account_id', '=', account.id), ('reconciled', '=', False)]) \
.reconcile()
def _check_payment_approval(self):
if not self.state:
return True
if self.state == "draft":
first_approval = self.env['ir.config_parameter'].sudo().get_param(
'account_payment_approval.payment_approval')
@ -81,6 +130,7 @@ class AccountPayment(models.Model):
})
return False
return True
return True
def approve_transfer(self):
if self.is_approver:
@ -92,3 +142,54 @@ class AccountPayment(models.Model):
self.write({
'state': 'rejected'
})
class AccountPaymentRegister(models.TransientModel):
_inherit = 'account.payment.register'
def _create_payments(self):
self.ensure_one()
batches = self._get_batches()
edit_mode = self.can_edit_wizard and (len(batches[0]['lines']) == 1 or self.group_payment)
to_process = []
if edit_mode:
payment_vals = self._create_payment_vals_from_wizard()
to_process.append({
'create_vals': payment_vals,
'to_reconcile': batches[0]['lines'],
'batch': batches[0],
})
else:
# Don't group payments: Create one batch per move.
if not self.group_payment:
new_batches = []
for batch_result in batches:
for line in batch_result['lines']:
new_batches.append({
**batch_result,
'lines': line,
})
batches = new_batches
for batch_result in batches:
to_reconcile_inv = batch_result['lines']
to_process.append({
'create_vals': self._create_payment_vals_from_batch(batch_result),
'to_reconcile': batch_result['lines'],
'batch': batch_result,
})
payments = self._init_payments(to_process, edit_mode=edit_mode)
self._post_payments(to_process, edit_mode=edit_mode)
for item_rec in to_process:
item_rec.get('payment').write({
'to_reconcile_inv': item_rec.get('to_reconcile'),
})
for rec in payments:
if rec.state == 'posted':
self._reconcile_payments(to_process, edit_mode=edit_mode)
return payments

23
digital_signature/__init__.py

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from . import models

45
digital_signature/__manifest__.py

@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
{
'name': 'Digital Signature In Purchase Order, Invoice, Inventory',
'summary': 'Digital Signature in Purchase Order, Invoice, Inventory',
'version': '14.0.1.0.0',
'description': """Digital Signature in Purchase Order, Invoice, Inventory""",
'author': 'Cybrosys Techno Solutions',
'company': 'Cybrosys Techno Solutions',
'maintainer': 'Cybrosys Techno Solutions',
'website': 'https://www.cybrosys.com',
'depends': ['purchase', 'stock', 'account'],
'data': [
'views/res_config_settings.xml',
'views/purchase_order.xml',
'views/inventory.xml',
'views/invoice.xml',
'views/purchase_report_inherit.xml',
'views/stock_picking_report.xml',
'views/invoice_report.xml',
],
'installable': True,
'application': False,
'images': ['static/description/banner.png'],
'license': 'LGPL-3',
}

7
digital_signature/doc/RELEASE_NOTES.md

@ -0,0 +1,7 @@
## Module <digital_signature>
#### 01.06.2022
#### Version 14.0.1.0.0
#### ADD
- Initial commit for Odoo 14 Digital Signature

26
digital_signature/models/__init__.py

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from . import res_config_settings
from . import purchase_order
from . import inventory
from . import invoice

72
digital_signature/models/inventory.py

@ -0,0 +1,72 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import models, fields, api, _
from odoo.exceptions import Warning, UserError
class InventoryInherit(models.Model):
_inherit = "stock.picking"
def _default_show_sign(self):
return self.env['ir.config_parameter'].sudo().get_param(
'digital_signature.show_digital_sign_inventory')
def _default_enable_options(self):
return self.env['ir.config_parameter'].sudo().get_param(
'digital_signature.enable_options_inventory')
digital_sign = fields.Binary(string='Signature')
sign_by = fields.Char(string='Signed By')
designation = fields.Char(string='Designation')
sign_on = fields.Datetime(string='Signed On')
show_sign = fields.Boolean(default=_default_show_sign,
compute='_compute_show_sign')
enable_option = fields.Boolean(default=_default_enable_options,
compute='_compute_enable_optiion')
sign_applicable = fields.Selection([
('picking_operations', 'Picking Operations'),
('delivery', 'Delivery Slip'),
('both', 'Both'),
], string="Sign Applicable inside", compute='_compute_sign_applicable')
def button_validate(self):
res = super(InventoryInherit, self).button_validate()
if self.env['ir.config_parameter'].sudo().get_param(
'digital_signature.confirm_sign_inventory') and self.digital_sign is False:
raise UserError('Signature is missing')
return res
def _compute_show_sign(self):
show_signature = self._default_show_sign()
for record in self:
record.show_sign = show_signature
def _compute_enable_optiion(self):
enable_others = self._default_enable_options()
for record in self:
record.enable_option = enable_others
def _compute_sign_applicable(self):
for rec in self:
rec.sign_applicable = self.env['ir.config_parameter'].sudo().get_param(
'digital_signature.sign_applicable')

82
digital_signature/models/invoice.py

@ -0,0 +1,82 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import models, fields, api, _
from odoo.exceptions import Warning, UserError
class InvoiceInherit(models.Model):
_inherit = "account.move"
@api.model
def _default_show_sign(self):
return self.env['ir.config_parameter'].sudo().get_param(
'digital_signature.show_digital_sign_invoice')
@api.model
def _default_enable_sign(self):
return self.env['ir.config_parameter'].sudo().get_param(
'digital_signature.enable_options_invoice')
@api.model
def _default_show_sign_bill(self):
return self.env['ir.config_parameter'].sudo().get_param(
'digital_signature.show_digital_sign_bill')
digital_sign = fields.Binary(string='Signature')
sign_by = fields.Char(string='Signed By')
designation = fields.Char(string='Designation')
sign_on = fields.Datetime(string='Signed On')
show_signature = fields.Boolean('Show Signature',
default=_default_show_sign,
compute='_compute_show_signature')
show_sign_bill = fields.Boolean('Show Signature',
default=_default_show_sign_bill,
compute='_compute_show_sign_bill')
enable_others = fields.Boolean(default=_default_enable_sign,
compute='_compute_enable_others')
def button_confirm(self):
res = super(InvoiceInherit, self).button_confirm()
if self.env[
'ir.config_parameter'].sudo().get_param(
'digital_signature.confirm_sign_invoice') and self.digital_sign is False:
raise UserError(_("Signature is missing"))
return res
def _compute_show_signature(self):
show_signature = self._default_show_sign()
print(show_signature)
for record in self:
record.show_signature = show_signature
def _compute_enable_others(self):
enable_others = self._default_enable_sign
print(enable_others)
for record in self:
record.enable_others = enable_others
def _compute_show_sign_bill(self):
show_sign_bill = self._default_show_sign_bill()
for record in self:
record.show_sign_bill = show_sign_bill

67
digital_signature/models/purchase_order.py

@ -0,0 +1,67 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import models, fields, api, _
from odoo.exceptions import Warning, UserError
class PurchaseOrderInherit(models.Model):
_inherit = "purchase.order"
@api.model
def _default_show_sign(self):
return self.env['ir.config_parameter'].sudo().get_param(
'digital_signature.show_digital_sign_po')
@api.model
def _default_enable_sign(self):
return self.env['ir.config_parameter'].sudo().get_param(
'digital_signature.enable_options_po')
digital_sign = fields.Binary(string='Signature')
sign_by = fields.Char(string='Signed By')
designation = fields.Char(string='Designation')
sign_on = fields.Datetime(string='Signed On')
show_signature = fields.Boolean('Show Signature',
default=_default_show_sign,
compute='_compute_show_signature')
enable_others = fields.Boolean(default=_default_enable_sign,
compute='_compute_enable_others')
def button_confirm(self):
res = super(PurchaseOrderInherit, self).button_confirm()
if self.env[
'ir.config_parameter'].sudo().get_param(
'digital_signature.confirm_sign_po') and self.digital_sign is False:
raise UserError(_("Signature is missing"))
return res
def _compute_show_signature(self):
show_signature = self._default_show_sign()
for record in self:
record.show_signature = show_signature
def _compute_enable_others(self):
enable_others = self._default_enable_sign
for record in self:
record.enable_others = enable_others

46
digital_signature/models/res_config_settings.py

@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import models, fields, api, _
class ResConfigurationInherit(models.TransientModel):
_inherit = 'res.config.settings'
show_digital_sign_po = fields.Boolean(config_parameter='digital_signature.show_digital_sign_po')
enable_options_po = fields.Boolean(default=True, config_parameter='digital_signature.enable_options_po')
confirm_sign_po = fields.Boolean(config_parameter='digital_signature.confirm_sign_po')
show_digital_sign_inventory = fields.Boolean(config_parameter='digital_signature.show_digital_sign_inventory')
enable_options_inventory = fields.Boolean(default=True, config_parameter='digital_signature.enable_options_inventory')
sign_applicable = fields.Selection([
('picking_operations', 'Picking Operations'),
('delivery', 'Delivery Slip'),
('both', 'Both'),
], string="Sign Applicable inside",
default="picking_operations",
config_parameter='digital_signature.sign_applicable')
confirm_sign_inventory = fields.Boolean(config_parameter='digital_signature.confirm_sign_inventory')
show_digital_sign_invoice = fields.Boolean(config_parameter='digital_signature.show_digital_sign_invoice')
enable_options_invoice = fields.Boolean(config_parameter='digital_signature.enable_options_invoice')
confirm_sign_invoice = fields.Boolean(config_parameter='digital_signature.confirm_sign_invoice')
show_digital_sign_bill = fields.Boolean(config_parameter='digital_signature.show_digital_sign_bill')

BIN
digital_signature/static/description/assets/arrow-circle-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

BIN
digital_signature/static/description/assets/arrow-circle-magenta.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

BIN
digital_signature/static/description/assets/hero.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
digital_signature/static/description/assets/icons/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 839 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 988 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
digital_signature/static/description/assets/modules/barcode_scanning.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

BIN
digital_signature/static/description/assets/modules/barcode_scanning_support.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

BIN
digital_signature/static/description/assets/modules/dynamic_financial_report.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

BIN
digital_signature/static/description/assets/modules/invoice.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

BIN
digital_signature/static/description/assets/modules/support_package.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

BIN
digital_signature/static/description/assets/modules/whatsapp-mail-messaging.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

BIN
digital_signature/static/description/assets/respnsive-img.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

BIN
digital_signature/static/description/assets/screenshots/settings_purchase.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 452 KiB

BIN
digital_signature/static/description/assets/screenshots/sticky_header.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 KiB

BIN
digital_signature/static/description/banner.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

BIN
digital_signature/static/description/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
digital_signature/static/description/images/bill.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

BIN
digital_signature/static/description/images/delivery.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

BIN
digital_signature/static/description/images/invoice.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

BIN
digital_signature/static/description/images/picking.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

BIN
digital_signature/static/description/images/purchase_option.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 KiB

BIN
digital_signature/static/description/images/purchase_order.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 KiB

BIN
digital_signature/static/description/images/settings_inventory.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 KiB

BIN
digital_signature/static/description/images/settings_invoice.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 KiB

BIN
digital_signature/static/description/images/settings_purchase.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 452 KiB

BIN
digital_signature/static/description/images/signature_purchase.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

BIN
digital_signature/static/description/images/warning_purchase.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 KiB

627
digital_signature/static/description/index.html

@ -0,0 +1,627 @@
<div class="container" style="padding: 1rem !important; margin-bottom: 1rem !important;">
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-12 d-flex justify-content-between" style="border-bottom: 1px solid #d5d5d5;">
<div class="my-3">
<img src="./assets/icons/logo.png" style="width: auto !important; height: 40px !important;">
</div>
<div class="my-3 d-flex align-items-center">
<div
style="background-color: #7C7BAD !important; color: #fff !important; font-weight: 600 !important; padding: 5px 15px 8px !important; margin: 0 5px !important;">
<i class="fa fa-check mr-1"></i>Community
</div>
<div
style="background-color: #875A7B !important; color: #fff !important; font-weight: 600 !important; padding: 5px 15px 8px !important; margin: 0 5px !important;">
<i class="fa fa-check mr-1"></i>Enterprise
</div>
</div>
</div>
</div>
</div>
<div class="container" style="padding: 0rem 1.5rem 4rem !important">
<div class="row" style="height: 900px !important;">
<div class="col-sm-12 col-md-12 col-lg-12"
style="padding: 4rem 1rem !important; background-color: #714B67 !important; height: 600px !important; border-radius: 20px !important;">
<h1
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #FFFFFF !important; font-size: 3.5rem !important; text-align: center !important;">
Digital Signature In Purchase, Inventory, Invoice</h1>
<p
style="font-family: 'Montserrat', sans-serif !important; font-weight: 300 !important; color: #FFFFFF !important; font-size: 1.4rem !important; text-align: center !important;">
A Module for adding Digital Signatures in Purchase, Inventory, Invoice
</p>
<img src="./assets/screenshots/hero.gif" class="img-responsive" width="100%" height="auto" />
</div>
</div>
<div class="row">
<div class="col-md-12" style="border-bottom: 1px solid #d5d5d5 !important; margin-bottom: 2rem !important">
<h2
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.5rem !important;">
<i class="fa fa-compass mr-2"></i>Explore this module
</h2>
<div class="row">
<div class="col-md-6">
<a href="#overview" style="text-decoration: none !important;">
<div class="row"
style="background-color: #f5f2f5 !important; border-radius: 10px !important; margin: 1rem !important; padding: 1.5em !important; height: 100px !important;">
<div class="col-8">
<h3
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.2rem !important;">
Overview</h3>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #714B67 !important; font-size: 0.9rem !important;">
Learn more about this module</p>
</div>
<div class="col-4 text-right d-flex justify-content-end align-items-center">
<i class="fa fa-chevron-right" style="color: #714B67 !important;"></i>
</div>
</div>
</a>
</div>
<div class="col-md-6">
<a href="#features" style="text-decoration: none !important;">
<div class="row"
style="background-color: #f5f2f5 !important; border-radius: 10px !important; margin: 1rem !important; padding: 1.5em !important; height: 100px !important;">
<div class="col-8">
<h3
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.2rem !important;">
Features</h3>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #714B67 !important; font-size: 0.9rem !important;">
View features of this module</p>
</div>
<div class="col-4 text-right d-flex justify-content-end align-items-center">
<i class="fa fa-chevron-right" style="color: #714B67 !important;"></i>
</div>
</div>
</a>
</div>
<div class="col-md-6">
<a href="#screenshots" style="text-decoration: none !important;">
<div class="row"
style="background-color: #f5f2f5 !important; border-radius: 10px !important; margin: 1rem !important; padding: 1.5em !important; height: 100px !important;">
<div class="col-8">
<h3
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.2rem !important;">
Screenshots</h3>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #714B67 !important; font-size: 0.9rem !important;">
See key screenshots of this module</p>
</div>
<div class="col-4 text-right d-flex justify-content-end align-items-center">
<i class="fa fa-chevron-right" style="color: #714B67 !important;"></i>
</div>
</div>
</a>
</div>
</div>
</div>
</div>
<div class="row" id="overview">
<div class="col-md-12" style="border-bottom: 1px solid #d5d5d5 !important; margin: 2rem 0 !important">
<h2
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.5rem !important;">
<i class="fa fa-pie-chart mr-2"></i>Overview
</h2>
</div>
<div class="col-mg-12 pl-3">
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important; line-height: 30px !important;">
This module helps to add the digital signature in purchase order, delivery slip, picking operations, customer invoices and vendor bills, and other details like signed by, designation, and date. Configurations for setting the signature as mandatory, if it is missing raise a warning. </div>
</p>
</div>
<div class="row" id="features">
<div class="col-md-12" style="border-bottom: 1px solid #d5d5d5 !important; margin: 2rem 0 !important">
<h2
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.5rem !important;">
<i class="fa fa-star mr-2"></i>Features
</h2>
</div>
<div class="col-md-6 pl-3 py-3 d-flex">
<div>
<img src="assets/icons/check.png">
</div>
<div>
<h4
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Print digital signature in reports</h4>
</div>
</div>
<div class="col-md-6 pl-3 py-3 d-flex">
<div>
<img src="assets/icons/check.png">
</div>
<div>
<h4
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Enable other options to add signature details</h4>
</div>
</div>
<div class="col-md-6 pl-3 py-3 d-flex">
<div>
<img src="assets/icons/check.png">
</div>
<div>
<h4
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Check signature before Confirmations
</h4>
</div>
</div>
</div>
<div class="row" id="screenshots">
<div class="col-md-12" style="border-bottom: 1px solid #d5d5d5 !important; margin: 2rem 0 !important">
<h2
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.5rem !important;">
<i class="fa fa-image mr-2"></i>Screenshots
</h2>
</div>
<div class="col-lg-12 my-3">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Settings in Purchase Module to Show Signature in Purchase Order
</h4>
<img src="images/settings_purchase.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
<div class="col-lg-12 my-3">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Enable Other Options to add extra signature details, Check signature before confirmation to raise a warning When signature is missing</h4>
<img src="images/purchase_option.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
<div class="col-lg-12 my-3">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Digital Signature Fields in Purchase Order</h4>
<img src="images/purchase_order.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
<div class="col-lg-12 my-3">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Digital Signature in Pdf Report</h4>
<img src="images/signature_purchase.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
<div class="col-lg-12 my-3">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Raise warning when signature is missing</h4>
<img src="images/warning_purchase.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
<div class="col-lg-12 my-3">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Signature Configuration in Inventory Settings</h4>
<img src="images/settings_inventory.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
<div class="col-lg-12 my-2">
<h4 class="mt-2"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Signature Configuration in Invoice Settings</h4>
<img src="images/settings_invoice.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
<div class="col-lg-12 my-3">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Digital Signature in Picking Operation</h4>
<img src="images/picking.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
<div class="col-lg-12 my-3">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Digital Signature in Delivery Slip</h4>
<img src="images/delivery.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
<div class="col-lg-12 my-3">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Digital Signature in Customer Invoice
</h4>
<img src="images/invoice.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
<div class="col-lg-12 my-3">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Digital Signature in Vendor Bill</h4>
<img src="images/bill.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
</div>
<!-- SUGGESTED PRODUCTS -->
<div class="row">
<div class="col-lg-12 d-flex flex-column justify-content-center"
style="text-align: center; padding: 2.5rem 1rem !important;">
<h2 style="color: #212529 !important;">Suggested Products</h2>
<hr
style="border: 3px solid #714B67 !important; background-color: #714B67 !important; width: 80px !important; margin-bottom: 2rem !important;" />
<div>
<div id="suggestedSlider" class="row carousel slide" data-ride="carousel">
<!-- The slideshow -->
<div class="carousel-inner">
<div class="carousel-item" style="min-height: 191px;">
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/14.0/dynamic_accounts_report/" 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/dynamic_financial_report.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/14.0/inventory_barcode_scanning/" 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_scanning.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/14.0/barcode_scanning_sale_purchase/"
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_scanning_support.png">
</div>
</a>
</div>
</div>
<div class="carousel-item active" style="min-height: 191px;">
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/14.0/support_package/" 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/support_package.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/14.0/invoice_format_editor/" 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/invoice.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/14.0/whatsapp_mail_messaging/" 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/whatsapp-mail-messaging.jpg">
</div>
</a>
</div>
</div>
</div>
<!-- Left and right controls -->
<a class="carousel-control-prev" href="#suggestedSlider" data-slide="prev" style="width:35px; color:#000">
<span class="carousel-control-prev-icon"><i class="fa fa-chevron-left"
style="font-size:24px"></i></span> </a> <a class="carousel-control-next" href="#suggestedSlider"
data-slide="next" style="width:35px; color:#000">
<span class="carousel-control-next-icon"><i class="fa fa-chevron-right"
style="font-size:24px"></i></span>
</a>
</div>
</div>
</div>
</div>
<!-- END OF SUGGESTED PRODUCTS -->
<!-- OUR SERVICES -->
<section class="container" style="margin-top: 6rem !important;">
<div class="row">
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center">
<h2 style="color: #212529 !important;">Our Services</h2>
<hr
style="border: 3px solid #714B67 !important; background-color: #714B67 !important; width: 80px !important; margin-bottom: 2rem !important;" />
</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: #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>
</section>
<!-- END OF END OF OUR SERVICES -->
<!-- OUR INDUSTRIES -->
<section class="container" style="margin-top: 6rem !important;">
<div class="row">
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center">
<h2 style="color: #212529 !important;">Our Industries</h2>
<hr
style="border: 3px solid #714B67 !important; background-color: #714B67 !important; width: 80px !important; margin-bottom: 2rem !important;" />
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; 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: 10px; 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: 10px; 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: 10px; 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: 10px; 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: 10px; 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: 10px; 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: 10px; 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>
</section>
<!-- END OF END OF OUR INDUSTRIES -->
<!-- FOOTER -->
<!-- Footer Section -->
<section class="container" style="margin: 5rem auto 2rem;">
<div class="row" style="max-width:1540px;">
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center">
<h2 style="color: #212529 !important;">Need Help?</h2>
<hr
style="border: 3px solid #714B67 !important; background-color: #714B67 !important; width: 80px !important; margin-bottom: 2rem !important;" />
</div>
</div>
<!-- Contact Cards -->
<div class="row d-flex justify-content-center align-items-center"
style="max-width:1540px; margin: 0 auto 2rem auto;">
<div class="col-lg-12" style="padding: 0rem 3rem 2rem; border-radius: 10px; margin-right: 3rem; ">
<div class="row mt-4">
<div class="col-lg-6">
<a href="mailto:odoo@cybrosys.com" target="_blank" class="btn btn-block mb-2 deep_hover"
style="text-decoration: none; background-color: #4d4d4d; color: #FFF; border-radius: 4px;"><i
class="fa fa-envelope mr-2"></i>odoo@cybrosys.com</a>
</div>
<div class="col-lg-6">
<a href="https://api.whatsapp.com/send?phone=918606827707" target="_blank"
class="btn btn-block mb-2 deep_hover"
style="text-decoration: none; background-color: #25D366; color: #FFF; border-radius: 4px;"><i
class="fa fa-whatsapp mr-2"></i>+91 86068 27707</a>
</div>
</div>
</div>
</div>
<!-- End of Contact Cards -->
</section>
<!-- Footer -->
<section class="oe_container" style="padding: 2rem 3rem 1rem;">
<div class="row" style="max-width:1540px; margin: 0 auto; margin-right: 3rem; ">
<!-- Logo -->
<div class="col-lg-12 d-flex justify-content-center align-items-center" style="margin-top: 3rem;">
<img src="https://www.cybrosys.com/images/logo.png" width="200px" height="auto" />
</div>
<!-- End of Logo -->
<div class="col-lg-12">
<hr
style="margin-top: 3rem;background: linear-gradient(90deg, rgba(2,0,36,0) 0%, rgba(229,229,229,1) 33%, rgba(229,229,229,1) 58%, rgba(0,212,255,0) 100%); height: 2px; border-style: none;">
<!-- End of Footer Section -->
</div>
</div>
</section>
<!-- END OF FOOTER -->
</div>

31
digital_signature/views/inventory.xml

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="inventory_view_form_inherit" model="ir.ui.view">
<field name="name">inventory.view.form.inherit</field>
<field name="model">stock.picking</field>
<field name="priority" eval="20"/>
<field name="inherit_id" ref="stock.view_picking_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='move_ids_without_package']"
position="after">
<group>
<field name="show_sign" invisible="1"/>
<field name="enable_option" invisible="1"/>
<field name="sign_applicable" invisible="1"/>
<group name="inventory_signature" string="Digital Signature"
attrs="{'invisible': [('show_sign','=',False)]}">
<field name="digital_sign"/>
<field name="sign_by"
attrs="{'invisible': [('enable_option','=',
False)]}"/>
<field name="designation"
attrs="{'invisible': [('enable_option','=',False)]}"/>
<field name="sign_on"
attrs="{'invisible': [('enable_option','=',False)]}"/>
</group>
</group>
</xpath>
</field>
</record>
</odoo>

52
digital_signature/views/invoice.xml

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record model="ir.ui.view" id="account_move_inherit">
<field name="name">account.move.inherit</field>
<field name="model">account.move</field>
<field name="inherit_id" ref="account.view_move_form"/>
<field name="arch" type="xml">
<xpath expr="//page[@id='invoice_tab']" position="after">
<field name="show_signature" invisible="1"/>
<page string="Digital Signature"
attrs="{'invisible': ['|', ('show_signature','=',False),
('move_type', '!=', 'out_invoice')]}">
<group>
<field name="enable_others" invisible="1"/>
<field name="digital_sign"/>
<field name="sign_by"
attrs="{'invisible': [
('enable_others','=',False)]}"/>
<field name="designation"
attrs="{'invisible': [
('enable_others','=',False)]}"/>
<field name="sign_on"
attrs="{'invisible': [
('enable_others','=',False)]}"/>
</group>
</page>
</xpath>
<xpath expr="//field[@name='narration']" position="before">
<field name="show_sign_bill" invisible="1"/>
<group string="Digital Signature"
attrs="{'invisible': ['|', ('show_sign_bill','=',False),
('move_type', '!=', 'in_invoice')]}">
<group>
<field name="enable_others" invisible="1"/>
<field name="digital_sign"/>
<field name="sign_by"
attrs="{'invisible': [
('enable_others','=',False)]}"/>
<field name="designation"
attrs="{'invisible': [
('enable_others','=',False)]}"/>
<field name="sign_on"
attrs="{'invisible': [
('enable_others','=',False)]}"/>
</group>
</group>
</xpath>
</field>
</record>
</odoo>

27
digital_signature/views/invoice_report.xml

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="report_invoice_report_inherit_sale"
inherit_id="account.report_invoice_document">
<xpath expr="//div[@id='qrcode']" position="after">
<div id="signature" class="row justify-content-end">
<div class="col-4">
<table class="table table-sm">
<div t-if="o.digital_sign" class="mt32 ml64 mr4"
name="signature">
<img t-att-src="image_data_uri(o.digital_sign)"
style="max-height: 4cm; max-width: 8cm;
padding-top: 50px;"/>
</div>
<tr>
<td class="text-right">
<p t-field="o.sign_by"/>
<p t-field="o.sign_on"/>
<p t-field="o.designation"/>
</td>
</tr>
</table>
</div>
</div>
</xpath>
</template>
</odoo>

31
digital_signature/views/purchase_order.xml

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="purchase_order_view_form_inherit" model="ir.ui.view">
<field name="name">purchase.order.view.form.inherit</field>
<field name="model">purchase.order</field>
<field name="priority" eval="20"/>
<field name="inherit_id" ref="purchase.purchase_order_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='notes']" position="before">
<group>
<field name="show_signature" invisible="1"/>
<field name="enable_others" invisible="1"/>
<group name="purchase_signature" string="Digital Signature"
attrs="{'invisible': [('show_signature','=',False)]}">
<field name="digital_sign"/>
<field name="sign_by"
attrs="{'invisible': [
('enable_others','=',False)]}"/>
<field name="designation"
attrs="{'invisible': [
('enable_others','=',False)]}"/>
<field name="sign_on"
attrs="{'invisible': [
('enable_others','=',False)]}"/>
</group>
</group>
</xpath>
</field>
</record>
</odoo>

29
digital_signature/views/purchase_report_inherit.xml

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<template id="purchase_report_inherit"
inherit_id="purchase.report_purchaseorder_document">
<xpath expr="//div[@id='total']" position="after">
<div id="signature" class="row justify-content-end">
<div class="col-4">
<table class="table table-sm">
<div t-if="o.digital_sign" class="mt32 ml64 mr4"
name="signature">
<img t-att-src="image_data_uri(o.digital_sign)"
style="max-height: 4cm; max-width: 8cm;
padding-top: 50px;"/>
</div>
<tr>
<td class="text-right">
<p t-field="o.sign_by"/>
<p t-field="o.sign_on"/>
<p t-field="o.designation"/>
</td>
</tr>
</table>
</div>
</div>
</xpath>
</template>
</odoo>

217
digital_signature/views/res_config_settings.xml

@ -0,0 +1,217 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="res_config_settings_view_form_purchase_inherit"
model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit.purchase</field>
<field name="model">res.config.settings</field>
<field name="priority" eval="10"/>
<field name="inherit_id"
ref="purchase.res_config_settings_view_form_purchase" />
<field name="arch" type="xml">
<xpath expr="//div[@data-key='purchase']/div[
@name='matrix_setting_container']"
position="after">
<h2>Digital Signature</h2>
<div class="row mt16 o_settings_container">
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane">
<field name="show_digital_sign_po"/>
</div>
<div class="o_setting_right_pane">
<label for="show_digital_sign_po"
string="Show Digital Sign
in Purchase Orders?"/>
<div class="text-muted">
Show digital sign inside purchase orders
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box"
attrs="{'invisible': [
('show_digital_sign_po', '==', False)]}">
<div class="o_setting_left_pane">
<field name="enable_options_po"/>
</div>
<div class="o_setting_right_pane">
<label for="enable_options_po"
string="Enable Other Sign Options"/>
<div class="text-muted">
Enable Other Sign Option
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box"
attrs="{'invisible': [
('show_digital_sign_po', '==', False)]}">
<div class="o_setting_left_pane">
<field name="confirm_sign_po"/>
</div>
<div class="o_setting_right_pane">
<label for="confirm_sign_po"
string="Check Sign
before confirmation"/>
<div class="text-muted">
Check Sign before confirmation
purchase Order
</div>
</div>
</div>
</div>
</xpath>
</field>
</record>
<record id="res_config_settings_view_form_stock_inherit" model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit.stock</field>
<field name="model">res.config.settings</field>
<field name="priority" eval="10"/>
<field name="inherit_id" ref="stock.res_config_settings_view_form" />
<field name="arch" type="xml">
<xpath expr="//div[@data-key='stock']/div[
@name='warehouse_setting_container']" position="after">
<h2>Digital Signature</h2>
<div class="row mt16 o_settings_container">
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane">
<field name="show_digital_sign_inventory"/>
</div>
<div class="o_setting_right_pane">
<label for="show_digital_sign_inventory"
string="Show Digital Sign in Inventory?"/>
<div class="text-muted">
Show digital sign inside inventory
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box"
attrs="{'invisible': [
('show_digital_sign_inventory', '==', False)]}">
<div class="o_setting_left_pane">
<field name="enable_options_inventory"/>
</div>
<div class="o_setting_right_pane">
<label for="enable_options_inventory"
string="Enable Other Sign Options"/>
<div class="text-muted">
Enable Other Sign Option
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box"
id="show_sign_in_inventory"
attrs="{'invisible': [
('show_digital_sign_inventory', '==', False)]}">
<div class="o_setting_left_pane"/>
<div class="o_setting_right_pane">
<label for="sign_applicable"/>
<div class="text-muted">
Show digital sign inside delivery slip,
inventory options or both
</div>
<div class="content-group">
<div class="mt16">
<field name="sign_applicable"
class="o_light_label"
widget="radio"/>
</div>
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box"
attrs="{'invisible': [
('show_digital_sign_inventory', '==', False)]}">
<div class="o_setting_left_pane">
<field name="confirm_sign_inventory"/>
</div>
<div class="o_setting_right_pane">
<label for="confirm_sign_inventory"
string="Check Sign before confirmation"/>
<div class="text-muted">
Check Sign before confirmation
</div>
</div>
</div>
</div>
</xpath>
</field>
</record>
<record id="res_config_settings_view_form_invoice_inherit"
model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit.invoice</field>
<field name="model">res.config.settings</field>
<field name="priority" eval="10"/>
<field name="inherit_id" ref="account.res_config_settings_view_form"/>
<field name="arch" type="xml">
<xpath expr="//div[@data-key='account']/div[
@id='print_vendor_checks_setting_container']" position="after">
<h2>Digital Signature</h2>
<div class="row mt16 o_settings_container">
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane">
<field name="show_digital_sign_invoice"/>
</div>
<div class="o_setting_right_pane">
<label for="show_digital_sign_invoice"
string="Show Digital Sign in
Customer Invoice?"/>
<div class="text-muted">
Show digital sign inside customer invoice
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box"
attrs="{'invisible': [
('show_digital_sign_invoice', '==', False),
('show_digital_sign_bill', '==', False)]}">
<div class="o_setting_left_pane">
<field name="enable_options_invoice"/>
</div>
<div class="o_setting_right_pane">
<label for="enable_options_invoice"
string="Enable Other Sign Options"/>
<div class="text-muted">
Enable Other Sign Option
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box"
attrs="{'invisible': [
('show_digital_sign_invoice', '==', False),
('show_digital_sign_bill', '==', False)]}">
<div class="o_setting_left_pane">
<field name="confirm_sign_invoice"/>
</div>
<div class="o_setting_right_pane">
<label for="confirm_sign_invoice"
string="Check Sign before confirmation"/>
<div class="text-muted">
Check Sign before confirmation
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane">
<field name="show_digital_sign_bill"/>
</div>
<div class="o_setting_right_pane">
<label for="show_digital_sign_bill"
string="Show Digital Sign in Vendor Bill?"/>
<div class="text-muted">
Show digital sign inside vendor bill
</div>
</div>
</div>
</div>
</xpath>
</field>
</record>
</odoo>

61
digital_signature/views/stock_picking_report.xml

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<template id="stock_picking_report_inherit"
inherit_id="stock.report_picking">
<xpath expr="//table" position="after">
<div id="signature" class="row justify-content-end">
<t t-if="o.sign_applicable == 'picking_operations' or
o.sign_applicable == 'both'">
<div class="col-4">
<table class="table table-sm">
<div t-if="o.digital_sign" class="mt32 ml64 mr4"
name="signature">
<img t-att-src="image_data_uri(o.digital_sign)"
style="max-height: 4cm; max-width: 8cm;
padding-top: 50px;"/>
</div>
<tr>
<td class="text-right">
<p t-field="o.sign_by"/>
<p t-field="o.sign_on"/>
<p t-field="o.designation"/>
</td>
</tr>
</table>
</div>
</t>
</div>
</xpath>
</template>
<template id="stock_delivery_slip_inherit"
inherit_id="stock.report_delivery_document">
<xpath expr="//div[@name='signature']" position="before">
<div id="signature" class="row justify-content-end">
<t t-if="o.sign_applicable == 'delivery' or
o.sign_applicable == 'both'">
<div class="col-4">
<table class="table table-sm">
<div t-if="o.digital_sign" class="mt32 ml64 mr4"
name="signature">
<img t-att-src="image_data_uri(o.digital_sign)"
style="max-height: 4cm; max-width: 8cm;
padding-top: 50px;"/>
</div>
<tr>
<td class="text-right">
<p t-field="o.sign_by"/>
<p t-field="o.sign_on"/>
<p t-field="o.designation"/>
</td>
</tr>
</table>
</div>
</t>
</div>
</xpath>
</template>
</odoo>

2
invoice_format_editor/__manifest__.py

@ -22,7 +22,7 @@
{
'name': 'Invoice Format Editor',
'version': '14.0.2.1.',
'version': '14.0.2.2.',
'category': 'Accounting',
'summary': 'Invoice Format Editor',
'description': """Invoice Format Editor For Configuring the Invoice Templates""",

11
invoice_format_editor/doc/RELEASE_NOTES.md

@ -0,0 +1,11 @@
## Module <invoice_format_editor>
#### 20.11.2021
#### Version 14.0.2.1.
#### ADD
- Initial commit for invoice_format_editor
#### 10.06.2022
#### Version 14.0.2.2.
#### UPDT AND BUGFIX
- Invoice printing issue

8
invoice_format_editor/reports/custom_invoice_template.xml

@ -405,7 +405,8 @@
</div>
</t>
</template>
<template id="account.report_invoice_with_payments">
<template id="report_invoice_with_payments_inherit" inherit_id="account.report_invoice_with_payments">
<xpath expr="//t[@t-call='web.html_container']" position="replace">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="o">
<t t-set="lang"
@ -429,8 +430,10 @@
</t>
</t>
</t>
</xpath>
</template>
<template id="account.report_invoice">
<template id="report_invoice_inherit" inherit_id="account.report_invoice">
<xpath expr="//t[@t-call='web.html_container']" position="replace">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="o">
<t t-set="lang"
@ -454,6 +457,7 @@
</t>
</t>
</t>
</xpath>
</template>
</data>
</odoo>

113
invoice_format_editor/reports/default_invoice_template.xml

@ -5,10 +5,14 @@
<t t-call="web.external_layout">
<t t-set="o" t-value="o.with_context(lang=lang)"/>
<t t-set="address">
<address t-field="o.partner_id" t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": True}' />
<address t-field="o.partner_id"
t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": True}'/>
<div t-if="o.partner_id.vat" class="mt16">
<t t-if="o.company_id.country_id.vat_label" t-esc="o.company_id.country_id.vat_label" id="inv_tax_id_label"/>
<t t-else="">Tax ID</t>: <span t-field="o.partner_id.vat"/></div>
<t t-if="o.company_id.country_id.vat_label" t-esc="o.company_id.country_id.vat_label"
id="inv_tax_id_label"/>
<t t-else="">Tax ID</t>:
<span t-field="o.partner_id.vat"/>
</div>
</t>
<div class="page">
<h2>
@ -26,7 +30,9 @@
<strong>Invoice Date:</strong>
<p class="m-0" t-field="o.invoice_date"/>
</div>
<div class="col-auto col-3 mw-100 mb-2" t-if="o.invoice_date_due and o.move_type == 'out_invoice' and o.state == 'posted'" name="due_date">
<div class="col-auto col-3 mw-100 mb-2"
t-if="o.invoice_date_due and o.move_type == 'out_invoice' and o.state == 'posted'"
name="due_date">
<strong>Due Date:</strong>
<p class="m-0" t-field="o.invoice_date_due"/>
</div>
@ -49,13 +55,24 @@
<table class="table table-sm o_main_table" name="invoice_line_table">
<thead>
<tr>
<th name="th_description" class="text-left"><span>Description</span></th>
<th name="th_quantity" class="text-right"><span>Quantity</span></th>
<th name="th_priceunit" t-attf-class="text-right {{ 'd-none d-md-table-cell' if report_type == 'html' else '' }}"><span>Unit Price</span></th>
<th name="th_price_unit" t-if="display_discount" t-attf-class="text-right {{ 'd-none d-md-table-cell' if report_type == 'html' else '' }}">
<th name="th_description" class="text-left">
<span>Description</span>
</th>
<th name="th_quantity" class="text-right">
<span>Quantity</span>
</th>
<th name="th_priceunit"
t-attf-class="text-right {{ 'd-none d-md-table-cell' if report_type == 'html' else '' }}">
<span>Unit Price</span>
</th>
<th name="th_price_unit" t-if="display_discount"
t-attf-class="text-right {{ 'd-none d-md-table-cell' if report_type == 'html' else '' }}">
<span>Disc.%</span>
</th>
<th name="th_taxes" t-attf-class="text-left {{ 'd-none d-md-table-cell' if report_type == 'html' else '' }}"><span>Taxes</span></th>
<th name="th_taxes"
t-attf-class="text-left {{ 'd-none d-md-table-cell' if report_type == 'html' else '' }}">
<span>Taxes</span>
</th>
<th name="th_subtotal" class="text-right">
<span groups="account.group_show_line_subtotals_tax_excluded">Amount</span>
<span groups="account.group_show_line_subtotals_tax_included">Total Price</span>
@ -64,15 +81,20 @@
</thead>
<tbody class="invoice_tbody">
<t t-set="current_subtotal" t-value="0"/>
<t t-set="lines" t-value="o.invoice_line_ids.sorted(key=lambda l: (-l.sequence, l.date, l.move_name, -l.id), reverse=True)"/>
<t t-set="lines"
t-value="o.invoice_line_ids.sorted(key=lambda l: (-l.sequence, l.date, l.move_name, -l.id), reverse=True)"/>
<t t-foreach="lines" t-as="line">
<t t-set="current_subtotal" t-value="current_subtotal + line.price_subtotal" groups="account.group_show_line_subtotals_tax_excluded"/>
<t t-set="current_subtotal" t-value="current_subtotal + line.price_total" groups="account.group_show_line_subtotals_tax_included"/>
<t t-set="current_subtotal" t-value="current_subtotal + line.price_subtotal"
groups="account.group_show_line_subtotals_tax_excluded"/>
<t t-set="current_subtotal" t-value="current_subtotal + line.price_total"
groups="account.group_show_line_subtotals_tax_included"/>
<tr t-att-class="'bg-200 font-weight-bold o_line_section' if line.display_type == 'line_section' else 'font-italic o_line_note' if line.display_type == 'line_note' else ''">
<t t-if="not line.display_type" name="account_invoice_line_accountable">
<td name="account_invoice_line_name"><span t-field="line.name" t-options="{'widget': 'text'}"/></td>
<td name="account_invoice_line_name">
<span t-field="line.name" t-options="{'widget': 'text'}"/>
</td>
<td class="text-right">
<span t-field="line.quantity"/>
<span t-field="line.product_uom_id" groups="uom.group_uom"/>
@ -80,15 +102,19 @@
<td t-attf-class="text-right {{ 'd-none d-md-table-cell' if report_type == 'html' else '' }}">
<span class="text-nowrap" t-field="line.price_unit"/>
</td>
<td t-if="display_discount" t-attf-class="text-right {{ 'd-none d-md-table-cell' if report_type == 'html' else '' }}">
<td t-if="display_discount"
t-attf-class="text-right {{ 'd-none d-md-table-cell' if report_type == 'html' else '' }}">
<span class="text-nowrap" t-field="line.discount"/>
</td>
<td t-attf-class="text-left {{ 'd-none d-md-table-cell' if report_type == 'html' else '' }}">
<span t-esc="', '.join(map(lambda x: (x.description or x.name), line.tax_ids))" id="line_tax_ids"/>
<span t-esc="', '.join(map(lambda x: (x.description or x.name), line.tax_ids))"
id="line_tax_ids"/>
</td>
<td class="text-right o_price_total">
<span class="text-nowrap" t-field="line.price_subtotal" groups="account.group_show_line_subtotals_tax_excluded"/>
<span class="text-nowrap" t-field="line.price_total" groups="account.group_show_line_subtotals_tax_included"/>
<span class="text-nowrap" t-field="line.price_subtotal"
groups="account.group_show_line_subtotals_tax_excluded"/>
<span class="text-nowrap" t-field="line.price_total"
groups="account.group_show_line_subtotals_tax_included"/>
</td>
</t>
<t t-if="line.display_type == 'line_section'">
@ -125,7 +151,9 @@
<div t-attf-class="#{'col-6' if report_type != 'html' else 'col-sm-7 col-md-6'} ml-auto">
<table class="table table-sm" style="page-break-inside: avoid;">
<tr class="border-black o_subtotal" style="">
<td><strong>Subtotal</strong></td>
<td>
<strong>Subtotal</strong>
</td>
<td class="text-right">
<span t-field="o.amount_untaxed"/>
</td>
@ -133,7 +161,9 @@
<t t-foreach="o.amount_by_group" t-as="amount_by_group">
<tr style="">
<t t-if="len(o.line_ids.filtered(lambda line: line.tax_line_id)) in [0, 1] and o.amount_untaxed == amount_by_group[2]">
<td><span class="text-nowrap" t-esc="amount_by_group[0]"/></td>
<td>
<span class="text-nowrap" t-esc="amount_by_group[0]"/>
</td>
<td class="text-right o_price_total">
<span class="text-nowrap" t-esc="amount_by_group[3]"/>
</td>
@ -152,27 +182,36 @@
</tr>
</t>
<tr class="border-black o_total">
<td><strong>Total</strong></td>
<td>
<strong>Total</strong>
</td>
<td class="text-right">
<span class="text-nowrap" t-field="o.amount_total"/>
</td>
</tr>
<t t-if="print_with_payments">
<t t-if="o.payment_state != 'invoicing_legacy'">
<t t-set="payments_vals" t-value="o.sudo()._get_reconciled_info_JSON_values()"/>
<t t-set="payments_vals"
t-value="o.sudo()._get_reconciled_info_JSON_values()"/>
<t t-foreach="payments_vals" t-as="payment_vals">
<tr>
<td>
<i class="oe_form_field text-right oe_payment_label">Paid on <t t-esc="payment_vals['date']" t-options='{"widget": "date"}'/></i>
<i class="oe_form_field text-right oe_payment_label">Paid on
<t t-esc="payment_vals['date']"
t-options='{"widget": "date"}'/>
</i>
</td>
<td class="text-right">
<span t-esc="payment_vals['amount']" t-options='{"widget": "monetary", "display_currency": o.currency_id}'/>
<span t-esc="payment_vals['amount']"
t-options='{"widget": "monetary", "display_currency": o.currency_id}'/>
</td>
</tr>
</t>
<t t-if="len(payments_vals) > 0">
<tr class="border-black">
<td><strong>Amount Due</strong></td>
<td>
<strong>Amount Due</strong>
</td>
<td class="text-right">
<span t-field="o.amount_residual"/>
</td>
@ -184,8 +223,12 @@
</div>
</div>
</div>
<p t-if="o.move_type in ('out_invoice', 'in_refund') and o.payment_reference" name="payment_communication">
Please use the following communication for your payment : <b><span t-field="o.payment_reference"/></b>
<p t-if="o.move_type in ('out_invoice', 'in_refund') and o.payment_reference"
name="payment_communication">
Please use the following communication for your payment :
<b>
<span t-field="o.payment_reference"/>
</b>
</p>
<p t-if="o.invoice_payment_term_id" name="payment_term">
<span t-field="o.invoice_payment_term_id.note"/>
@ -197,11 +240,16 @@
<span t-field="o.fiscal_position_id.note"/>
</p>
<p t-if="o.invoice_incoterm_id" name="incoterm">
<strong>Incoterm: </strong><span t-field="o.invoice_incoterm_id.code"/> - <span t-field="o.invoice_incoterm_id.name"/>
<strong>Incoterm:</strong>
<span t-field="o.invoice_incoterm_id.code"/>
-
<span t-field="o.invoice_incoterm_id.name"/>
</p>
<div id="qrcode" t-if="o.display_qr_code">
<p t-if="qr_code_urls.get(o.id)">
<strong class="text-center">Scan me with your banking app.</strong><br/><br/>
<strong class="text-center">Scan me with your banking app.</strong>
<br/>
<br/>
<img class="border border-dark rounded" t-att-src="qr_code_urls[o.id]"/>
</p>
</div>
@ -212,7 +260,8 @@
<template id="report_invoice">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="o">
<t t-set="lang" t-value="o.invoice_user_id.sudo().lang if o.move_type in ('in_invoice', 'in_refund') else o.partner_id.lang"/>
<t t-set="lang"
t-value="o.invoice_user_id.sudo().lang if o.move_type in ('in_invoice', 'in_refund') else o.partner_id.lang"/>
<t t-if="o._get_name_invoice_report() == 'account.report_invoice_document'"
t-call="account.report_invoice_document" t-lang="lang"/>
</t>
@ -222,7 +271,8 @@
<template id="report_invoice_with_payments">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="o">
<t t-set="lang" t-value="o.invoice_user_id.sudo().lang if o.move_type in ('in_invoice', 'in_refund') else o.partner_id.lang"/>
<t t-set="lang"
t-value="o.invoice_user_id.sudo().lang if o.move_type in ('in_invoice', 'in_refund') else o.partner_id.lang"/>
<t t-set="print_with_payments" t-value="True"/>
<t t-if="o._get_name_invoice_report() == 'account.report_invoice_document'"
t-call="account.report_invoice_document" t-lang="lang"/>
@ -236,7 +286,8 @@
<template id="report_original_vendor_bill">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="o">
<div class="article" t-att-data-oe-model="o and o._name" t-att-data-oe-id="o and o.id" t-att-data-oe-lang="o and o.env.context.get('lang')"></div>
<div class="article" t-att-data-oe-model="o and o._name" t-att-data-oe-id="o and o.id"
t-att-data-oe-lang="o and o.env.context.get('lang')"></div>
</t>
</t>
</template>

42
pos_report_generator/README.rst

@ -0,0 +1,42 @@
POS All In One Report Generator
===============================
* POS All In One Dynamic Report For Odoo 14 Community And Enterprise editions
Installation
============
- www.odoo.com/documentation/14.0/setup/install.html
- Install our custom addon
License
-------
General Public License, Version 3 (LGPL v3).
(https://www.odoo.com/documentation/user/14.0/legal/licenses/licenses.html)
Company
-------
* 'Cybrosys Techno Solutions <https://cybrosys.com/>`__
Credits
-------
* Developer:
(v14) Sreelakshmi @ Cybrosys
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
==========
This module is maintained by Cybrosys Technologies.
For support and more information, please visit https://www.cybrosys.com
Further information
===================
HTML Description: `<static/description/index.html>`__

24
pos_report_generator/__init__.py

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from . import models
from . import report
from . import controllers

50
pos_report_generator/__manifest__.py

@ -0,0 +1,50 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
{
'name': 'POS All in One Report Generator',
'version': '14.0.1.0.0',
'summary': "POS All In One Dynamic Report For Odoo 14 Community And Enterprise editions",
'description': "POS All In One Dynamic Report For Odoo 14 Community And Enterprise editions",
'category': 'Point of Sale',
'author': 'Cybrosys Techno Solutions',
'maintainer': 'Cybrosys Techno Solutions',
'company': 'Cybrosys Techno Solutions',
'website': 'https://www.cybrosys.com',
'depends': [
'point_of_sale',
'stock',
],
'data': [
'security/ir.model.access.csv',
'report/pos_order_report.xml',
'views/pos_report.xml',
'views/templates.xml',
],
'qweb': [
'static/src/xml/pos_report_view.xml',
],
'images': ['static/description/banner.png'],
'license': 'AGPL-3',
'installable': True,
'auto_install': False,
'auto_install': False,
}

22
pos_report_generator/controllers/__init__.py

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from . import controllers

56
pos_report_generator/controllers/controllers.py

@ -0,0 +1,56 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
import json
from odoo import http
from odoo.http import content_disposition, request
from odoo.addons.web.controllers.main import _serialize_exception
from odoo.tools import html_escape
class TBXLSXReportController(http.Controller):
@http.route('/pos_dynamic_xlsx_reports', type='http', auth='user', methods=['POST'], csrf=False)
def get_report_xlsx(self, model, options, output_format, token, report_data, report_name, dfr_data, **kw):
uid = request.session.uid
report_obj = request.env[model].with_user(uid)
dfr_data = dfr_data
options = options
try:
if output_format == 'xlsx':
response = request.make_response(
None,
headers=[
('Content-Type', 'application/vnd.ms-excel'),
('Content-Disposition', content_disposition(report_name + '.xlsx'))
]
)
report_obj.get_pos_xlsx_report(options, response, report_data, dfr_data)
response.set_cookie('fileToken', token)
return response
except Exception as e:
se = _serialize_exception(e)
error = {
'code': 200,
'message': 'Odoo Server Error',
'data': se
}
return request.make_response(html_escape(json.dumps(error)))

6
pos_report_generator/doc/RELEASE_NOTES.md

@ -0,0 +1,6 @@
## Module <pos_report_generator>
#### 15.12.2022
#### Version 15.0.1.0.0
##### ADD
- Initial commit for pos_report_generator

22
pos_report_generator/models/__init__.py

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from . import pos_report

567
pos_report_generator/models/pos_report.py

@ -0,0 +1,567 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import models, fields, api
import io
import json
try:
from odoo.tools.misc import xlsxwriter
except ImportError:
import xlsxwriter
class PosReportGenerator(models.Model):
_name = "pos.report"
pos_report = fields.Char(string="PoS Report")
date_from = fields.Datetime(string="Date From")
date_to = fields.Datetime(string="Date to")
report_type = fields.Selection([('report_by_order', 'Report By Order'),
('report_by_order_detail', 'Report By Order Detail'),
('report_by_product', 'Report By Product'),
('report_by_categories', 'Report By Categories'),
('report_by_salesman', 'Report By Salesman'),
('report_by_payment', 'Report By Payment')],
default='report_by_order')
@api.model
def pos_report(self, option):
orders = self.env['pos.order'].search([])
report_values = self.env['pos.report'].search([('id', '=', option[0])])
data = {
'report_type': report_values.report_type,
'model': self,
}
if report_values.date_from:
data.update({
'date_from': report_values.date_from,
})
if report_values.date_to:
data.update({
'date_to': report_values.date_to,
})
# print("reports",reports)
filters = self.get_filter(option)
report = self._get_report_values(data)
lines = self._get_report_values(data).get('POS')
main_line = self._get_report_values(data).get('pos_main')
return {
'name': "PoS Orders",
'type': 'ir.actions.client',
'tag': 'p_r',
'orders': data,
'filters': filters,
'report_lines': lines,
'report_main_line': main_line,
}
def get_filter(self, option):
data = self.get_filter_data(option)
filters = {}
if data.get('report_type') == 'report_by_order':
filters['report_type'] = 'Report By Order'
elif data.get('report_type') == 'report_by_order_detail':
filters['report_type'] = 'Report By Order Detail'
elif data.get('report_type') == 'report_by_product':
filters['report_type'] = 'Report By Product'
elif data.get('report_type') == 'report_by_categories':
filters['report_type'] = 'Report By Categories'
elif data.get('report_type') == 'report_by_salesman':
filters['report_type'] = 'Report By Salesman'
elif data.get('report_type') == 'report_by_payment':
filters['report_type'] = 'Report By Payment'
else:
filters['report_type'] = 'report_by_order'
return filters
def get_filter_data(self, option):
r = self.env['pos.report'].search([('id', '=', option[0])])
default_filters = {}
filter_dict = {
'report_type': r.report_type,
}
filter_dict.update(default_filters)
return filter_dict
@api.model
def create(self, vals):
print("vals", vals)
res = super(PosReportGenerator, self).create(vals)
return res
def write(self, vals):
res = super(PosReportGenerator, self).write(vals)
return res
def _get_report_sub_lines(self, data, report, date_from, date_to):
report_sub_lines = []
new_filter = None
if data.get('report_type') == 'report_by_order':
query = '''
select l.name,l.date_order,l.partner_id,l.amount_total,l.note,l.user_id,res_partner.name,l.name as shop,pos_session.name as session,
res_users.partner_id as user_partner,sum(pos_order_line.qty),l.id as id,
(SELECT res_partner.name as salesman FROM res_partner WHERE res_partner.id = res_users.partner_id)
from pos_order as l
left join pos_session on l.session_id = pos_session.id
left join res_partner on l.partner_id = res_partner.id
left join res_users on l.user_id = res_users.id
left join pos_order_line on l.id = pos_order_line.order_id
'''
term = 'Where '
if data.get('date_from'):
query += "Where l.date_order >= '%s' " % data.get('date_from')
term = 'AND '
if data.get('date_to'):
query += term + "l.date_order <= '%s' " % data.get('date_to')
query += "group by l.user_id,res_users.partner_id,res_partner.name,l.partner_id,l.date_order,pos_session.name,l.session_id,l.name,l.amount_total,l.note,l.id"
self._cr.execute(query)
report_by_order = self._cr.dictfetchall()
report_sub_lines.append(report_by_order)
elif data.get('report_type') == 'report_by_order_detail':
query = '''
select l.name,l.date_order,l.partner_id,l.amount_total,l.note,l.user_id,res_partner.name,l.name as shop,pos_session.name as session,
res_users.partner_id as user_partner,sum(pos_order_line.qty), pos_order_line.full_product_name, pos_order_line.price_unit,pos_order_line.price_subtotal,pos_order_line.price_subtotal_incl,pos_order_line.product_id,product_product.default_code,
(SELECT res_partner.name as salesman FROM res_partner WHERE res_partner.id = res_users.partner_id)
from pos_order as l
left join pos_session on l.session_id = pos_session.id
left join res_partner on l.partner_id = res_partner.id
left join res_users on l.user_id = res_users.id
left join pos_order_line on l.id = pos_order_line.order_id
left join product_product on pos_order_line.product_id = product_product.id
'''
term = 'Where '
if data.get('date_from'):
query += "Where l.date_order >= '%s' " % data.get('date_from')
term = 'AND '
if data.get('date_to'):
query += term + "l.date_order <= '%s' " % data.get('date_to')
query += "group by l.user_id,res_users.partner_id,res_partner.name,l.partner_id,l.date_order,pos_session.name,l.session_id,l.name,l.amount_total,l.note,pos_order_line.full_product_name,pos_order_line.price_unit,pos_order_line.price_subtotal,pos_order_line.price_subtotal_incl,pos_order_line.product_id,product_product.default_code"
self._cr.execute(query)
report_by_order_details = self._cr.dictfetchall()
report_sub_lines.append(report_by_order_details)
elif data.get('report_type') == 'report_by_product':
query ='''
select l.amount_total,l.amount_paid,sum(pos_order_line.qty) as qty, pos_order_line.full_product_name, pos_order_line.price_unit,product_product.default_code,product_category.name
from pos_order as l
left join pos_order_line on l.id = pos_order_line.order_id
left join product_product on pos_order_line.product_id = product_product.id
left join product_template on pos_order_line.product_id = product_template.id
left join product_category on product_category.id = product_template.categ_id
'''
term = 'Where '
if data.get('date_from'):
query += "Where l.date_order >= '%s' " % data.get('date_from')
term = 'AND '
if data.get('date_to'):
query += term + "l.date_order <= '%s' " % data.get('date_to')
query += "group by l.amount_total,l.amount_paid,pos_order_line.full_product_name,pos_order_line.price_unit,pos_order_line.product_id,product_product.default_code,product_template.categ_id,product_category.name"
self._cr.execute(query)
report_by_product = self._cr.dictfetchall()
report_sub_lines.append(report_by_product)
elif data.get('report_type') == 'report_by_categories':
query ='''
select product_category.name,sum(l.qty) as qty,sum(l.price_subtotal) as amount_total,sum(price_subtotal_incl) as total_incl
from pos_order_line as l
left join product_template on l.product_id = product_template.id
left join product_category on product_category.id = product_template.categ_id
left join pos_order on l.order_id = pos_order.id
'''
term = 'Where '
if data.get('date_from'):
query += "Where pos_order.date_order >= '%s' " % data.get('date_from')
term = 'AND '
if data.get('date_to'):
query += term + "pos_order.date_order <= '%s' " % data.get('date_to')
query += "group by product_category.name"
self._cr.execute(query)
report_by_categories = self._cr.dictfetchall()
report_sub_lines.append(report_by_categories)
elif data.get('report_type') == 'report_by_salesman':
query ='''
select res_partner.name,sum(pos_order_line.qty) as qty,sum(pos_order_line.price_subtotal) as amount,count(l.id) as order
from pos_order as l
left join res_users on l.user_id = res_users.id
left join res_partner on res_users.partner_id = res_partner.id
left join pos_order_line on l.id = pos_order_line.order_id
'''
term = 'Where '
if data.get('date_from'):
query += "Where l.date_order >= '%s' " % data.get('date_from')
term = 'AND '
if data.get('date_to'):
query += term + "l.date_order <= '%s' " % data.get('date_to')
query += "group by res_partner.name"
self._cr.execute(query)
report_by_salesman = self._cr.dictfetchall()
report_sub_lines.append(report_by_salesman)
elif data.get('report_type') == 'report_by_payment':
query ='''
select pos_payment_method.name,sum(l.amount_total),pos_session.name as session,pos_config.name as config
from pos_order as l
left join pos_payment on l.id = pos_payment.pos_order_id
left join pos_payment_method on pos_payment.payment_method_id = pos_payment_method.id
left join pos_session on l.session_id = pos_session.id
left join pos_config on pos_session.config_id = pos_config.id
'''
term = 'Where '
if data.get('date_from'):
query += "Where l.date_order >= '%s' " % data.get('date_from')
term = 'AND '
if data.get('date_to'):
query += term + "l.date_order <= '%s' " % data.get('date_to')
query += "group by pos_payment_method.name,pos_session.name,pos_config.name"
self._cr.execute(query)
report_by_payment = self._cr.dictfetchall()
report_sub_lines.append(report_by_payment)
return report_sub_lines
def _get_report_total_value(self, data, report):
report_main_lines = []
if data.get('report_type') == 'report_by_order':
self._cr.execute('''
select count(l.id) as order,sum(l.amount_total) as amount
from pos_order as l
''')
report_by_order = self._cr.dictfetchall()
report_main_lines.append(report_by_order)
elif data.get('report_type') == 'report_by_order_detail':
self._cr.execute('''
select count(line.id) as order,sum(line.price_subtotal) as total,sum(line.price_subtotal_incl)
from pos_order_line as line
''')
report_by_order_detail = self._cr.dictfetchall()
report_main_lines.append(report_by_order_detail)
elif data.get('report_type') == 'report_by_product':
self._cr.execute('''
select count(l.product_id) as order,sum(l.price_subtotal) as amount
from pos_order_line as l
''')
report_by_product = self._cr.dictfetchall()
report_main_lines.append(report_by_product)
else:
report_main_lines = False
return report_main_lines
def _get_report_values(self, data):
docs = data['model']
date_from = data.get('date_from')
date_to = data.get('date_to')
if data['report_type'] == 'report_by_order_detail':
report = ['Report By Order Detail']
elif data['report_type'] == 'report_by_product':
report = ['Report By Product']
elif data['report_type'] == 'report_by_categories':
report = ['Report By Categories']
elif data['report_type'] == 'report_by_salesman':
report = ['Report By Salesman']
elif data['report_type'] == 'report_by_payment':
report = ['Report By Payment']
else:
report = ['Report By Order']
report_res_total = self._get_report_total_value(data, report)
if data.get('report_type'):
report_res = self._get_report_sub_lines(data, report, date_from, date_to)[0]
else:
report_res = self._get_report_sub_lines(data, report, date_from, date_to)
if data.get('report_type') == 'report_by_order':
report_res_total = self._get_report_total_value(data, report)[0]
return {
'doc_ids': self.ids,
'docs': docs,
'POS': report_res,
'pos_main': report_res_total,
}
def get_pos_xlsx_report(self, data, response, report_data, dfr_data):
report_data_main = json.loads(report_data)
output = io.BytesIO()
filters = json.loads(data)
workbook = xlsxwriter.Workbook(output, {'in_memory': True})
sheet = workbook.add_worksheet()
head = workbook.add_format({'align': 'center', 'bold': True,
'font_size': '20px'})
sub_heading = workbook.add_format(
{'align': 'center', 'bold': True, 'font_size': '10px',
'border': 1,
'border_color': 'black'})
heading = workbook.add_format(
{'align': 'center', 'bold': True, 'font_size': '10px',
'border': 2,
'border_color': 'black'})
txt = workbook.add_format({'font_size': '10px', 'border': 1})
txt_l = workbook.add_format(
{'font_size': '10px', 'border': 1, 'bold': True})
txt_v = workbook.add_format(
{'align': 'right', 'font_size': '10px', 'border': 1})
sheet.merge_range('A2:H3',
'Point of Sale Report',
head)
date_head = workbook.add_format({'align': 'center', 'bold': True,
'font_size': '10px'})
date_style = workbook.add_format({'align': 'center',
'font_size': '10px'})
if filters.get('report_type') == 'report_by_order':
sheet.merge_range('B5:D5', 'Report Type: ' +
filters.get('report_type'), txt_l)
sheet.write('A7', 'PoS', heading)
sheet.write('B7', 'Order', heading)
sheet.write('C7', 'Date Order', heading)
sheet.write('D7', 'Customer', heading)
sheet.write('E7', 'Salesman', heading)
sheet.write('F7', 'Total Qty', heading)
sheet.write('G7', 'Amount Total', heading)
sheet.write('H7', 'Note', heading)
lst = []
for rec in report_data_main[0]:
lst.append(rec)
row = 6
col = 0
sheet.set_column(3, 0, 15)
sheet.set_column(4, 1, 15)
sheet.set_column(5, 2, 15)
sheet.set_column(6, 3, 15)
sheet.set_column(7, 4, 15)
sheet.set_column(8, 5, 15)
sheet.set_column(9, 6, 15)
for rec_data in report_data_main:
one_lst = []
two_lst = []
print("iiii", rec_data)
row += 1
sheet.write(row, col, rec_data['shop'], txt_l)
sheet.write(row, col + 1, rec_data['session'], txt_l)
sheet.write(row, col + 2, rec_data['date_order'], txt_l)
sheet.write(row, col + 3, rec_data['name'], txt_l)
sheet.write(row, col + 4, rec_data['salesman'], txt_l)
sheet.write(row, col + 5, rec_data['sum'], txt_l)
sheet.write(row, col + 6, rec_data['amount_total'], txt_l)
sheet.write(row, col + 7, rec_data['note'], txt_l)
if filters.get('report_type') == 'report_by_order_detail':
sheet.merge_range('B5:D5', 'Report Type: ' +
filters.get('report_type'), txt_l)
sheet.write('A7', 'PoS', heading)
sheet.write('B7', 'Order', heading)
sheet.write('C7', 'Date Order', heading)
sheet.write('D7', 'Customer', heading)
sheet.write('E7', 'Salesman', heading)
sheet.write('F7', 'Product Code', heading)
sheet.write('G7', 'Product Name', heading)
sheet.write('H7', 'Price unit', heading)
sheet.write('I7', 'Qty', heading)
sheet.write('J7', 'Price Subtotal', heading)
sheet.write('K7', 'Price Subtotal Incl', heading)
lst = []
for rec in report_data_main[0]:
lst.append(rec)
row = 6
col = 0
sheet.set_column(3, 0, 15)
sheet.set_column(4, 1, 15)
sheet.set_column(5, 2, 15)
sheet.set_column(6, 3, 15)
sheet.set_column(7, 4, 15)
sheet.set_column(8, 5, 15)
sheet.set_column(9, 6, 15)
sheet.set_column(10, 7, 15)
sheet.set_column(11, 8, 15)
sheet.set_column(12, 9, 15)
for rec_data in report_data_main:
one_lst = []
two_lst = []
print("iiii", rec_data)
row += 1
sheet.write(row, col, rec_data['shop'], txt_l)
sheet.write(row, col + 1, rec_data['session'], txt_l)
sheet.write(row, col + 2, rec_data['date_order'], txt_l)
sheet.write(row, col + 3, rec_data['name'], txt_l)
sheet.write(row, col + 4, rec_data['salesman'], txt_l)
sheet.write(row, col + 5, rec_data['default_code'], txt_l)
sheet.write(row, col + 6, rec_data['full_product_name'], txt_l)
sheet.write(row, col + 7, rec_data['price_unit'], txt_l)
sheet.write(row, col + 8, rec_data['sum'], txt_l)
sheet.write(row, col + 9, rec_data['price_subtotal'], txt_l)
sheet.write(row, col + 10, rec_data['price_subtotal_incl'], txt_l)
if filters.get('report_type') == 'report_by_product':
sheet.merge_range('B5:D5', 'Report Type: ' +
filters.get('report_type'), txt_l)
sheet.write('A7', 'Category', heading)
sheet.write('B7', 'Product Code', heading)
sheet.write('C7', 'Product Name', heading)
sheet.write('D7', 'Qty', heading)
sheet.write('E7', 'Amount Total', heading)
sheet.write('F7', 'Amount Total Incl', heading)
lst = []
for rec in report_data_main[0]:
lst.append(rec)
row = 6
col = 0
sheet.set_column(3, 0, 15)
sheet.set_column(4, 1, 15)
sheet.set_column(5, 2, 15)
sheet.set_column(6, 3, 15)
sheet.set_column(7, 4, 15)
sheet.set_column(8, 5, 15)
# sheet.set_column(9, 6, 15)
# sheet.set_column(10, 7, 15)
# sheet.set_column(11, 8, 15)
# sheet.set_column(12, 9, 15)
for rec_data in report_data_main:
one_lst = []
two_lst = []
print("iiii", rec_data)
row += 1
sheet.write(row, col, rec_data['name'], txt_l)
sheet.write(row, col + 1, rec_data['default_code'], txt_l)
sheet.write(row, col + 2, rec_data['full_product_name'], txt_l)
sheet.write(row, col + 3, rec_data['qty'], txt_l)
sheet.write(row, col + 4, rec_data['amount_total'], txt_l)
sheet.write(row, col + 5, rec_data['amount_paid'], txt_l)
if filters.get('report_type') == 'report_by_categories':
sheet.merge_range('B5:D5', 'Report Type: ' +
filters.get('report_type'), txt_l)
sheet.write('A7', 'Category', heading)
sheet.write('B7', 'Qty', heading)
sheet.write('C7', 'Amount Total', heading)
sheet.write('D7', 'Amount Total Incl', heading)
lst = []
for rec in report_data_main[0]:
lst.append(rec)
row = 6
col = 0
sheet.set_column(3, 0, 15)
sheet.set_column(4, 1, 15)
sheet.set_column(5, 2, 15)
sheet.set_column(6, 3, 15)
for rec_data in report_data_main:
one_lst = []
two_lst = []
print("iiii", rec_data)
row += 1
sheet.write(row, col, rec_data['name'], txt_l)
sheet.write(row, col + 1, rec_data['qty'], txt_l)
sheet.write(row, col + 2, rec_data['amount_total'], txt_l)
sheet.write(row, col + 3, rec_data['total_incl'], txt_l)
if filters.get('report_type') == 'report_by_salesman':
sheet.merge_range('B5:D5', 'Report Type: ' +
filters.get('report_type'), txt_l)
sheet.write('A7', 'Salesman', heading)
sheet.write('B7', 'Total Order', heading)
sheet.write('C7', 'Total Qty', heading)
sheet.write('D7', 'Total Amount', heading)
lst = []
for rec in report_data_main[0]:
lst.append(rec)
row = 6
col = 0
sheet.set_column(3, 0, 15)
sheet.set_column(4, 1, 15)
sheet.set_column(5, 2, 15)
sheet.set_column(6, 3, 15)
for rec_data in report_data_main:
one_lst = []
two_lst = []
print("iiii", rec_data)
row += 1
sheet.write(row, col, rec_data['name'], txt_l)
sheet.write(row, col + 1, rec_data['order'], txt_l)
sheet.write(row, col + 2, rec_data['qty'], txt_l)
sheet.write(row, col + 3, rec_data['amount'], txt_l)
if filters.get('report_type') == 'report_by_payment':
sheet.merge_range('B5:D5', 'Report Type: ' +
filters.get('report_type'), txt_l)
sheet.write('A7', 'Point of Sale', heading)
sheet.write('B7', 'PoS Session', heading)
sheet.write('C7', 'Payment', heading)
sheet.write('D7', 'Total Amount', heading)
lst = []
for rec in report_data_main[0]:
lst.append(rec)
row = 6
col = 0
sheet.set_column(3, 0, 15)
sheet.set_column(4, 1, 15)
sheet.set_column(5, 2, 15)
sheet.set_column(6, 3, 15)
for rec_data in report_data_main:
one_lst = []
two_lst = []
print("iiii", rec_data)
row += 1
sheet.write(row, col, rec_data['config'], txt_l)
sheet.write(row, col + 1, rec_data['session'], txt_l)
sheet.write(row, col + 2, rec_data['name'], txt_l)
sheet.write(row, col + 3, rec_data['sum'], txt_l)
workbook.close()
output.seek(0)
response.stream.write(output.read())
output.close()

22
pos_report_generator/report/__init__.py

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from . import pos_order_report

37
pos_report_generator/report/pos_order_report.py

@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import api, models, _
class PosOrder(models.AbstractModel):
_name = 'report.pos_report_generator.pos_order_report'
@api.model
def _get_report_values(self, docids, data=None):
if self.env.context.get('pos_order_report'):
if data.get('report_data'):
data.update({'report_main_line_data': data.get('report_data')['report_lines'],
'Filters': data.get('report_data')['filters'],
'company': self.env.company,
})
return data

478
pos_report_generator/report/pos_order_report.xml

@ -0,0 +1,478 @@
<odoo>
<template id="pos_order_report">
<t t-call="web.html_container">
<t t-call="web.internal_layout">
<t t-if="Filters.get('report_type')=='Report By Order'">
<t t-call="pos_report_generator.report_order"/>
</t>
<t t-if="Filters.get('report_type')=='Report By Order Detail'">
<t t-call="pos_report_generator.report_order_detail"/>
</t>
<t t-if="Filters.get('report_type')=='Report By Product'">
<t t-call="pos_report_generator.report_product"/>
</t>
<t t-if="Filters.get('report_type')=='Report By Categories'">
<t t-call="pos_report_generator.report_category"/>
</t>
<t t-if="Filters.get('report_type')=='Report By Salesman'">
<t t-call="pos_report_generator.report_salesman"/>
</t>
<t t-if="Filters.get('report_type')=='Report By Payment'">
<t t-call="pos_report_generator.report_payment"/>
</t>
</t>
</t>
</template>
<template id="report_order">
<div class="page">
<div class="oe_structure"/>
<span t-if="Filters.get('date_from')">
<strong>From:</strong>
<t t-esc="Filters['date_from']"/>
</span>
<span t-if="Filters.get('date_to')">
<strong>To:</strong>
<t t-esc="Filters['date_to']"/>
</span>
<div>
<div style="width:100%;">
<div style="text-align:centre;" class="row">
<div class="col-2">
<strong>Report Type:</strong>
<t t-esc="Filters.get('report_type')"/>
</div>
</div>
</div>
<br></br>
<table class="table table-sm table-reports">
<thead>
<tr class="text-right">
<th>PoS</th>
<th colspan="6">Order</th>
<th colspan="6">Date Order</th>
<th colspan="6">Customer</th>
<th colspan="6">Salesman</th>
<th colspan="6">Total Qty</th>
<th colspan="6">Amount Total</th>
<th colspan="6">Note</th>
</tr>
</thead>
<tbody>
<t t-foreach="report_main_line_data" t-as="main">
<tr style="font-weight: bold;">
<td colspan="6">
<span t-esc="main['shop']"/>
</td>
<td colspan="6">
<span t-esc="main['session']"/>
</td>
<td colspan="6">
<span t-esc="main['date_order']"/>
</td>
<td colspan="6">
<span t-esc="main['name']"/>
</td>
<td colspan="6">
<span t-esc="main['salesman']"/>
</td>
<td colspan="6">
<span t-esc="main['sum']"/>
</td>
<td colspan="6">
<span t-esc="main['amount_total']"/>
</td>
<td colspan="6">
<span t-esc="main['note']"/>
</td>
</tr>
</t>
</tbody>
</table>
</div>
<br></br>
</div>
</template>
<template id="report_order_detail">
<div class="page">
<div class="oe_structure"/>
<span t-if="Filters.get('date_from')">
<strong>From:</strong>
<t t-esc="Filters['date_from']"/>
</span>
<span t-if="Filters.get('date_to')">
<strong>To:</strong>
<t t-esc="Filters['date_to']"/>
</span>
<div>
<div style="width:100%;">
<div style="text-align:centre;" class="row">
<div class="col-2">
<strong>Report Type:</strong>
<t t-esc="Filters.get('report_type')"/>
</div>
</div>
</div>
<br></br>
<table class="table table-sm table-reports">
<thead>
<tr class="text-right">
<th>PoS</th>
<th colspan="6">Order</th>
<th colspan="6">Date Order</th>
<th colspan="6">Customer</th>
<th colspan="6">Salesman</th>
<th colspan="6">Product Code</th>
<th colspan="6">Product Name</th>
<th colspan="6">Price unit</th>
<th colspan="6">Qty</th>
<th colspan="6">Price Subtotal</th>
<th colspan="6">Price Subtotal Incl</th>
</tr>
</thead>
<tbody>
<t t-foreach="report_main_line_data" t-as="main">
<tr style="font-weight: bold;">
<td colspan="6">
<span t-esc="main['shop']"/>
</td>
<td colspan="6">
<span t-esc="main['session']"/>
</td>
<td colspan="6">
<span t-esc="main['date_order']"/>
</td>
<td colspan="6">
<span t-esc="main['name']"/>
</td>
<td colspan="6">
<span t-esc="main['salesman']"/>
</td>
<td colspan="6">
<span t-esc="main['default_code']"/>
</td>
<td colspan="6">
<span t-esc="main['full_product_name']"/>
</td>
<td colspan="6">
<span t-esc="main['price_unit']"/>
</td>
<td colspan="6">
<span t-esc="main['sum']"/>
</td>
<td colspan="6">
<span t-esc="main['price_subtotal']"/>
</td>
<td colspan="6">
<span t-esc="main['price_subtotal_incl']"/>
</td>
</tr>
</t>
</tbody>
</table>
</div>
<br></br>
</div>
</template>
<template id="report_product">
<div class="page">
<div class="oe_structure"/>
<span t-if="Filters.get('date_from')">
<strong>From:</strong>
<t t-esc="Filters['date_from']"/>
</span>
<span t-if="Filters.get('date_to')">
<strong>To:</strong>
<t t-esc="Filters['date_to']"/>
</span>
<div>
<div style="width:100%;">
<div style="text-align:centre;" class="row">
<div class="col-2">
<strong>Report Type:</strong>
<t t-esc="Filters.get('report_type')"/>
</div>
</div>
</div>
<br></br>
<table class="table table-sm table-reports">
<thead>
<tr class="text-right">
<th>Category</th>
<th colspan="6">Product Code</th>
<th colspan="6">Product Name</th>
<th colspan="6">Qty</th>
<th colspan="6">Amount Total</th>
<th colspan="6">Amount Total Incl</th>
</tr>
</thead>
<tbody>
<t t-foreach="report_main_line_data" t-as="main">
<tr style="font-weight: bold;">
<td colspan="6">
<span t-esc="main['name']"/>
</td>
<td colspan="6">
<span t-esc="main['default_code']"/>
</td>
<td colspan="6">
<span t-esc="main['full_product_name']"/>
</td>
<td colspan="6">
<span t-esc="main['qty']"/>
</td>
<td colspan="6">
<span t-esc="main['amount_total']"/>
</td>
<td colspan="6">
<span t-esc="main['amount_total']"/>
</td>
</tr>
</t>
</tbody>
</table>
</div>
<br></br>
</div>
</template>
<template id="report_category">
<div class="page">
<div class="oe_structure"/>
<span t-if="Filters.get('date_from')">
<strong>From:</strong>
<t t-esc="Filters['date_from']"/>
</span>
<span t-if="Filters.get('date_to')">
<strong>To:</strong>
<t t-esc="Filters['date_to']"/>
</span>
<div>
<div style="width:100%;">
<div style="text-align:centre;" class="row">
<div class="col-2">
<strong>Report Type:</strong>
<t t-esc="Filters.get('report_type')"/>
</div>
</div>
</div>
<br></br>
<table class="table table-sm table-reports">
<thead>
<tr>
<th colspan="6">Category</th>
<th colspan="6">Qty</th>
<th colspan="6">Amount Total</th>
<th colspan="6">Amount Total Incl</th>
</tr>
</thead>
<tbody>
<t t-foreach="report_main_line_data" t-as="pos_category">
<tr style="font-weight: bold;">
<td colspan="6">
<span t-esc="pos_category['name']"/>
</td>
<td colspan="6">
<span t-esc="pos_category['qty']"/>
</td>
<td colspan="6">
<span t-esc="pos_category['amount_total']"/>
</td>
<td colspan="6">
<span t-esc="pos_category['total_incl']"/>
</td>
</tr>
</t>
</tbody>
</table>
</div>
<br></br>
</div>
</template>
<template id="report_salesman">
<div class="page">
<div class="oe_structure"/>
<span t-if="Filters.get('date_from')">
<strong>From:</strong>
<t t-esc="Filters['date_from']"/>
</span>
<span t-if="Filters.get('date_to')">
<strong>To:</strong>
<t t-esc="Filters['date_to']"/>
</span>
<div>
<div style="width:100%;">
<div style="text-align:centre;" class="row">
<div class="col-2">
<strong>Report Type:</strong>
<t t-esc="Filters.get('report_type')"/>
</div>
</div>
</div>
<br></br>
<table class="table table-sm table-reports">
<thead>
<tr>
<th>Salesman</th>
<th colspan="6">Total Order</th>
<th colspan="6">Total Qty</th>
<th colspan="6">Total Amount</th>
</tr>
</thead>
<tbody>
<t t-foreach="report_main_line_data" t-as="main">
<tr style="font-weight: bold;">
<td>
<span t-esc="main['name']"/>
</td>
<td colspan="6">
<span t-esc="main['order']"/>
</td>
<td colspan="6">
<span t-esc="main['qty']"/>
</td>
<td colspan="6">
<span t-esc="main['amount']"/>
</td>
</tr>
</t>
</tbody>
</table>
</div>
<br></br>
</div>
</template>
<template id="report_payment">
<div class="page">
<div class="oe_structure"/>
<span t-if="Filters.get('date_from')">
<strong>From:</strong>
<t t-esc="Filters['date_from']"/>
</span>
<span t-if="Filters.get('date_to')">
<strong>To:</strong>
<t t-esc="Filters['date_to']"/>
</span>
<div>
<div style="width:100%;">
<div style="text-align:centre;" class="row">
<div class="col-2">
<strong>Report Type:</strong>
<t t-esc="Filters.get('report_type')"/>
</div>
</div>
</div>
<br></br>
<table class="table table-sm table-reports">
<thead>
<tr>
<th>Point of Sale</th>
<th colspan="6">PoS Session</th>
<th colspan="6">Payment</th>
<th colspan="6">Total Amount</th>
</tr>
</thead>
<tbody>
<t t-foreach="report_main_line_data" t-as="main">
<tr style="font-weight: bold;">
<td>
<span t-esc="main['config']"/>
</td>
<td colspan="6">
<span t-esc="main['session']"/>
</td>
<td colspan="6">
<span t-esc="main['name']"/>
</td>
<td colspan="6">
<span t-esc="main['sum']"/>
</td>
</tr>
</t>
</tbody>
</table>
</div>
<br></br>
</div>
</template>
<record id="action_report_pos_all_in_one" model="ir.actions.report">
<field name="name">POS All In One Report</field>
<field name="model">pos.report</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">pos_report_generator.pos_order_report</field>
<field name="report_file">pos_report_generator.pos_order_report</field>
</record>
</odoo>

2
pos_report_generator/security/ir.model.access.csv

@ -0,0 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_pos_report,access.pos.report,model_pos_report,base.group_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_pos_report access.pos.report model_pos_report base.group_user 1 1 1 1

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
pos_report_generator/static/description/assets/icons/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 839 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 988 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

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

Loading…
Cancel
Save