You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

132 lines
5.4 KiB

# -*- 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>))
#
# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1)
# It is forbidden to publish, distribute, sublicense, or sell copies of the Software
# or modified copies of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#
########################################################################################
from odoo import fields, models, api, _
try:
import qrcode
except ImportError:
qrcode = None
try:
import base64
except ImportError:
base64 = None
from io import BytesIO
import binascii
import pytz
from odoo.exceptions import UserError
from odoo.tools.pycompat import to_text
from odoo.tools import float_is_zero, float_compare, DEFAULT_SERVER_DATETIME_FORMAT
class InheritAccountMove(models.Model):
_inherit = 'account.move'
qr = fields.Binary("QR Code", compute='generate_qrcode', store=True)
def timezone(self, userdate):
tz_name = self.env.context.get('tz') or self.env.user.tz
contex_tz = pytz.timezone(tz_name)
date_time = pytz.utc.localize(userdate).astimezone(contex_tz)
return date_time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
def string_hexa(self, value):
if value:
string = str(value)
string_bytes = string.encode("UTF-8")
encoded_hex_value = binascii.hexlify(string_bytes)
hex_value = encoded_hex_value.decode("UTF-8")
return hex_value
def hexa(self, tag, length, value):
if tag and length and value:
hex_string = self.string_hexa(value)
length = int(len(hex_string) / 2)
conversion_table = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']
hexadecimal = ''
while (length > 0):
remainder = length % 16
hexadecimal = conversion_table[remainder] + hexadecimal
length = length // 16
if len(hexadecimal) == 1:
hexadecimal = "0" + hexadecimal
return tag + hexadecimal + hex_string
def qr_code_data(self):
sellername = str(self.company_id.name)
seller_vat_no = self.company_id.vat or ''
seller_hex = self.hexa("01", "0c", sellername)
vat_hex = self.hexa("02", "0f", seller_vat_no) or ""
time_stamp = self.timezone(self.create_date)
date_hex = self.hexa("03", "14", time_stamp)
total_with_vat_hex = self.hexa("04", "0a", str(round(self.amount_total, 2)))
total_vat_hex = self.hexa("05", "09", str(round(self.amount_tax, 2)))
qr_hex = seller_hex + vat_hex + date_hex + total_with_vat_hex + total_vat_hex
encoded_base64_bytes = base64.b64encode(bytes.fromhex(qr_hex)).decode()
return encoded_base64_bytes
@api.depends('state')
def generate_qrcode(self):
param = self.env['ir.config_parameter'].sudo()
qr_code = param.get_param('advanced_vat_invoice.generate_qr')
for rec in self:
if rec.state == 'posted':
if qrcode and base64:
if qr_code == 'automatically':
qr = qrcode.QRCode(
version=4,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=4,
border=1,
)
qr.add_data(self._origin.qr_code_data())
qr.make(fit=True)
img = qr.make_image()
temp = BytesIO()
img.save(temp, format="PNG")
qr_image = base64.b64encode(temp.getvalue())
rec.qr = qr_image
else:
raise UserError(_('Necessary Requirements To Run This Operation Is Not Satisfied'))
def generate_qr_button(self):
param = self.env['ir.config_parameter'].sudo()
qr_code = param.get_param('advanced_vat_invoice.generate_qr')
for rec in self:
if qrcode and base64:
if qr_code == 'manually':
qr = qrcode.QRCode(
version=4,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=4,
border=1,
)
qr.add_data(self.qr_code_data())
qr.make(fit=True)
img = qr.make_image()
temp = BytesIO()
img.save(temp, format="PNG")
qr_image = base64.b64encode(temp.getvalue())
rec.qr = qr_image
else:
raise UserError(_('Necessary Requirements To Run This Operation Is Not Satisfied'))