diff --git a/new_module/s_license/controllers/__init__.py b/new_module/s_license/controllers/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f15990643090e623374de05461ea677547aae32d --- /dev/null +++ b/new_module/s_license/controllers/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -* +from . import license_registration +from . import license_check diff --git a/new_module/s_license/controllers/license_check.py b/new_module/s_license/controllers/license_check.py new file mode 100644 index 0000000000000000000000000000000000000000..f461043b14cde9459d5f688b3e1240450d14c074 --- /dev/null +++ b/new_module/s_license/controllers/license_check.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -* +from odoo import http +from odoo.http import request +import json + +class LicenseCheckController(http.Controller): + + @http.route('/api/license/check', type='http', auth='public', methods=['GET', 'POST'], csrf=False) + def check_license(self, key=None, **kwargs): + if not key: + return json.dumps({'error': 'Missing key parameter'}) + + license = request.env['license.manager'].sudo().search([('key', '=', key)], limit=1) + if not license: + return json.dumps({'status': 'Not found'}) + + return json.dumps({'status': license.status}) diff --git a/new_module/s_license/controllers/license_registration.py b/new_module/s_license/controllers/license_registration.py new file mode 100644 index 0000000000000000000000000000000000000000..1f7c509280ce1ef875000d25e8a9a49b4474c855 --- /dev/null +++ b/new_module/s_license/controllers/license_registration.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -* +from odoo import http +from odoo.http import request +import uuid + + +class LicenseController(http.Controller): + @http.route('/license/register', type='http', auth='public', website=True) + def license_registration_form(self, **kw): + return request.render('s_license.license_registration_form') + + @http.route('/license/register/submit', type='http', auth='public', methods=['POST'], website=True, csrf=False) + def submit_license_registration(self, **post): + license_values = { + 'name': post.get('name'), + 'start_date': post.get('start_date'), + 'end_date': post.get('end_date'), + 'key': str(uuid.uuid4()), + 'status': 'pending' + } + request.env['license.manager'].sudo().create(license_values) + return request.render('s_license.license_registration_success') diff --git a/new_module/s_license/data/cron_job.xml b/new_module/s_license/data/cron_job.xml new file mode 100644 index 0000000000000000000000000000000000000000..a7d34edb7a73fe0d850a853491832536606ec17c --- /dev/null +++ b/new_module/s_license/data/cron_job.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<odoo> + <record id="ir_cron_send_expiration_reminders" model="ir.cron"> + <field name="name">Send License Expiration Reminders</field> + <field name="model_id" ref="model_license_manager"/> + <field name="state">code</field> + <field name="code">model.send_expiration_reminders()</field> + <field name="interval_number">1</field> + <field name="interval_type">days</field> + <field name="numbercall">-1</field> + </record> + <record id="ir_cron_license_auto_renewal" model="ir.cron"> + <field name="name">License Auto Renewal</field> + <field name="model_id" ref="model_license_manager"/> + <field name="state">code</field> + <field name="code">model.auto_renew_licenses()</field> + <field name="interval_number">1</field> + <field name="interval_type">days</field> + <field name="active" eval="True"/> + </record> + <record id="ir_cron_license_auto_inactive" model="ir.cron"> + <field name="name">License Auto Inactive</field> + <field name="model_id" ref="model_license_manager"/> + <field name="state">code</field> + <field name="code">model.auto_inactive_licenses()</field> + <field name="interval_number">1</field> + <field name="interval_type">days</field> + <field name="active" eval="True"/> + </record> +</odoo> diff --git a/new_module/s_license/data/email_template.xml b/new_module/s_license/data/email_template.xml new file mode 100644 index 0000000000000000000000000000000000000000..3f324fee5697f5b0d9126268f00d769bf1c8656c --- /dev/null +++ b/new_module/s_license/data/email_template.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<odoo> + <data noupdate="1"> + <record id="email_template_license_expiration_reminder" model="mail.template"> + <field name="name">License Expiration Reminder</field> + <field name="model_id" ref="s_license.model_license_manager"/> + <field name="subject">Your License is About to Expire</field> + <field name="email_from">${object.env['res.users'].browse(object.env.uid).email}</field> + <field name="email_to">${object.email}</field> + <field name="body_html" type="html"> + <p>Dear <t t-esc="object.name"/>, + </p> + <p>Your license with key + <t t-esc="object.key"/> + is about to expire on <t t-esc="object.end_date"/>. + </p> + <p>Please renew your license to continue using our services.</p> + </field> + </record> + + <record id="email_template_license_registered" model="mail.template"> + <field name="name">New License Registered</field> + <field name="model_id" ref="s_license.model_license_manager"/> + <field name="email_from">{{object.env['res.users'].browse(object.env.uid).email}}</field> + <field name="subject">New License Registered</field> + <field name="body_html" type="html"> + <h2>A new License has been registered:</h2> + <label>Name:</label> + <p t-out="object.name"/> + <label>Email:</label> + <p t-out="object.email"/> + <label>Key:</label> + <p t="object.key"/> + </field> + </record> + </data> +</odoo> diff --git a/new_module/s_license/models/__init__.py b/new_module/s_license/models/__init__.py index a0fdc10fe11b9eb562881952079e34c2982f8604..a41708a85aab4cd364f0fd9534c5257925a40c1d 100644 --- a/new_module/s_license/models/__init__.py +++ b/new_module/s_license/models/__init__.py @@ -1,2 +1,3 @@ # -*- coding: utf-8 -*- -from . import models +from . import license_manager +from . import license_report diff --git a/new_module/s_license/models/license_manager.py b/new_module/s_license/models/license_manager.py new file mode 100644 index 0000000000000000000000000000000000000000..5ca62d92a3458902324cbfe9c81d7bf7f62c666a --- /dev/null +++ b/new_module/s_license/models/license_manager.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- +from odoo import models, fields, api +from datetime import timedelta, datetime +import logging + +_logger = logging.getLogger(__name__) + + +class LicenseManager(models.Model): + _name = 'license.manager' + _inherit = ['mail.thread', 'mail.activity.mixin'] + _description = 'License' + + name = fields.Char(string='Name', required=True, track_visibility='onchange') + start_date = fields.Date(string='Start Date', required=True) + end_date = fields.Date(string='End Date', required=True) + email = fields.Char(string='Email', required=True) + key = fields.Char(string='Key', required=True, track_visibility='onchange') + note = fields.Text(string='Note') + status = fields.Selection([ + ('active', 'Active'), + ('inactive', 'Inactive'), + ('pending', 'Pending'), + ('cancelled', 'Cancelled') + ], string='Status', default='pending', track_visibility='onchange') + auto_renew = fields.Boolean(string='Auto Renew', default=False) + auto_renewal_date = fields.Date(string='Auto Renewal Date') + + def send_expiration_reminders(self): + licenses_to_notify = self.search([ + ('end_date', '<=', fields.Date.today() + timedelta(days=7)), + ('status', '=', 'active') + ]) + email_from = self.env['res.users'].search([]).email + for license in licenses_to_notify: + email_to = license.email + template = self.env.ref('s_license.email_template_license_expiration_reminder') + template.send_mail(license.id, force_send=True, email_values={ + 'email_to': email_to, + 'email_from': email_from + }) + + @api.model + def create(self, vals): + record = super(LicenseManager, self).create(vals) + self._send_admin_notification(record) + return record + + def _send_admin_notification(self, record): + email_to = self.env['res.users'].search([]).email + template = self.env.ref('s_license.email_template_license_registered') + + template.send_mail(record.id, force_send=True, email_values={ + 'email_to': email_to, + 'email_from': email_to + }) + + def auto_renew_licenses(self): + today = fields.Date.today().strftime('%Y-%m-%d') + licenses_to_renew = self.search([ + ('end_date', '=', today), + ('auto_renew', '=', True), + ('status', '!=', 'cancelled') + ]) + for license in licenses_to_renew: + license.write({ + 'start_date': fields.Date.today(), + 'end_date': fields.Date.today() + timedelta(days=30 * int( + self.env['ir.config_parameter'].sudo().get_param('s_license.auto_renewal_period', default=1))), + 'auto_renewal_date': fields.Date.today() + timedelta(days=30 * int( + self.env['ir.config_parameter'].sudo().get_param('s_license.auto_renewal_period', default=1))), + }) + + def auto_inactive_licenses(self): + today = fields.Date.today().strftime('%Y-%m-%d') + licenses_to_inactive = self.search([ + ('end_date', '=', today), + ('auto_renew', '!=', True), + ('status', '=', 'active') + ]) + for license in licenses_to_inactive: + license.write({ + 'status': 'inactive' + }) + + @api.constrains("name", "start_date", "end_date", "email") + def check_change(self): + for record in self: + if record.status != "pending": + record.status = "pending" + + def action_approve(self): + return self._show_popup('Approve', 'pending', 'active') + + def action_cancel(self): + return self._show_popup('Cancel', 'pending', 'cancelled') + + def action_deactivate(self): + return self._show_popup('Deactivate', 'active', 'inactive') + + def _show_popup(self, action_name, from_state, to_state): + self.ensure_one() + return { + 'name': 'Date and Reason', + 'type': 'ir.actions.act_window', + 'view_type': 'form', + 'view_mode': 'form', + 'res_model': 'license.wizard', + 'target': 'new', + 'view_id': self.env.ref("s_license.view_form_license_wizard").id, + 'context': { + 'default_license_id': self.id, + 'default_action_name': action_name, + 'default_from_state': from_state, + 'default_to_state': to_state, + }, + } diff --git a/new_module/s_license/models/license_report.py b/new_module/s_license/models/license_report.py new file mode 100644 index 0000000000000000000000000000000000000000..84767d2506aa8e232bb3ce703497ce350c5227a5 --- /dev/null +++ b/new_module/s_license/models/license_report.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +from odoo import models, fields, api + + +class LicenseReport(models.AbstractModel): + _name = 'report.license_manager.license_report' + + @api.model + def _get_report_values(self, docids, data=None): + docs = self.env['license.manager'].browse(docids) + return { + 'doc_ids': docids, + 'doc_model': 'license.manager', + 'docs': docs, + 'data': data, + } diff --git a/new_module/s_license/models/models.py b/new_module/s_license/models/models.py deleted file mode 100644 index f3b81de05ec905a018fcbcd43df86574889aa132..0000000000000000000000000000000000000000 --- a/new_module/s_license/models/models.py +++ /dev/null @@ -1,68 +0,0 @@ -from datetime import datetime - -from odoo import models, fields, api - - -class License(models.Model): - _name = 'license.model' - _inherit = ['mail.thread', 'mail.activity.mixin'] - _description = 'License' - - name = fields.Char(string='Há» tĂªn', required=True, track_visibility='onchange') - start_date = fields.Date(string='NgĂ y bắt đầu', required=True) - end_date = fields.Date(string='NgĂ y kết thĂºc', required=True) - key = fields.Char(string='Key', required=True, track_visibility='onchange') - note = fields.Text(string='Ghi chĂº') - status = fields.Selection([ - ('active', 'Äang hoạt động'), - ('inactive', 'Ngừng hoạt động'), - ('pending', 'Chá» duyệt'), - ('cancelled', 'Há»§y') - ], string='Trạng thĂ¡i', default='pending', track_visibility='onchange') - - def action_approve(self): - return self._show_popup('approve') - - def action_cancel(self): - return self._show_popup('cancel') - - def action_deactivate(self): - return self._show_popup('deactivate') - - def _show_popup(self, action_name): - return { - 'name': 'Nháºp ngĂ y vĂ lĂ½ do', - 'type': 'ir.actions.act_window', - 'res_model': 'license.model', - 'view_mode': 'form', - 'res_id': self.id, - 'target': 'new', - 'view_id': self.env.ref("s_license.view_form_enter_date_reason_popup", False).id, - 'context': { - 'default_action_name': action_name, - }, - } - - def action_save_date_reason(self): - self.ensure_one() - action_name = self.env.context.get('default_action_name') - # note = self.env.context.get('default_note') - # current_date = fields.Date.context_today(self) - formatted_note = f"{datetime.today().strftime('%d/%m/%Y')} - {self.note}" - if action_name == 'approve': - self.write({ - 'status': 'active', - 'note': formatted_note, - }) - elif action_name == 'cancel': - self.write({ - 'status': 'cancelled', - 'note': formatted_note, - }) - elif action_name == 'deactivate': - self.write({ - 'status': 'inactive', - 'note': formatted_note, - }) - - return {'type': 'ir.actions.act_window_close'}