From 9736b1baf3fa3eb46e993dde36c48533e2422588 Mon Sep 17 00:00:00 2001 From: sinergia Date: Fri, 23 Sep 2022 11:03:47 -0500 Subject: [PATCH] create model maintenance_service --- __init__.py | 3 + address.xml | 5 ++ locale/es.po | 5 ++ maintenance.py | 105 ++++++++++++++++++++--- maintenance.xml | 125 ++++++++++++++++++++++++--- sale.py | 145 ++++++-------------------------- sale.xml | 13 +-- subscription.py | 122 ++++++++++++++++++++++----- subscription.xml | 20 +++++ view/contract_form.xml | 5 ++ view/create_prorogue_form.xml | 15 ++-- view/maintenance_form.xml | 3 +- view/maintenance_tree.xml | 2 +- view/optical_equipment_tree.xml | 14 +-- view/sale_line_form.xml | 3 +- 15 files changed, 394 insertions(+), 191 deletions(-) diff --git a/__init__.py b/__init__.py index 3dda22c..4253dde 100644 --- a/__init__.py +++ b/__init__.py @@ -15,10 +15,13 @@ def register(): equipment.EquipmentMaintenance, configuration_equipment.Configuration, maintenance.Maintenance, + maintenance.MaintenanceService, maintenance.MaintenanceActivity, maintenance.MaintenanceLine, move.Move, move.ShipmentOut, + sale.Sale, + sale.SaleLine, subscription.Contract, subscription.Subscription, subscription.CreateInitialContract, diff --git a/address.xml b/address.xml index 1ad2a65..c3fbd96 100644 --- a/address.xml +++ b/address.xml @@ -2,6 +2,11 @@ + + party.address + + address_tree + party.address diff --git a/locale/es.po b/locale/es.po index 8f36591..ae407b0 100644 --- a/locale/es.po +++ b/locale/es.po @@ -392,6 +392,11 @@ msgctxt "field:sale.subscription.line,subscription_end_date:" msgid "Subscription End Date" msgstr "Fecha final del Contrato" +msgctxt "" +"model:ir.action.act_window.domain,name:act_subscription_form_domain_closed" +msgid "Closed" +msgstr "Vencidas" + msgctxt "model:ir.ui.menu,name:menu_contracts" msgid "Contracts Management" msgstr "Gestión de Contratos" diff --git a/maintenance.py b/maintenance.py index 2eb2bab..2854047 100644 --- a/maintenance.py +++ b/maintenance.py @@ -4,6 +4,7 @@ from trytond.model import ( Workflow, ModelSQL, ModelView, Unique, fields, sequence_ordered) from trytond.transaction import Transaction from trytond.pyson import Eval, If, Id +from trytond.pool import Pool import math as mt import numpy as np @@ -12,7 +13,9 @@ class Maintenance(Workflow, ModelSQL, ModelView): 'Equipment Maintenance' __name__ = 'optical_equipment.maintenance' - + + service_maintenance = fields.Many2One('optical_equipment.maintenance.service', "Maintenance Service", + ondelete='CASCADE', select=True) code = fields.Char( "Code", select=True,states={'readonly': True }) @@ -69,10 +72,9 @@ class Maintenance(Workflow, ModelSQL, ModelView): ('in_progress', 'finished') }) cls._buttons.update({ - 'draft': {}, - 'agended': {}, - 'in_progress': {}, - 'finished': {}, + 'agended': {'invisible': Eval('state').in_(['agended', 'in_progress', 'finished'])}, + 'in_progress': {'invisible': Eval('state').in_(['draft', 'in_progress', 'finished'])}, + 'finished': {'invisible': Eval('state').in_(['draft', 'agended', 'finished'])}, }) @staticmethod @@ -91,11 +93,6 @@ class Maintenance(Workflow, ModelSQL, ModelView): def default_state_agended(cls): return 'no_agenda' - @classmethod - @ModelView.button - @Workflow.transition('draft') - def draft(cls, maintenances): - pass @classmethod @ModelView.button @@ -106,7 +103,7 @@ class Maintenance(Workflow, ModelSQL, ModelView): @classmethod @ModelView.button @Workflow.transition('in_progress') - def inProgress(cls, maintenances): + def in_progress(cls, maintenances): pass @classmethod @@ -126,6 +123,90 @@ class Maintenance(Workflow, ModelSQL, ModelView): }) ] + +class MaintenanceService(ModelSQL, ModelView): + 'Equipment Maintenance Service' + __name__ = 'optical_equipment.maintenance.service' + + code = fields.Char( + "Code", select=True,states={'readonly': True }) + reference = fields.Char( + "Reference", select=True, + help="The identification of an external origin.") + description = fields.Char("Description", + states={ + 'readonly': Eval('state') != 'draft', + }) + #sale_date = fields.Function(fields.Char("Sale Date"), 'get_sale_date') + sale_origin = fields.Reference("Sale Origin", selection='get_origin', select=True, + states={'readonly': True}) + company = fields.Many2One('company.company', "Company", readonly=True) + maintenance_type = fields.Selection([('preventive', 'Preventive'), + ('corrective', 'Corrective') + ], "Maintenance Type") + propietary = fields.Many2One('party.party', "Propietary", required=True) + propietary_address = fields.Many2One('party.address', "Propietary Address", required=True, + domain=[('party', '=', Eval('propietary'))] + ) + lines = fields.One2Many('optical_equipment.maintenance', 'service_maintenance', "Lines") + estimated_agended = fields.DateTime("Date Maintenance") + state_agended = fields.Selection([('no_agenda', "No agenda"), + ('agended', "Agended"), + ('in_progress', "In progress"), + ('finish', "Finish"), + ('failed', "Failed")], "State Agenda") + technical = fields.Many2One('company.employee', "Technical") + + state = fields.Selection([('draft', "Draft"), + ('agended', "Agended"), + ('in_progress', "In Progress"), + ('failed', "Failed"), + ('finished', "Finished") + ], "State",required=True, readonly=True, sort=False) + + + @classmethod + def default_state(self): + return 'draft' + + @classmethod + def get_sale_date(self): + pass + + @classmethod + def _get_origin(cls): + 'Return list of Model names for origin Reference' + pool = Pool() + Sale = pool.get('sale.line') + + return [Sale.__name__] + + @classmethod + def get_origin(cls): + Model = Pool().get('ir.model') + get_name = Model.get_name + models = cls._get_origin() + + return [(None, '')] + [(m, get_name(m)) for m in models] + + + @classmethod + @ModelView.button + @Workflow.transition('agended') + def agended(cls, maintenances): + pass + + @classmethod + @ModelView.button + @Workflow.transition('in_progress') + def in_progress(cls, maintenances): + pass + + @classmethod + @ModelView.button + @Workflow.transition('finished') + def finished(cls, maintenances): + pass class MaintenanceActivity(ModelSQL): 'Maintenance - Products' @@ -290,4 +371,4 @@ class CalibrationSample(sequence_ordered(), ModelView, ModelSQL): expanded_uncertainty = fields.Float("Uncertainy Expanded") - + diff --git a/maintenance.xml b/maintenance.xml index 7a47f93..6b64bf0 100644 --- a/maintenance.xml +++ b/maintenance.xml @@ -18,6 +18,23 @@ form maintenance_form + + Services Maintenance + optical_equipment.maintenance.service + + + + optical_equipment.maintenance.service + tree + maintenance_service_tree + + + optical_equipment.maintenance.service + form + maintenance_service_form + + + optical_equipment.maintenance-optical_equipment.equipment @@ -84,30 +101,80 @@ - + + draft Draft - + - + agended Agended - + - + in_progress In progress - + - + finished Finished - + - + + + Draft + + + + + + + Agended + + + + + + + In progress + + + + + + + Failed + + + + + + + Finished + + + + + + + All + + + + + optical_equipment.maintenance.line form @@ -124,5 +191,39 @@ maintenance_calibration_tree + + optical_equipment.maintenance.service + calendar + maintenance_calendar + + + Agenda + optical_equipment.maintenance.service + + + + + + + + + + + + + + + diff --git a/sale.py b/sale.py index 34414aa..dc89e93 100644 --- a/sale.py +++ b/sale.py @@ -18,7 +18,11 @@ class Sale(metaclass=PoolMeta): 'Sale' __name__ = 'sale.sale' - """ + agended = fields.Boolean("Scheduling") + sale_type = fields.Selection([('maintenance', 'Maintenance'), + ('equipments', 'Equipos'), + ('replaces', 'Replaces')], "Sale Type", required=True) + @classmethod @ModelView.button @Workflow.transition('confirmed') @@ -26,31 +30,33 @@ class Sale(metaclass=PoolMeta): def confirm(cls, sales): pool = Pool() Configuration = pool.get('sale.configuration') + transaction = Transaction() + context = transaction.context cls.set_sale_date(sales) cls.store_cache(sales) config = Configuration(1) - pool = Pool() - Equipments = pool.get('optical_equipment.equipment') - + MaintenanceService = pool.get('optical_equipment.maintenance.service') for sale in sales: for line in sale.lines: - if line.equipment: - equipment=line.equipment - equipment.propietary=sale.party.id - equipment.propietary_address=sale.shipment_address.id - equipment.state="uncontrated" - equipment.sale_destination = line - equipment.maintenance_frequency = "6" if sale.party.client_type == "ips" else "12" - equipment.save() + maintenanceService = MaintenanceService( + maintenance_type='preventive', + state_agended='no_agenda', + propietary=cls.party, + propietary_address=cls.shipment_address, + state="draft" + ) + #raise UserError(str(dir(maintenanceService))) + maintenanceService.save() + cls.agended = True + sale.save() - with Transaction().set_context( - queue_name='sale', - queue_scheduled_at=config.sale_process_after): + with transaction.set_context( + queue_scheduled_at=config.sale_process_after, + queue_batch=context.get('queue_batch', True)): cls.__queue__.process(sales) - class SaleLine(metaclass=PoolMeta): 'SaleLine' __name__ = 'sale.line' @@ -69,11 +75,16 @@ class SaleLine(metaclass=PoolMeta): 'on_change_with_unit_digits') + @classmethod def __setup__(cls): super(SaleLine, cls).__setup__() cls.quantity.states['readonly'] = If(Eval('product_equipment') == True, True) - + #raise UserError(str(Eval('_parent_sale', {}).get('sale_type'))) + if Eval('_parent_sale', {}).get('sale_type') == 'maintenance': + cls.product.domain + [('type', '=', 'service'), + ('maintenance_activity', '=', True)] + @fields.depends('product_equipment','equipment') def get_serial_equipment(self): if self.product_equipment: @@ -239,103 +250,3 @@ class SaleLine(metaclass=PoolMeta): ('//page[@id="equipment"]', 'states', { 'invisible': ~Eval('product_equipment', True), })] - - - -class CreateSubscriptionStart(ModelView): - 'Create Subscription Start' - __name__ = 'sale.create.subscription.start' - - start_date = fields.Date("Start Date", required=True) - end_date = fields.Date("End Date", required=True) - invoice_recurrence = fields.Many2One('sale.subscription.recurrence.rule.set', - "Invoice Recurrence",required=True) - invoice_start_date = fields.Date("Invoice Start Date", - help='Billing start date') - service = fields.Many2One('sale.subscription.service', "Service") - quantity = fields.Float("Quantity", digits='unit') - unit_price = Monetary("Unit Price", currency='currency', - digits=price_digits, - ) - - @classmethod - def default_start_date(cls): - pool = Pool() - Date = pool.get('ir.date') - return Date.today() - - @classmethod - @fields.depends(methods=['default_start_date']) - def default_invoice_start_date(self): - invoice_start_date = self.default_start_date() - - return invoice_start_date - -class CreateSubscription(Wizard): - 'Create Subscription' - __name__ = 'sale.create.subscription' - - start = StateView('sale.create.subscription.start', - 'optical_equipment.create_subscription_view_form',[ - Button('Cancel', 'end', 'tryton-cancel'), - Button('Create', 'create_subscription', 'tryton-ok', default=True), - ]) - create_subscription = StateAction('sale_subscription.act_subscription_form') - - done_ = StateView('sale.create.subscription.start', - 'optical_equipment.create_subscription_view_form',[ - Button('Done', 'end', 'tryton-cancel'), - ]) - @property - def _subscription_start(self): - return dict(start_date=self.start.start_date, - end_date=self.start.end_date, - invoice_recurrence=self.start.invoice_recurrence, - invoice_start_date=self.start.invoice_start_date, - service=self.start.service, - quantity=self.start.quantity, - unit_price=self.start.unit_price) - - def _equipments_to_subscription(self): - sale = self.records[0] - equipments_to_subscription = [] - for line in sale.lines: - if line.product_equipment: - equipments_to_subscription.append(line.equipment) - - return equipments_to_subscription - - def do_create_subscription(self, action): - pool = Pool() - Subscription = pool.get('sale.subscription') - SubscriptionLine = pool.get('sale.subscription.line') - - sale = self.records[0] - a = self._subscription_start - - equipments_to_subscription=self._equipments_to_subscription() - subscription_lines = [SubscriptionLine( - start_date=a['start_date'], - end_date=a['end_date'], - consumption_recurrence=a['invoice_recurrence'], - service=a['service'], - unit=a['service'].product.default_uom, - quantity=a['quantity'], - unit_price=a['unit_price'] - )] - - subscription = Subscription( - start_date=a['start_date'], - end_date=a['end_date'], - invoice_recurrence=a['invoice_recurrence'], - invoice_start_date=a['invoice_start_date'], - party=sale.party.id, - contact=sale.contact.id if sale.contact else None, - invoice_party=sale.invoice_party.id if sale.invoice_party else None, - invoice_address=sale.invoice_address.id, - payment_term=sale.payment_term.id if sale.payment_term else None, - lines=subscription_lines, - equipments=equipments_to_subscription, - ) - subscription.save() - """ diff --git a/sale.xml b/sale.xml index 4d0606e..94b2427 100644 --- a/sale.xml +++ b/sale.xml @@ -1,7 +1,11 @@ - + --> diff --git a/subscription.py b/subscription.py index c340c00..29d1d3c 100644 --- a/subscription.py +++ b/subscription.py @@ -75,7 +75,13 @@ class Contract(ModelSQL, ModelView): ('state', '=', 'uncontrated')] ]) - + @classmethod + def __setup__(cls): + super(Contract, cls).__setup__() + cls._buttons.update({ + 'quotation': {'invisible': Eval('state').in_(['quotation', 'running', 'closed', 'cancelled'])}, + 'run': {'invisible': Eval('state').in_(['draft', 'running', 'closed', 'cancelled'])} + }) @staticmethod def default_company(): @@ -85,18 +91,59 @@ class Contract(ModelSQL, ModelView): def default_state(): return 'draft' - # @classmethod - # @ModelView.button - # def run(cls, subscription): - # for equipment in cls.equipments: - # if equipment.state == "contrated": - # #aise UserError(str("El equipo"+str(equipment.number) - # # +"No puede pertencer a este contrato porque - # # ya se encuentra en un contrato")) - # else: - # continue - - + @classmethod + @ModelView.button + def quotation(self, contract): + #raise UserError(str(self)) + pool = Pool() + Subscription = pool.get('sale.subscription') + #raise UserError(str((subscription[0].equipments))) + for equipment in contract[0].equipments: + if equipment.state == "contrated": + raise UserError(str("El equipo"+str(equipment.number) + + "No puede pertencer a este contrato porque ya se encuentra en un contrato")) + else: + continue + + #raise UserError(str((contract[0].prorogues))) + if contract[0].contract and contract[0].prorogues == (): + #raise UserError(str(contract[0].contract)) + Subscription.quote([contract[0].contract]) + Subscription.run([contract[0].contract]) + else: + IdProrogues = set() + for ide in contract[0].prorogues: + IdProrogues.add(ide.id) + + subscription = Subscription.search([('state', '=', 'draft'), + ('id', 'in', IdProrogues)]) + + raise UserError(str(subscription)) + #raise UserError(str(list(contract[0].prorogues))) + raise UserError(str(list(contract[0].prorogues).find(['state', '=', 'draft']))) + + + @classmethod + @ModelView.button + def run(cls, subscription): + pool = Pool() + Subscription = pool.get('sale.subscription') + + if subscription.state == 'quotation': + Subscription.run(subscription) + elif subscription.state == 'draft': + for equipment in cls.equipments: + if equipment.state == "contrated": + raise UserError(str("El equipo"+str(equipment.number) + + "No puede pertencer a este contrato porque ya se encuentra en un contrato")) + else: + continue + + Subscription.quotation(subscription) + Subscription.run(subscription) + + Subscription.quotation(subscription) + class CreateInitialContract(ModelView): 'Create Initial Contract' @@ -142,7 +189,8 @@ class CreateInitialContract(ModelView): 'equipment', "Equipments", required=True, domain=[['OR', ('state', '=', 'registred'), - ('state', '=', 'uncontrated')] + ('state', '=', 'uncontrated')], + ('propietary', '=', Eval('party')) ]) @staticmethod @@ -276,10 +324,13 @@ class CreateNextProrogue(ModelView): __name__ = 'optical_equipment_prorogue.next' party = fields.Many2One('party.party', "Party", required=True, - domain=[('party', '=', Eval('party'))], help="The party who subscribes.") - initial_contract = fields.Many2One('optical_equipment.contract', "Initial Contract") - contact = fields.Many2One('party.contact_mechanism', "Contact") + initial_contract = fields.Many2One('optical_equipment.contract', "Initial Contract", required=True, + domain=[('party', '=', Eval('party')), + ('state', '=', "closed")], + depends=['party']) + contact = fields.Many2One('party.contact_mechanism', "Contact", required=True, + domain=[('party', '=', Eval('party'))]) invoice_address = fields.Many2One('party.address', 'Invoice Address', required=True, domain=[('party', '=', Eval('party'))]) invoice_recurrence = fields.Many2One('sale.subscription.recurrence.rule.set', "Invoice Recurrence", @@ -294,9 +345,11 @@ class CreateNextProrogue(ModelView): Eval('start_date', datetime.date.min), datetime.date.min)), ('end_date', '=', None), - ]) + ], + depends=['invoice_start_date']) invoice_start_date = fields.Date("Invoice Start Date", required=True, - help='Billing start date') + help='Billing start date', + depends=['start_date']) service = fields.Many2One('sale.subscription.service', "Service", required=True) quantity = fields.Float("Quantity", digits='unit', required=True) unit_price = Monetary("Unit Price", currency='currency', @@ -306,9 +359,16 @@ class CreateNextProrogue(ModelView): 'equipment', "Equipments", required=True, domain=[['OR', ('state', '=', 'registred'), - ('state', '=', 'uncontrated')] + ('state', '=', 'uncontrated')], + ('propietary', '=', Eval('party')) ]) + + @fields.depends('party', 'contact') + def on_change_party(self): + self.contact = None + self.initial_contract = None + @fields.depends('initial_contract', 'party', 'contact', 'invoice_address', 'invoice_recurrence', 'start_date', 'end_date', 'equipments') @@ -318,8 +378,8 @@ class CreateNextProrogue(ModelView): self.party = contract.party.id self.contact = contract.contact.id self.invoice_address = contract.invoice_address.id - self.invoice_recurrence = contract.invoice_recurrence.id self.start_date = contract.end_date + self.invoice_start_date = contract.end_date self.equipments = contract.equipments else: self.party = None @@ -329,7 +389,25 @@ class CreateNextProrogue(ModelView): self.start_date = None self.equipments = [] - + @fields.depends('invoice_recurrence', 'start_date') + def on_change_invoice_recurrence(self): + if self.invoice_recurrence and self.invoice_recurrence.rules[0].freq == "yearly": + #pool = Pool() + #Date = pool.get('ir.date') + self.end_date = self.start_date + timedelta(days=365) + #self.end_date = Date.today() + timedelta(days=365) + elif self.invoice_recurrence == None: + self.end_date = None + + + @fields.depends('invoice_start_date', 'start_date') + def on_change_start_date(self): + self.invoice_start_date = self.start_date + + @classmethod + def default_quantity(self): + return 1 + class CreateProrogue(Wizard): 'Create Prorogue' __name__ = 'optical_equipment.prorogue' diff --git a/subscription.xml b/subscription.xml index f0d33f5..c756dcc 100644 --- a/subscription.xml +++ b/subscription.xml @@ -51,6 +51,13 @@ + + Closed + + + + All @@ -113,6 +120,19 @@ run + + Closed + + + + + + quotation + Quotation + Are you sure you want to quote these subscription? + +