# Part of Odoo. See LICENSE file for full copyright and licensing details. import base64 import io import json import zipfile from datetime import datetime from odoo import fields, models, api, _ from odoo.exceptions import ValidationError from odoo.addons.l10n_at_pos.models.fiskaly_client import FiskalyClient, fiskaly_iap_rpc class PosConfig(models.Model): _inherit = 'pos.config' l10n_at_cash_regid = fields.Char(string="Fiskaly Cash Register ID", readonly=True, copy=False, help="Cash register identifier for this config generated by fiskaly") @api.model_create_multi def create(self, vals_list): configs = super().create(vals_list) for config in configs: if config.company_id.l10n_at_fiskaly_access_token: if not config.company_id.l10n_at_is_fon_authenticated: raise ValidationError(_("Please Authenticate FON first from the company form.")) config._configure_register() return configs def _configure_register(self): self.ensure_one() fiskaly_client = FiskalyClient(self.company_id, self.company_id.l10n_at_fiskaly_api_key, self.company_id.l10n_at_fiskaly_api_secret) self.company_id._verify_required_fields() # For each company there should be only single SCU with initialized state if not self.company_id.l10n_at_pos_company_scuid: scuid = fiskaly_client.setup_scu({"legal_entity_id": {"vat_id": self.company_id.vat}}, self.company_id.l10n_at_fiskaly_access_token) self.company_id.l10n_at_pos_company_scuid = scuid self.env.cr.commit() # Now create register on fiskaly (no need to check for config) new_reg_id = fiskaly_client.setup_cash_reg(self.company_id.l10n_at_fiskaly_access_token) self.l10n_at_cash_regid = new_reg_id self.env.cr.commit() # Now update these data if company managed by us if self.company_id.l10n_at_is_odoo_managed_org: data = { "db_uuid": self.env['ir.config_parameter'].sudo().get_param('database.uuid'), "company_id": self.company_id.id, "fiskaly_reg_id": self.l10n_at_cash_regid, "company_scuid": self.company_id.l10n_at_pos_company_scuid, } fiskaly_iap_rpc(self.company_id, "/update_reg", data) def print_dep7_report(self, start_date, end_date): fiskaly_client = FiskalyClient(self.company_id, self.company_id.l10n_at_fiskaly_api_key, self.company_id.l10n_at_fiskaly_api_secret) starting_time, ending_time = (int(dt.timestamp()) for dt in (start_date, end_date)) zip_buffer = io.BytesIO() with zipfile.ZipFile(zip_buffer, 'w', 0) as zf: for config in self: if config.l10n_at_cash_regid: audit_report_response = fiskaly_client.get_dep_data(config.company_id.l10n_at_fiskaly_access_token, config.l10n_at_cash_regid, starting_time, ending_time) filename = f"{config.name}_{start_date}_to_{end_date}_DEP_KassenID.json".replace(" ", "_") zf.writestr(filename, json.dumps(audit_report_response, indent=4, default=str)) zip_buffer.seek(0) attachment = self.env['ir.attachment'].create({ 'name': 'dep7_reports.zip', 'type': 'binary', 'datas': base64.b64encode(zip_buffer.read()), 'mimetype': 'application/zip', }) return { 'type': 'ir.actions.act_url', 'url': f'/web/content/{attachment.id}?download=true', } def fetch_fiskaly_closing_receipt_data(self, selection_date, period): self.ensure_one() fiskaly_client = FiskalyClient(self.company_id, self.company_id.l10n_at_fiskaly_api_key, self.company_id.l10n_at_fiskaly_api_secret) selected_date = datetime.strptime(selection_date, "%Y-%m") current_date = datetime.now() year_diff = current_date.year - selected_date.year month_diff = current_date.month - selected_date.month # Calculate the total difference in months total_month_diff = (year_diff * 12 + month_diff) offset = total_month_diff if period == "monthly" else year_diff message = _("No closing receipt found for the selected period.") # Closings exist only for past months, so the most recent closing (at the bottom) is for last month. # Therefore, Calculate the offset from last month if offset - 1 >= 0: receipt_type = "MONTHLY_CLOSE" if period == "monthly" else "YEARLY_CLOSE" response = fiskaly_client.get_closing_receipt(self.l10n_at_cash_regid, receipt_type, offset - 1, self.company_id.l10n_at_fiskaly_access_token) if response.get('data'): message = "success" return {'data': response.get('data'), 'message': message} return {'data': [], 'message': message} class ReportL10nAtPosConfigAuditTemplate(models.AbstractModel): _name = 'report.l10n_at_pos.report_config_audit_template' _description = 'Get DEP7 Report for Session.' @api.model def _get_report_values(self, docids, data=None): return { 'data': data, 'docs': self.env['res.company'].browse(self.env.company.id), }