bigdawgbz

Submission.py

Jun 17th, 2025 (edited)
5
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 26.55 KB | Software | 0 0
  1. # -*- coding: utf-8 -*-
  2. import base64
  3. import io
  4. import re
  5. from datetime import datetime, time
  6. from urllib import response
  7.  
  8. import PyPDF2
  9. import werkzeug
  10. from PyPDF2 import PdfFileMerger
  11. from werkzeug import urls
  12. from odoo import models, fields, api, exceptions, _
  13. from odoo.exceptions import UserError, ValidationError
  14. from odoo.http import request
  15. from dateutil.relativedelta import relativedelta
  16. from dateutil import rrule
  17.  
  18. from odoo.tools.safe_eval import json
  19.  
  20. AMPS_SELECTION = [
  21. ('60', '60'), ('100', '100'), ('125', '125'),
  22. ('150', '150'), ('200', '200'), ('300', '300'),
  23. ('400', '400'), ('500', '500'), ('600', '600'),
  24. ('700', '700'), ('800', '800'), ('900', '900'),
  25. ('1000', '1000'), ('1100', '1100'), ('1200', '1200'),
  26. ('2000', '2000'), ('2500', '2500'),
  27. ]
  28. VOLTS_SELECTION = [
  29. ('240/120', '240/120'), ('208/120', '208/120'),
  30. ('480/277', '480/277'), ('600+', '600+'),
  31. ]
  32. PHASE_SELECTION = [
  33. ('single', 'Single'), ('double', 'Double'),
  34. ('three', 'Three'), ('four', 'Four'),
  35. ]
  36. METER_TYPE_SELECTION = [
  37. ('meter_bank', 'Meter Bank'), ('meter_1', 'Meter 1'),
  38. ('meter_2', 'Meter 2'), ('meter_3', 'Meter 3'),
  39. ('meter_4', 'Meter 4'), ('meter_5', 'Meter 5'),
  40. ('meter_6', 'Meter 6'),
  41. ]
  42.  
  43. class MeterSize(models.Model):
  44. _name = 'puc.meter.size'
  45. name = fields.Char('Meter')
  46.  
  47. class CableSize(models.Model):
  48. _name = 'puc.cable.size'
  49. name = fields.Char('Cable Size')
  50.  
  51. class ProjectSummary(models.Model):
  52. _name = 'project.summary'
  53.  
  54. service_type = fields.Many2one('puc.meter.size', string="Service Type")
  55. type = fields.Selection(selection=METER_TYPE_SELECTION, string="Type")
  56. amps = fields.Selection(selection=AMPS_SELECTION, string='AMPS', required=True)
  57. volts = fields.Selection(selection=VOLTS_SELECTION, string="Volts", required=True)
  58. phase = fields.Selection(selection=PHASE_SELECTION, string="Phase", required=True)
  59.  
  60. cable_type_L = fields.Many2one('puc.cable.size', string="C size/type L")
  61. cable_type_L2 = fields.Many2one('puc.cable.size', string="C size/type L2")
  62. cable_type_L3 = fields.Many2one('puc.cable.size', string="C size/type L3")
  63. cable_type_N = fields.Many2one('puc.cable.size', string="C size/type N", required=True)
  64. cable_type_G = fields.Many2one('puc.cable.size', string="C size/type G")
  65.  
  66. square_footage = fields.Char(string="Square Feet")
  67. kva = fields.Char(string="kVA", required=True)
  68. submission_id = fields.Many2one('puc.submission', string='Submission')
  69.  
  70. class PucSubmission(models.Model):
  71. _name = 'puc.submission'
  72. _inherit = ['portal.mixin', 'mail.thread', 'mail.activity.mixin']
  73. _description = "PUC Submission"
  74. _rec_name = 'name'
  75.  
  76. @api.model
  77. def create(self, values):
  78. if self._context.get(
  79. 'default_submission_type') == 'Design for No Objection' or \
  80. values['submission_type'] == 'Design for No Objection':
  81. values['name'] = self.env['ir.sequence'].get(
  82. 'puc.submission.design.code') or ' '
  83. elif self._context.get(
  84. 'default_submission_type') == 'Non-Compliance' or \
  85. values['submission_type'] == 'Non-Compliance':
  86. values['name'] = self.env['ir.sequence'].get(
  87. 'puc.submission.compliance.code') or ' '
  88. elif self._context.get(
  89. 'default_submission_type') == 'Social TCC' or \
  90. values['submission_type'] == 'Social TCC':
  91. values['name'] = self.env['ir.sequence'].get(
  92. 'puc.submission.social.code') or ' '
  93. elif self._context.get(
  94. 'default_submission_type') == 'Upgrade' or \
  95. values['submission_type'] == 'Upgrade':
  96. values['name'] = self.env['ir.sequence'].get(
  97. 'puc.submission.upgrade.code') or ' '
  98. elif self._context.get(
  99. 'default_submission_type') == 'Add To Existing' or \
  100. values['submission_type'] == 'Add To Existing':
  101. values['name'] = self.env['ir.sequence'].get(
  102. 'puc.submission.add.code') or ' '
  103. res = super(PucSubmission, self).create(values)
  104. return res
  105.  
  106. def _default_officer(self):
  107. user = self.env.user
  108. inspector = self.env['hr.employee'].search([('user_id', '=', user.id)])
  109. return inspector
  110.  
  111. puc_wireman_id = fields.Many2one('puc.wireman',
  112. domain="[('state', 'in', ['active', 'inactive'])]",
  113. string='Submitted By', tracking=True)
  114. wireman_id_no = fields.Char('Wireman ID', tracking=True)
  115. image = fields.Binary('Image')
  116. name = fields.Char(size=128, string="Project", copy=False)
  117. street = fields.Char(string="Street", tracking=True)
  118. street2 = fields.Char(string='Street 2', tracking=True)
  119. zip = fields.Char(string='Zip', tracking=True)
  120. city_id = fields.Many2one('puc.city', 'City', tracking=True)
  121. submission_id = fields.Many2one('puc.submission', string='Submission No',
  122. domain="[('states', '=', 'NOD')]")
  123. village_id = fields.Many2one('puc.village', 'Village',
  124. domain="[('district_id', '=?', district_id)]",
  125. tracking=True)
  126. major_town_id = fields.Many2one('puc.majortown', 'Major Town',
  127. domain="[('district_id', '=?', district_id)]",
  128. tracking=True)
  129. major_city_id = fields.Many2one('puc.major.city', 'Major City',
  130. domain="[('district_id', '=?', district_id)]",
  131. tracking=True)
  132. district_id = fields.Many2one('puc.district', 'District',
  133. tracking=True)
  134. country_id = fields.Many2one('res.country', string="Country",
  135. tracking=True)
  136. states = fields.Selection(selection=[('Draft', 'Draft'),
  137. ('Received', 'Recieved'),
  138. ('Reviewing', 'Reviewing'),
  139. ('Returned For Corrections',
  140. 'Returned For Corrections'),
  141. ('NOD', 'NOD'), ('Unapproved',
  142. 'Unapproved')],
  143. default="Draft", tracking=True,
  144. string="State")
  145. enable_inspection = fields.Boolean(default=False)
  146. telephone_no = fields.Char(string="Telephone No.", tracking=True)
  147. submission_date = fields.Datetime(compute='compute_submission_date',
  148. store=True)
  149. approval_date = fields.Datetime(readonly=True)
  150. wireman_license_no = fields.Char(string='Cat/Lic No',
  151. related='puc_wireman_id.wireman_license_no')
  152. submission_type = fields.Selection([("Design for No Objection",
  153. "Design for No Objection"),
  154. ("Non-Compliance", "Non-Compliance"),
  155. ("Add To Existing", "Add To Existing"),
  156. ("Social TCC", "Social TCC"),
  157. ("Upgrade", "Upgrade")],
  158. required=True,
  159. string="Submission Type", tracking=True)
  160. phone = fields.Char('Phone', tracking=True)
  161. email = fields.Char('Email', tracking=True)
  162. date = fields.Date('Submission Date',
  163. default=fields.Date.context_today)
  164. owner_phone_no = fields.Char('Owner Phone', tracking=True)
  165. owner_email = fields.Char('Owner E-mail', tracking=True)
  166. owner_id = fields.Many2many('res.partner', string='Owner/Developer',
  167. required=True, tracking=True)
  168. location = fields.Char(string="Project Location", size=64)
  169. district = fields.Selection(string="District",
  170. selection=[("belize", "Belize"),
  171. ("cayo", "Cayo"),
  172. ("corozal", "Corozal"),
  173. ("orange walk", "Orange Walk"),
  174. ("stann creek", "Stann Creek"),
  175. ("toledo", "Todelo")],
  176. default="belize")
  177. notes = fields.Text(string="Additional Notes", tracking=True)
  178. attachment_ids = fields.Many2many('ir.attachment', 'up_attachment_id',
  179. 'attachment_ref',
  180. string="Attachments")
  181. approved_attachment_ids = fields.Many2many('ir.attachment',
  182. 'approved_attachment_id',
  183. 'attachment_ref1',
  184. string="Upload Approved Document")
  185. returned_attachment_ids = fields.Many2many('ir.attachment',
  186. 'returned_attachment_ids',
  187. 'attachment_ref2',
  188. string="Returned For Correction")
  189. corrected_attachment_ids = fields.Many2many('ir.attachment',
  190. 'return_attachment_ids',
  191. 'attachment_ref3',
  192. string="Corrected document")
  193. reviewed_attachment_ids = fields.Many2many('ir.attachment',
  194. 'review_attachment_ids',
  195. 'attachment_ref4',
  196. string="Reviewed document")
  197. upload_documents = fields.Selection([('approved', 'Approved Document'),
  198. ('returned', 'Returned For Correction')
  199. ], string="Upload Documents For")
  200. project_summary_id = fields.One2many('project.summary', 'submission_id',
  201. 'Summary')
  202. service_type = fields.Many2one('puc.meter.size', compute='_compute_summary_fields', store=True, string="Service Type")
  203. #amps = fields.Selection(selection=AMPS_SELECTION, string='AMPS', required=True)
  204. amps = fields.Selection(selection=AMPS_SELECTION, compute='_compute_summary_fields', store=True)
  205. #amps = fields.Selection(selection=ProjectSummary._fields['amps'].selection, compute='_compute_summary_fields', store=True)
  206. volts = fields.Selection(selection=ProjectSummary._fields['volts'].selection, compute='_compute_summary_fields', store=True)
  207. phase = fields.Selection(selection=ProjectSummary._fields['phase'].selection, compute='_compute_summary_fields', store=True)
  208. kva = fields.Char(string="kVA", compute='_compute_summary_fields', store=True)
  209. #End
  210. user_id1 = fields.Many2one('res.users', string='User',
  211. default=lambda self: self.env.uid)
  212. company_id = fields.Many2one('res.company', 'Company', readonly=True,
  213. default=lambda self: self.env.user.company_id,
  214. tracking=True)
  215. reviewer_id = fields.Many2one('hr.employee',
  216. domain="[('is_reviewer', '=', True)]",
  217. default=_default_officer, readonly=True)
  218. reviewer_signature = fields.Binary(readonly=True)
  219. approval_id = fields.Many2one('hr.employee',
  220. domain="[('id', '!=', reviewer_id), "
  221. "('is_approver', '=', True)]",
  222. readonly=True)
  223. approval_signature = fields.Binary(readonly=True)
  224. days_pending = fields.Integer(default=0)
  225. inspection_created = fields.Boolean(default=False)
  226. re_attached_boolean = fields.Boolean(default=False)
  227. return_corrected_boolean = fields.Boolean(default=False)
  228. load_center_code = fields.Selection([('Belize City', 'BC'),
  229. ('Belize District', 'BD'),
  230. ('San Pedro', 'SP'),
  231. ('Caye Caulker', 'CC'),
  232. ('Orange Walk', 'OWK'),
  233. ('Corozal', 'CZL'),
  234. ('Belmopan', 'BMP'),
  235. ('Cayo', 'CYO'),
  236. ('Dangriga', 'DNG'),
  237. ('Independence', 'IND'),
  238. ('Placencia', 'PLA'),
  239. ('Stann Creek', 'SC'),
  240. ('Toledo', 'TOL')], string="Load Center", tracking=True)
  241.  
  242. def name_get(self):
  243. result = []
  244. for record in self:
  245. if record.name:
  246. result.append(
  247. (record.id, "{}".format(record.name)))
  248. else:
  249. result.append(
  250. (record.id, "{}".format(record.submission_id.name)))
  251. return result
  252.  
  253. @api.depends('create_date')
  254. def compute_submission_date(self):
  255. """Compute submission date"""
  256. self.submission_date = self.create_date
  257.  
  258. @api.onchange('puc_wireman_id')
  259. def _onchange_puc_wireman_id(self):
  260. """Onchange of wireman id"""
  261. self.wireman_id_no = self.puc_wireman_id.id_number
  262. self.email = self.puc_wireman_id.email
  263. self.phone = self.puc_wireman_id.mobile_telephone_no
  264. self.country_id = self.env.user.company_id.country_id
  265.  
  266. @api.onchange('owner_id')
  267. def _onchange_owner_id(self):
  268. """Onchange of owner id"""
  269. for rec in self.owner_id:
  270. if not self.owner_email:
  271. self.owner_email = rec.email
  272. if not self.owner_phone_no:
  273. self.owner_phone_no = rec.phone
  274.  
  275. @api.onchange('submission_id')
  276. def _onchange_submission_id(self):
  277. """Onchange of submission id"""
  278. submission_id = self.submission_id
  279. self.puc_wireman_id = submission_id.puc_wireman_id
  280. self.owner_id = submission_id.owner_id
  281. self.street = submission_id.street
  282. self.street2 = submission_id.street2
  283. self.village_id = submission_id.village_id
  284. self.major_town_id = submission_id.major_town_id
  285. self.major_city_id = submission_id.major_city_id
  286. self.district_id = submission_id.district_id
  287. self.country_id = submission_id.country_id
  288. self.notes = submission_id.notes
  289.  
  290. #Added 17/06/2025
  291. @api.depends('project_summary_id')
  292. def _compute_summary_fields(self):
  293. for rec in self:
  294. summary = rec.project_summary_id[:1] # Get first summary safely
  295. rec.service_type = summary.service_type.id if summary else False
  296. rec.amps = summary.amps if summary else False
  297. rec.volts = summary.volts if summary else False
  298. rec.phase = summary.phase if summary else False
  299. rec.kva = summary.kva if summary else False
  300.  
  301. def action_submit(self):
  302. """Submit action"""
  303. for line in self:
  304. display_message = 'Submission Request: ' + self.name + '<br>from ' + self.puc_wireman_id.name + '' \
  305. '<br>for Owner: ' + self.owner_id.name
  306. line.write({'states': 'Received'})
  307. line.message_post(body=display_message)
  308.  
  309. def action_submit_verify(self):
  310. if not self.reviewed_attachment_ids:
  311. raise UserError(_('Upload the Reviewed document'))
  312. view_id = self.env.ref(
  313. 'wireman.view_submission_reviewer_signature_form').id
  314. return {
  315. 'name': 'Reviewer Signature',
  316. 'type': 'ir.actions.act_window',
  317. 'res_model': 'submission.reviewer.signature',
  318. 'view_type': 'form',
  319. 'view_mode': 'form',
  320. 'target': 'new',
  321. 'view_id': view_id
  322. }
  323.  
  324. def action_validation(self):
  325. for line in self:
  326. if line.upload_documents != 'returned':
  327. raise UserError(_('Attach document For "Returned for '
  328. 'correction"'))
  329. if not line.returned_attachment_ids:
  330. raise UserError(_('Upload the document'))
  331. template_id = self.env.ref(
  332. 'wireman.email_template_submission_returned_for_correction1').id
  333. template = self.env['mail.template'].browse(template_id)
  334. if template:
  335. ctx = {
  336. 'default_model': 'puc.submission',
  337. 'default_res_id': self.ids[0],
  338. 'default_use_template': bool(template_id),
  339. 'default_template_id': template_id,
  340. 'default_composition_mode': 'comment',
  341. 'mark_so_as_sent': True,
  342. 'proforma': self.env.context.get('proforma', False),
  343. 'force_email': True,
  344. 'default_attachment_ids': [
  345. (6, 0, self.returned_attachment_ids.ids)]
  346. }
  347. return {
  348. 'type': 'ir.actions.act_window',
  349. 'view_mode': 'form',
  350. 'res_model': 'mail.compose.message',
  351. 'views': [(False, 'form')],
  352. 'view_id': False,
  353. 'target': 'new',
  354. 'context': ctx,
  355. }
  356.  
  357. def action_done(self):
  358. if self.upload_documents != 'approved':
  359. raise UserError(_('Attach document For Approved'))
  360. if not self.approved_attachment_ids:
  361. raise UserError(_('Upload the document'))
  362. if not self.project_summary_id:
  363. raise UserError(
  364. _('There is no project summary for this submission'))
  365. attach_approved = self.approved_attachment_ids._full_path(
  366. self.approved_attachment_ids.store_fname)
  367. try:
  368. PyPDF2.PdfFileReader(open(attach_approved, "rb"))
  369. except PyPDF2.utils.PdfReadError:
  370. raise UserError(_('Please upload a pdf file'))
  371. else:
  372. view_id = self.env.ref(
  373. 'wireman.view_submission_approve_signature_form').id
  374. return {
  375. 'name': 'Approval Signature',
  376. 'type': 'ir.actions.act_window',
  377. 'res_model': 'submission.approve.signature',
  378. 'view_type': 'form',
  379. 'view_mode': 'form',
  380. 'target': 'new',
  381. 'view_id': view_id
  382. }
  383.  
  384. def action_cancel(self):
  385. """Cancel action"""
  386. for line in self:
  387. line.write({'states': 'Unapproved'})
  388.  
  389. @api.model
  390. def build_qr_code_url(self):
  391. """QR Code creation"""
  392. base_url = request.env['ir.config_parameter'].sudo().get_param(
  393. 'web.base.url')
  394. base_url += '/submission/%s' % (self.id)
  395.  
  396. return '/report/barcode/?' + werkzeug.urls.url_encode(
  397. {'type': 'QR', 'value': base_url, 'width': 128,
  398. 'height': 128, 'humanreadable': 1})
  399.  
  400. def action_submission_send(self):
  401. submission_print = self.env['ir.attachment'].search(
  402. [('name', '=', 'Submission - %s' % self.name)])
  403. """ Opens a wizard to compose an email,
  404. with relevant mail template loaded by default """
  405. self.ensure_one()
  406. template_id = self.env.ref(
  407. 'wireman.email_template_submission_document_approved').id
  408. lang = self.env.context.get('lang')
  409. template = self.env['mail.template'].browse(template_id)
  410. Urls = urls.url_join(self.get_base_url(),
  411. '/my/submission/%(id)s' % {
  412. 'id': self.id,
  413. })
  414. if template.lang:
  415. lang = template._render_lang(self.ids)[self.id]
  416. ctx = {
  417. 'default_model': 'puc.submission',
  418. 'default_res_id': self.ids[0],
  419. 'default_use_template': bool(template_id),
  420. 'default_template_id': template_id,
  421. 'default_composition_mode': 'comment',
  422. 'force_email': True,
  423. 'default_attachment_ids': [
  424. (6, 0, submission_print.ids)],
  425. 'Urls': Urls
  426. }
  427. return {
  428. 'type': 'ir.actions.act_window',
  429. 'view_mode': 'form',
  430. 'res_model': 'mail.compose.message',
  431. 'views': [(False, 'form')],
  432. 'view_id': False,
  433. 'target': 'new',
  434. 'context': ctx,
  435. }
  436.  
  437.  
  438. def day_pending_submission(self):
  439. puc_submission = self.env['puc.submission'].sudo().search(
  440. [('states', 'not in', ('NOD', 'Unapproved'))])
  441. for rec in puc_submission:
  442. today = fields.Date.today()
  443. sub_date = rec.submission_date.date()
  444. rec.days_pending = (today - sub_date).days
  445.  
  446. def action_create_inspection(self):
  447. submission_type_code = self.env['submission.type.code'].search(
  448. [('name', '=', self.submission_type)])
  449. if re.search("SUBDA", str(self.name)):
  450. inspection_type = "TCC-RI"
  451. elif re.search("SUBNC", str(self.name)):
  452. inspection_type = "TCC-RI-End"
  453. elif re.search("SUBAE", str(self.name)):
  454. inspection_type = "ADD TO Existing"
  455. else:
  456. inspection_type = "BEL"
  457. puc_inspection = self.env['puc.inspection'].create({
  458. 'submission_id': self.id,
  459. 'construct_wireman_id': self.puc_wireman_id.id,
  460. 'district_code': self.district_id.district_code,
  461. 'submission_type_code': submission_type_code.code,
  462. 'inspection_type': inspection_type,
  463. })
  464.  
  465. if puc_inspection:
  466. display_message = puc_inspection.name + ' Inspection has been created ' \
  467. '<br> for submission :' + self.name
  468. self.inspection_created = True
  469. self.message_post(body=display_message)
  470. view = self.env.ref('wireman.view_puc_inspection_form')
  471. return {
  472. 'name': 'inspection',
  473. 'view_type': 'form',
  474. 'res_model': 'puc.inspection',
  475. 'res_id': puc_inspection.id,
  476. 'views': [(view.id, 'form')],
  477. 'view_id': view.id,
  478. 'type': 'ir.actions.act_window',
  479. 'target': 'current'
  480. }
  481.  
  482. @api.onchange('attachment_ids', 'approved_attachment_ids',
  483. 'returned_attachment_ids', 'corrected_attachment_ids',
  484. 'reviewed_attachment_ids')
  485. def _attachment_check(self):
  486. attach_approved1 = ''
  487. if self.attachment_ids:
  488. attach_approved = self.attachment_ids._full_path(
  489. self.attachment_ids.store_fname)
  490. attach_approved1 = attach_approved
  491. if self.approved_attachment_ids:
  492. attach_approved = self.approved_attachment_ids._full_path(
  493. self.approved_attachment_ids.store_fname)
  494. attach_approved1 = attach_approved
  495. if self.returned_attachment_ids:
  496. attach_approved = self.returned_attachment_ids._full_path(
  497. self.returned_attachment_ids.store_fname)
  498. attach_approved1 = attach_approved
  499. if self.corrected_attachment_ids:
  500. attach_approved = self.corrected_attachment_ids._full_path(
  501. self.returned_attachment_ids.store_fname)
  502. attach_approved1 = attach_approved
  503. if self.reviewed_attachment_ids:
  504. attach_approved = self.reviewed_attachment_ids._full_path(
  505. self.reviewed_attachment_ids.store_fname)
  506. attach_approved1 = attach_approved
  507. if attach_approved1:
  508. try:
  509. PyPDF2.PdfFileReader(open(attach_approved1, "rb"))
  510. except PyPDF2.utils.PdfReadError:
  511. raise UserError(_('Please upload a pdf file'))
  512.  
  513. def action_notify(self, ):
  514. print('notify')
  515. notification = {
  516. 'type': 'ir.actions.client',
  517. 'tag': 'display_notification',
  518. 'params': {
  519. 'title': _('height'),
  520. 'message': 'Your Custom Message',
  521. 'sticky': False,
  522. }
  523. }
  524. return notification
  525.  
  526. class SubmissionReport(models.AbstractModel):
  527. _name = 'report.wireman.wireman_license_document'
  528. _description = 'Submission'
  529.  
  530. def _get_report_values(self, docids, data=None):
  531. docs = self.env['puc.submission'].browse(docids)
  532. for doc in docs:
  533. if doc.states != 'NOD':
  534. raise exceptions.ValidationError(
  535. 'Submission not in NOD State Cannot be printed')
  536. length = len(docs.project_summary_id)
  537. return {
  538. 'doc_ids': docs.ids,
  539. 'doc_model': 'puc.submission',
  540. 'docs': docs,
  541. 'project_length': length
  542. }
  543.  
  544. class SubmissionEmptyReport(models.AbstractModel):
  545. _name = 'report.wireman.wireman_submission_approved_pdf'
  546. _description = 'Submission'
  547.  
  548. def _get_report_values(self, docids, data=None):
  549. docs = self.env['puc.submission'].browse(docids)
  550. for doc in docs:
  551. if doc.states != 'NOD':
  552. raise exceptions.ValidationError(
  553. 'Submission not in NOD State Cannot be printed')
  554. length = len(docs.project_summary_id)
  555. return {
  556. 'doc_ids': docs.ids,
  557. 'doc_model': 'puc.submission',
  558. 'docs': docs,
  559. 'project_length': length
  560. }
  561.  
  562.  
  563. class SubmissionTypeCode(models.Model):
  564. _name = 'submission.type.code'
  565. _description = 'submission type code'
  566.  
  567. name = fields.Char('Submission Type')
  568. code = fields.Char('Submission Type Code')
  569.  
  570.  
  571. class SubmissionLoadCenter(models.Model):
  572. _name = 'submission.load.center'
  573. _description = 'Submission Load Center'
  574.  
  575. name = fields.Char('Name')
  576. load_center_code = fields.Char('Load Center Code')
  577. district_id = fields.Many2one('puc.district', 'District')
  578. country_id = fields.Many2one('res.country', 'Country')
Tags: submission
Add Comment
Please, Sign In to add comment