Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # -*- coding: utf-8 -*-
- import base64
- import io
- import re
- from datetime import datetime, time
- from urllib import response
- import PyPDF2
- import werkzeug
- from PyPDF2 import PdfFileMerger
- from werkzeug import urls
- from odoo import models, fields, api, exceptions, _
- from odoo.exceptions import UserError, ValidationError
- from odoo.http import request
- from dateutil.relativedelta import relativedelta
- from dateutil import rrule
- from odoo.tools.safe_eval import json
- AMPS_SELECTION = [
- ('60', '60'), ('100', '100'), ('125', '125'),
- ('150', '150'), ('200', '200'), ('300', '300'),
- ('400', '400'), ('500', '500'), ('600', '600'),
- ('700', '700'), ('800', '800'), ('900', '900'),
- ('1000', '1000'), ('1100', '1100'), ('1200', '1200'),
- ('2000', '2000'), ('2500', '2500'),
- ]
- VOLTS_SELECTION = [
- ('240/120', '240/120'), ('208/120', '208/120'),
- ('480/277', '480/277'), ('600+', '600+'),
- ]
- PHASE_SELECTION = [
- ('single', 'Single'), ('double', 'Double'),
- ('three', 'Three'), ('four', 'Four'),
- ]
- METER_TYPE_SELECTION = [
- ('meter_bank', 'Meter Bank'), ('meter_1', 'Meter 1'),
- ('meter_2', 'Meter 2'), ('meter_3', 'Meter 3'),
- ('meter_4', 'Meter 4'), ('meter_5', 'Meter 5'),
- ('meter_6', 'Meter 6'),
- ]
- class MeterSize(models.Model):
- _name = 'puc.meter.size'
- name = fields.Char('Meter')
- class CableSize(models.Model):
- _name = 'puc.cable.size'
- name = fields.Char('Cable Size')
- class ProjectSummary(models.Model):
- _name = 'project.summary'
- service_type = fields.Many2one('puc.meter.size', string="Service Type")
- type = fields.Selection(selection=METER_TYPE_SELECTION, string="Type")
- amps = fields.Selection(selection=AMPS_SELECTION, string='AMPS', required=True)
- volts = fields.Selection(selection=VOLTS_SELECTION, string="Volts", required=True)
- phase = fields.Selection(selection=PHASE_SELECTION, string="Phase", required=True)
- cable_type_L = fields.Many2one('puc.cable.size', string="C size/type L")
- cable_type_L2 = fields.Many2one('puc.cable.size', string="C size/type L2")
- cable_type_L3 = fields.Many2one('puc.cable.size', string="C size/type L3")
- cable_type_N = fields.Many2one('puc.cable.size', string="C size/type N", required=True)
- cable_type_G = fields.Many2one('puc.cable.size', string="C size/type G")
- square_footage = fields.Char(string="Square Feet")
- kva = fields.Char(string="kVA", required=True)
- submission_id = fields.Many2one('puc.submission', string='Submission')
- class PucSubmission(models.Model):
- _name = 'puc.submission'
- _inherit = ['portal.mixin', 'mail.thread', 'mail.activity.mixin']
- _description = "PUC Submission"
- _rec_name = 'name'
- @api.model
- def create(self, values):
- if self._context.get(
- 'default_submission_type') == 'Design for No Objection' or \
- values['submission_type'] == 'Design for No Objection':
- values['name'] = self.env['ir.sequence'].get(
- 'puc.submission.design.code') or ' '
- elif self._context.get(
- 'default_submission_type') == 'Non-Compliance' or \
- values['submission_type'] == 'Non-Compliance':
- values['name'] = self.env['ir.sequence'].get(
- 'puc.submission.compliance.code') or ' '
- elif self._context.get(
- 'default_submission_type') == 'Social TCC' or \
- values['submission_type'] == 'Social TCC':
- values['name'] = self.env['ir.sequence'].get(
- 'puc.submission.social.code') or ' '
- elif self._context.get(
- 'default_submission_type') == 'Upgrade' or \
- values['submission_type'] == 'Upgrade':
- values['name'] = self.env['ir.sequence'].get(
- 'puc.submission.upgrade.code') or ' '
- elif self._context.get(
- 'default_submission_type') == 'Add To Existing' or \
- values['submission_type'] == 'Add To Existing':
- values['name'] = self.env['ir.sequence'].get(
- 'puc.submission.add.code') or ' '
- res = super(PucSubmission, self).create(values)
- return res
- def _default_officer(self):
- user = self.env.user
- inspector = self.env['hr.employee'].search([('user_id', '=', user.id)])
- return inspector
- puc_wireman_id = fields.Many2one('puc.wireman',
- domain="[('state', 'in', ['active', 'inactive'])]",
- string='Submitted By', tracking=True)
- wireman_id_no = fields.Char('Wireman ID', tracking=True)
- image = fields.Binary('Image')
- name = fields.Char(size=128, string="Project", copy=False)
- street = fields.Char(string="Street", tracking=True)
- street2 = fields.Char(string='Street 2', tracking=True)
- zip = fields.Char(string='Zip', tracking=True)
- city_id = fields.Many2one('puc.city', 'City', tracking=True)
- submission_id = fields.Many2one('puc.submission', string='Submission No',
- domain="[('states', '=', 'NOD')]")
- village_id = fields.Many2one('puc.village', 'Village',
- domain="[('district_id', '=?', district_id)]",
- tracking=True)
- major_town_id = fields.Many2one('puc.majortown', 'Major Town',
- domain="[('district_id', '=?', district_id)]",
- tracking=True)
- major_city_id = fields.Many2one('puc.major.city', 'Major City',
- domain="[('district_id', '=?', district_id)]",
- tracking=True)
- district_id = fields.Many2one('puc.district', 'District',
- tracking=True)
- country_id = fields.Many2one('res.country', string="Country",
- tracking=True)
- states = fields.Selection(selection=[('Draft', 'Draft'),
- ('Received', 'Recieved'),
- ('Reviewing', 'Reviewing'),
- ('Returned For Corrections',
- 'Returned For Corrections'),
- ('NOD', 'NOD'), ('Unapproved',
- 'Unapproved')],
- default="Draft", tracking=True,
- string="State")
- enable_inspection = fields.Boolean(default=False)
- telephone_no = fields.Char(string="Telephone No.", tracking=True)
- submission_date = fields.Datetime(compute='compute_submission_date',
- store=True)
- approval_date = fields.Datetime(readonly=True)
- wireman_license_no = fields.Char(string='Cat/Lic No',
- related='puc_wireman_id.wireman_license_no')
- submission_type = fields.Selection([("Design for No Objection",
- "Design for No Objection"),
- ("Non-Compliance", "Non-Compliance"),
- ("Add To Existing", "Add To Existing"),
- ("Social TCC", "Social TCC"),
- ("Upgrade", "Upgrade")],
- required=True,
- string="Submission Type", tracking=True)
- phone = fields.Char('Phone', tracking=True)
- email = fields.Char('Email', tracking=True)
- date = fields.Date('Submission Date',
- default=fields.Date.context_today)
- owner_phone_no = fields.Char('Owner Phone', tracking=True)
- owner_email = fields.Char('Owner E-mail', tracking=True)
- owner_id = fields.Many2many('res.partner', string='Owner/Developer',
- required=True, tracking=True)
- location = fields.Char(string="Project Location", size=64)
- district = fields.Selection(string="District",
- selection=[("belize", "Belize"),
- ("cayo", "Cayo"),
- ("corozal", "Corozal"),
- ("orange walk", "Orange Walk"),
- ("stann creek", "Stann Creek"),
- ("toledo", "Todelo")],
- default="belize")
- notes = fields.Text(string="Additional Notes", tracking=True)
- attachment_ids = fields.Many2many('ir.attachment', 'up_attachment_id',
- 'attachment_ref',
- string="Attachments")
- approved_attachment_ids = fields.Many2many('ir.attachment',
- 'approved_attachment_id',
- 'attachment_ref1',
- string="Upload Approved Document")
- returned_attachment_ids = fields.Many2many('ir.attachment',
- 'returned_attachment_ids',
- 'attachment_ref2',
- string="Returned For Correction")
- corrected_attachment_ids = fields.Many2many('ir.attachment',
- 'return_attachment_ids',
- 'attachment_ref3',
- string="Corrected document")
- reviewed_attachment_ids = fields.Many2many('ir.attachment',
- 'review_attachment_ids',
- 'attachment_ref4',
- string="Reviewed document")
- upload_documents = fields.Selection([('approved', 'Approved Document'),
- ('returned', 'Returned For Correction')
- ], string="Upload Documents For")
- project_summary_id = fields.One2many('project.summary', 'submission_id',
- 'Summary')
- service_type = fields.Many2one('puc.meter.size', compute='_compute_summary_fields', store=True, string="Service Type")
- #amps = fields.Selection(selection=AMPS_SELECTION, string='AMPS', required=True)
- amps = fields.Selection(selection=AMPS_SELECTION, compute='_compute_summary_fields', store=True)
- #amps = fields.Selection(selection=ProjectSummary._fields['amps'].selection, compute='_compute_summary_fields', store=True)
- volts = fields.Selection(selection=ProjectSummary._fields['volts'].selection, compute='_compute_summary_fields', store=True)
- phase = fields.Selection(selection=ProjectSummary._fields['phase'].selection, compute='_compute_summary_fields', store=True)
- kva = fields.Char(string="kVA", compute='_compute_summary_fields', store=True)
- #End
- user_id1 = fields.Many2one('res.users', string='User',
- default=lambda self: self.env.uid)
- company_id = fields.Many2one('res.company', 'Company', readonly=True,
- default=lambda self: self.env.user.company_id,
- tracking=True)
- reviewer_id = fields.Many2one('hr.employee',
- domain="[('is_reviewer', '=', True)]",
- default=_default_officer, readonly=True)
- reviewer_signature = fields.Binary(readonly=True)
- approval_id = fields.Many2one('hr.employee',
- domain="[('id', '!=', reviewer_id), "
- "('is_approver', '=', True)]",
- readonly=True)
- approval_signature = fields.Binary(readonly=True)
- days_pending = fields.Integer(default=0)
- inspection_created = fields.Boolean(default=False)
- re_attached_boolean = fields.Boolean(default=False)
- return_corrected_boolean = fields.Boolean(default=False)
- load_center_code = fields.Selection([('Belize City', 'BC'),
- ('Belize District', 'BD'),
- ('San Pedro', 'SP'),
- ('Caye Caulker', 'CC'),
- ('Orange Walk', 'OWK'),
- ('Corozal', 'CZL'),
- ('Belmopan', 'BMP'),
- ('Cayo', 'CYO'),
- ('Dangriga', 'DNG'),
- ('Independence', 'IND'),
- ('Placencia', 'PLA'),
- ('Stann Creek', 'SC'),
- ('Toledo', 'TOL')], string="Load Center", tracking=True)
- def name_get(self):
- result = []
- for record in self:
- if record.name:
- result.append(
- (record.id, "{}".format(record.name)))
- else:
- result.append(
- (record.id, "{}".format(record.submission_id.name)))
- return result
- @api.depends('create_date')
- def compute_submission_date(self):
- """Compute submission date"""
- self.submission_date = self.create_date
- @api.onchange('puc_wireman_id')
- def _onchange_puc_wireman_id(self):
- """Onchange of wireman id"""
- self.wireman_id_no = self.puc_wireman_id.id_number
- self.email = self.puc_wireman_id.email
- self.phone = self.puc_wireman_id.mobile_telephone_no
- self.country_id = self.env.user.company_id.country_id
- @api.onchange('owner_id')
- def _onchange_owner_id(self):
- """Onchange of owner id"""
- for rec in self.owner_id:
- if not self.owner_email:
- self.owner_email = rec.email
- if not self.owner_phone_no:
- self.owner_phone_no = rec.phone
- @api.onchange('submission_id')
- def _onchange_submission_id(self):
- """Onchange of submission id"""
- submission_id = self.submission_id
- self.puc_wireman_id = submission_id.puc_wireman_id
- self.owner_id = submission_id.owner_id
- self.street = submission_id.street
- self.street2 = submission_id.street2
- self.village_id = submission_id.village_id
- self.major_town_id = submission_id.major_town_id
- self.major_city_id = submission_id.major_city_id
- self.district_id = submission_id.district_id
- self.country_id = submission_id.country_id
- self.notes = submission_id.notes
- #Added 17/06/2025
- @api.depends('project_summary_id')
- def _compute_summary_fields(self):
- for rec in self:
- summary = rec.project_summary_id[:1] # Get first summary safely
- rec.service_type = summary.service_type.id if summary else False
- rec.amps = summary.amps if summary else False
- rec.volts = summary.volts if summary else False
- rec.phase = summary.phase if summary else False
- rec.kva = summary.kva if summary else False
- def action_submit(self):
- """Submit action"""
- for line in self:
- display_message = 'Submission Request: ' + self.name + '<br>from ' + self.puc_wireman_id.name + '' \
- '<br>for Owner: ' + self.owner_id.name
- line.write({'states': 'Received'})
- line.message_post(body=display_message)
- def action_submit_verify(self):
- if not self.reviewed_attachment_ids:
- raise UserError(_('Upload the Reviewed document'))
- view_id = self.env.ref(
- 'wireman.view_submission_reviewer_signature_form').id
- return {
- 'name': 'Reviewer Signature',
- 'type': 'ir.actions.act_window',
- 'res_model': 'submission.reviewer.signature',
- 'view_type': 'form',
- 'view_mode': 'form',
- 'target': 'new',
- 'view_id': view_id
- }
- def action_validation(self):
- for line in self:
- if line.upload_documents != 'returned':
- raise UserError(_('Attach document For "Returned for '
- 'correction"'))
- if not line.returned_attachment_ids:
- raise UserError(_('Upload the document'))
- template_id = self.env.ref(
- 'wireman.email_template_submission_returned_for_correction1').id
- template = self.env['mail.template'].browse(template_id)
- if template:
- ctx = {
- 'default_model': 'puc.submission',
- 'default_res_id': self.ids[0],
- 'default_use_template': bool(template_id),
- 'default_template_id': template_id,
- 'default_composition_mode': 'comment',
- 'mark_so_as_sent': True,
- 'proforma': self.env.context.get('proforma', False),
- 'force_email': True,
- 'default_attachment_ids': [
- (6, 0, self.returned_attachment_ids.ids)]
- }
- return {
- 'type': 'ir.actions.act_window',
- 'view_mode': 'form',
- 'res_model': 'mail.compose.message',
- 'views': [(False, 'form')],
- 'view_id': False,
- 'target': 'new',
- 'context': ctx,
- }
- def action_done(self):
- if self.upload_documents != 'approved':
- raise UserError(_('Attach document For Approved'))
- if not self.approved_attachment_ids:
- raise UserError(_('Upload the document'))
- if not self.project_summary_id:
- raise UserError(
- _('There is no project summary for this submission'))
- attach_approved = self.approved_attachment_ids._full_path(
- self.approved_attachment_ids.store_fname)
- try:
- PyPDF2.PdfFileReader(open(attach_approved, "rb"))
- except PyPDF2.utils.PdfReadError:
- raise UserError(_('Please upload a pdf file'))
- else:
- view_id = self.env.ref(
- 'wireman.view_submission_approve_signature_form').id
- return {
- 'name': 'Approval Signature',
- 'type': 'ir.actions.act_window',
- 'res_model': 'submission.approve.signature',
- 'view_type': 'form',
- 'view_mode': 'form',
- 'target': 'new',
- 'view_id': view_id
- }
- def action_cancel(self):
- """Cancel action"""
- for line in self:
- line.write({'states': 'Unapproved'})
- @api.model
- def build_qr_code_url(self):
- """QR Code creation"""
- base_url = request.env['ir.config_parameter'].sudo().get_param(
- 'web.base.url')
- base_url += '/submission/%s' % (self.id)
- return '/report/barcode/?' + werkzeug.urls.url_encode(
- {'type': 'QR', 'value': base_url, 'width': 128,
- 'height': 128, 'humanreadable': 1})
- def action_submission_send(self):
- submission_print = self.env['ir.attachment'].search(
- [('name', '=', 'Submission - %s' % self.name)])
- """ Opens a wizard to compose an email,
- with relevant mail template loaded by default """
- self.ensure_one()
- template_id = self.env.ref(
- 'wireman.email_template_submission_document_approved').id
- lang = self.env.context.get('lang')
- template = self.env['mail.template'].browse(template_id)
- Urls = urls.url_join(self.get_base_url(),
- '/my/submission/%(id)s' % {
- 'id': self.id,
- })
- if template.lang:
- lang = template._render_lang(self.ids)[self.id]
- ctx = {
- 'default_model': 'puc.submission',
- 'default_res_id': self.ids[0],
- 'default_use_template': bool(template_id),
- 'default_template_id': template_id,
- 'default_composition_mode': 'comment',
- 'force_email': True,
- 'default_attachment_ids': [
- (6, 0, submission_print.ids)],
- 'Urls': Urls
- }
- return {
- 'type': 'ir.actions.act_window',
- 'view_mode': 'form',
- 'res_model': 'mail.compose.message',
- 'views': [(False, 'form')],
- 'view_id': False,
- 'target': 'new',
- 'context': ctx,
- }
- def day_pending_submission(self):
- puc_submission = self.env['puc.submission'].sudo().search(
- [('states', 'not in', ('NOD', 'Unapproved'))])
- for rec in puc_submission:
- today = fields.Date.today()
- sub_date = rec.submission_date.date()
- rec.days_pending = (today - sub_date).days
- def action_create_inspection(self):
- submission_type_code = self.env['submission.type.code'].search(
- [('name', '=', self.submission_type)])
- if re.search("SUBDA", str(self.name)):
- inspection_type = "TCC-RI"
- elif re.search("SUBNC", str(self.name)):
- inspection_type = "TCC-RI-End"
- elif re.search("SUBAE", str(self.name)):
- inspection_type = "ADD TO Existing"
- else:
- inspection_type = "BEL"
- puc_inspection = self.env['puc.inspection'].create({
- 'submission_id': self.id,
- 'construct_wireman_id': self.puc_wireman_id.id,
- 'district_code': self.district_id.district_code,
- 'submission_type_code': submission_type_code.code,
- 'inspection_type': inspection_type,
- })
- if puc_inspection:
- display_message = puc_inspection.name + ' Inspection has been created ' \
- '<br> for submission :' + self.name
- self.inspection_created = True
- self.message_post(body=display_message)
- view = self.env.ref('wireman.view_puc_inspection_form')
- return {
- 'name': 'inspection',
- 'view_type': 'form',
- 'res_model': 'puc.inspection',
- 'res_id': puc_inspection.id,
- 'views': [(view.id, 'form')],
- 'view_id': view.id,
- 'type': 'ir.actions.act_window',
- 'target': 'current'
- }
- @api.onchange('attachment_ids', 'approved_attachment_ids',
- 'returned_attachment_ids', 'corrected_attachment_ids',
- 'reviewed_attachment_ids')
- def _attachment_check(self):
- attach_approved1 = ''
- if self.attachment_ids:
- attach_approved = self.attachment_ids._full_path(
- self.attachment_ids.store_fname)
- attach_approved1 = attach_approved
- if self.approved_attachment_ids:
- attach_approved = self.approved_attachment_ids._full_path(
- self.approved_attachment_ids.store_fname)
- attach_approved1 = attach_approved
- if self.returned_attachment_ids:
- attach_approved = self.returned_attachment_ids._full_path(
- self.returned_attachment_ids.store_fname)
- attach_approved1 = attach_approved
- if self.corrected_attachment_ids:
- attach_approved = self.corrected_attachment_ids._full_path(
- self.returned_attachment_ids.store_fname)
- attach_approved1 = attach_approved
- if self.reviewed_attachment_ids:
- attach_approved = self.reviewed_attachment_ids._full_path(
- self.reviewed_attachment_ids.store_fname)
- attach_approved1 = attach_approved
- if attach_approved1:
- try:
- PyPDF2.PdfFileReader(open(attach_approved1, "rb"))
- except PyPDF2.utils.PdfReadError:
- raise UserError(_('Please upload a pdf file'))
- def action_notify(self, ):
- print('notify')
- notification = {
- 'type': 'ir.actions.client',
- 'tag': 'display_notification',
- 'params': {
- 'title': _('height'),
- 'message': 'Your Custom Message',
- 'sticky': False,
- }
- }
- return notification
- class SubmissionReport(models.AbstractModel):
- _name = 'report.wireman.wireman_license_document'
- _description = 'Submission'
- def _get_report_values(self, docids, data=None):
- docs = self.env['puc.submission'].browse(docids)
- for doc in docs:
- if doc.states != 'NOD':
- raise exceptions.ValidationError(
- 'Submission not in NOD State Cannot be printed')
- length = len(docs.project_summary_id)
- return {
- 'doc_ids': docs.ids,
- 'doc_model': 'puc.submission',
- 'docs': docs,
- 'project_length': length
- }
- class SubmissionEmptyReport(models.AbstractModel):
- _name = 'report.wireman.wireman_submission_approved_pdf'
- _description = 'Submission'
- def _get_report_values(self, docids, data=None):
- docs = self.env['puc.submission'].browse(docids)
- for doc in docs:
- if doc.states != 'NOD':
- raise exceptions.ValidationError(
- 'Submission not in NOD State Cannot be printed')
- length = len(docs.project_summary_id)
- return {
- 'doc_ids': docs.ids,
- 'doc_model': 'puc.submission',
- 'docs': docs,
- 'project_length': length
- }
- class SubmissionTypeCode(models.Model):
- _name = 'submission.type.code'
- _description = 'submission type code'
- name = fields.Char('Submission Type')
- code = fields.Char('Submission Type Code')
- class SubmissionLoadCenter(models.Model):
- _name = 'submission.load.center'
- _description = 'Submission Load Center'
- name = fields.Char('Name')
- load_center_code = fields.Char('Load Center Code')
- district_id = fields.Many2one('puc.district', 'District')
- country_id = fields.Many2one('res.country', 'Country')
Add Comment
Please, Sign In to add comment