From a343766dda61ac78238d995c2b46b6ccc7dde9e8 Mon Sep 17 00:00:00 2001 From: Stepan Savelyev Date: Tue, 12 Nov 2019 16:16:14 +0500 Subject: [PATCH 001/121] [REFACTOR] cleanup and todos --- __init__.py | 2 - __manifest__.py | 21 +- controllers/__init__.py | 2 - demo/demo.xml | 30 --- models/__init__.py | 7 +- models/contract_wizard.py | 347 ++++++++++++++++++++++----------- models/models.py | 118 ----------- models/res_partner.py | 64 ++++++ models/res_partner_contract.py | 85 ++++++++ models/sale_order.py | 11 ++ views/contract_wizard.xml | 6 +- views/res_partner.xml | 2 +- views/templates.xml | 2 +- 13 files changed, 409 insertions(+), 288 deletions(-) delete mode 100644 demo/demo.xml delete mode 100644 models/models.py create mode 100644 models/res_partner.py create mode 100644 models/res_partner_contract.py create mode 100644 models/sale_order.py diff --git a/__init__.py b/__init__.py index aa4d0fd..91c5580 100644 --- a/__init__.py +++ b/__init__.py @@ -1,4 +1,2 @@ -# -*- coding: utf-8 -*- - from . import controllers from . import models diff --git a/__manifest__.py b/__manifest__.py index 573b7c5..923c6fa 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -3,7 +3,7 @@ 'name': "client_contracts", 'summary': """ - Module for storing and creating print forms for contracts with clients""", + Print forms for contracts with clients""", 'description': """ Module for storing and creating print forms for contracts with clients @@ -12,24 +12,19 @@ 'author': "RYDLAB", 'website': "http://rydlab.ru", - # Categories can be used to filter modules in modules listing - # Check https://github.com/odoo/odoo/blob/master/odoo/addons/base/module/module_data.xml - # for the full list - 'category': 'hr', - 'version': '0.1', + 'category': 'Invoicing & Payments', + 'version': '0.1.1', - # any module necessary for this one to work correctly - 'depends': ['base', 'sale'], + 'depends': [ + 'base', + 'contacts', + 'sale' + ], - # always loaded 'data': [ # 'security/ir.model.access.csv', 'views/templates.xml', 'views/res_partner.xml', 'views/contract_wizard.xml', ], - # only loaded in demonstration mode - 'demo': [ - 'demo/demo.xml', - ], } diff --git a/controllers/__init__.py b/controllers/__init__.py index b0f26a9..e046e49 100644 --- a/controllers/__init__.py +++ b/controllers/__init__.py @@ -1,3 +1 @@ -# -*- coding: utf-8 -*- - from . import controllers diff --git a/demo/demo.xml b/demo/demo.xml deleted file mode 100644 index 41cfe8a..0000000 --- a/demo/demo.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/models/__init__.py b/models/__init__.py index 57f6dd7..5f8738b 100644 --- a/models/__init__.py +++ b/models/__init__.py @@ -1,3 +1,6 @@ -# -*- coding: utf-8 -*- +from . import contract_wizard +from . import res_partner +from . import res_partner_contract +from . import sale_order -from . import models, contract_wizard +# TODO: rename all fields ilike 'adress' -> 'address' diff --git a/models/contract_wizard.py b/models/contract_wizard.py index d355b91..a39d84e 100644 --- a/models/contract_wizard.py +++ b/models/contract_wizard.py @@ -10,22 +10,13 @@ from odoo import models, fields, api from odoo.tools.config import config -class AnnexLine(models.TransientModel): - _name = 'res.partner.contract.annex.line' - - @api.onchange('annex_type') - def _get_default_description(self): - self.description = self.annex_type.description - - annex_type = fields.Many2one('res.partner.contract.annex.type') - description = fields.Text() - - class ContractWizard(models.TransientModel): _name = 'res.partner.contract.wizard' + # TODO: Move _get_default_+ method down def _get_default_template(self): - _template = self.env['res.partner.contract.template'].search([('is_contract_template', '=', True)]) + _template = self.env['res.partner.contract.template'].search( + [('is_contract_template', '=', True)]) if _template: return _template[0].id else: @@ -42,38 +33,210 @@ class ContractWizard(models.TransientModel): def _get_partner_representer(self): return self.partner_id.representative_id - type = fields.Selection(string='Type of contract', - selection=[('person', 'With person'), ('company', 'With company')], - default='company') + _context_name = fields.Char( + string='Contract number', compute='_compute_context_name', readonly=True + ) + _context_date = fields.Char( + string='Contract date', compute='_compute_context_date', readonly=True + ) + _context_partner_contract_name = fields.Char( + string='Partner contract name', + compute='_compute_context_partner_contract_name', readonly=True + ) + _context_partner_adress = fields.Char( + compute='_compute_context_partner_adress', readonly=True + ) + _context_partner_representer_contract_name = fields.Char( + string='partner representer contract name', + compute='_compute_context_partner_representer_contract_name', readonly=True + ) + _context_partner_inn = fields.Char( + string='Partner inn', compute='_compute_context_partner_inn', readonly=True + ) + _context_partner_kpp = fields.Char( + string='Partner kpp', compute='_compute_context_partner_kpp', readonly=True + ) + _context_partner_rs = fields.Char( + string='Partner corresponding account', + compute='_compute_context_partner_rs', + readonly=True + ) + _context_partner_bik = fields.Char( + string='Partner bank bik', + compute='_compute_context_partner_bik', + readonly=True + ) + _context_partner_bank = fields.Char( + string='Partner bank name', + compute='_compute_context_partner_bank', + readonly=True + ) + _context_partner_phone = fields.Char( + string='Partner phone', + compute='_compute_context_partner_phone', + readonly=True + ) + _context_partner_representer_name = fields.Char( + string='Partner representer name', + compute='_compute_context_partner_representer_name', + readonly=True + ) + _context_seller_contract_name = fields.Char( + string='Seller contract name', + compute='_compute_context_seller_contract_name', + readonly=True + ) + _context_seller_adress = fields.Char( + string='Seller full adress', + compute='_compute_context_seller_adress', + readonly=True + ) + _context_seller_representer_contract_job_name = fields.Char( + string='Seller representer contract job name', + compute='_compute_context_seller_representer_contract_job_name', + readonly=True + ) + _context_seller_representer_contract_name = fields.Char( + string='Seller representer contract name', + compute='_compute_context_seller_representer_contract_name', + readonly=True + ) + _context_seller_inn = fields.Char( + string='Seller inn', + compute='_compute_context_seller_inn', + readonly=True + ) + _context_seller_kpp = fields.Char( + string='Seller kpp', + compute='_compute_context_seller_kpp', + readonly=True + ) + _context_seller_rs = fields.Char( + string='Seller corresponding account', + compute='_compute_context_seller_rs', + readonly=True + ) + _context_seller_bik = fields.Char( + string='Seller bank bik', + compute='_compute_context_seller_bik', + readonly=True + ) + _context_seller_bank = fields.Char( + string='Seller bank name', + compute='_compute_context_seller_bank', + readonly=True + ) + _context_seller_phone = fields.Char( + string='Seller phone', + compute='_compute_context_seller_phone', + readonly=True + ) + _context_seller_representer_job_name = fields.Char( + string='Seller representer job name', + compute='_compute_context_seller_representer_job_name', + readonly=True + ) + _context_seller_representer_name = fields.Char( + string='Seller representer name', + compute='_compute_context_seller_representer_name', + readonly=True + ) + _context_summ_rub = fields.Char( + string='Contract summ(rub)', + compute='_compute_context_summ_rub', + readonly=True + ) + _context_summ_rub_word = fields.Char( + string='Contract summ(rub), word', + compute='_compute_context_summ_rub_word', + readonly=True + ) + _context_summ_kop = fields.Char( + string='Contract summ(kop)', + compute='_compute_context_summ_kop', + readonly=True + ) + _context_summ_word = fields.Char( + string='Contract summ word', + compute='_compute_context_summ_word', + readonly=True + ) + _context_delivery_term = fields.Char( + string='Contract delivery term', + compute='_compute_context_delivery_term', + readonly=True + ) + _context_delivery_term_word = fields.Char( + string='Contract delivery term word', + compute='_compute_context_delivery_term_word', + readonly=True + ) + _context_payment_term = fields.Char( + string='Contract payment term', + compute='_compute_context_payment_term', readonly=True + ) + _context_payment_term_word = fields.Char( + string='Contract payment term word', + compute='_compute_context_payment_term_word', readonly=True + ) + _context_partner_passport_data = fields.Char( + string='Partner passport data', + compute='_compute_partner_passport_data', + readonly=True + ) - template = fields.Many2one('res.partner.contract.template', - string='Template', - help='Template for contract', - default=_get_default_template) - partner_id = fields.Many2one('res.partner', - string='Partner', - help='Partner to render contract', - default=_get_default_partner) - order_id = fields.Many2one('sale.order', - string='Appex order', - help='Appex', - ) - company_id = fields.Many2one('res.partner', - string='Company', - help='Seller company', - default=lambda self: self.env.user.company_id.partner_id) - - contract_id = fields.Many2one('res.partner.contract', - string='Contract', - default=_get_default_contract) - payment_terms = fields.Integer(string='Payment term', - help='When customer must pay', - default=45) - delivery_terms = fields.Integer(string='Delivery terms', - help='When product must be delivered', - default=10) - - annex_lines = fields.One2many('res.partner.contract.annex.line', 'id', auto_join=True, copy=True) + annex_lines = fields.One2many( + 'res.partner.contract.annex.line', + 'id', + auto_join=True, + copy=True + ) + company_id = fields.Many2one( + 'res.partner', + string='Company', + help='Seller company', + default=lambda self: self.env.user.company_id.partner_id + ) + contract_id = fields.Many2one( + 'res.partner.contract', + string='Contract', + default=_get_default_contract + ) + delivery_terms = fields.Integer( + string='Delivery terms', + help='When product must be delivered', + default=10 + ) + order_id = fields.Many2one( + 'sale.order', + string='Appex order', + help='Appex', + ) + partner_id = fields.Many2one( + 'res.partner', + string='Partner', + help='Partner to render contract', + default=_get_default_partner + ) + payment_terms = fields.Integer( + string='Payment term', + help='When customer must pay', + default=45 + ) + template = fields.Many2one( + 'res.partner.contract.template', + string='Template', + help='Template for contract', + default=_get_default_template + ) + type = fields.Selection( + selection=[ + ('person', 'With person'), + ('company', 'With company') + ], + string='Type of contract', + default='company' + ) @api.depends('contract_id') def _compute_context_name(self): @@ -94,6 +257,7 @@ class ContractWizard(models.TransientModel): @api.depends('partner_id') def _compute_context_partner_representer_contract_name(self): + # TODO: lite refactor if self.partner_id.representative_id: partner_representer_contract_name = self.partner_id.representative_id.contract_name else: @@ -138,6 +302,7 @@ class ContractWizard(models.TransientModel): @api.depends('company_id') def _compute_context_seller_representer_contract_job_name(self): + # TODO: lite refactor if self.company_id.representative_id: seller_represent_contract_job_name = self.company_id.representative_id.contract_job_name else: @@ -146,6 +311,7 @@ class ContractWizard(models.TransientModel): @api.depends('company_id') def _compute_context_seller_representer_contract_name(self): + # TODO: lite refactor if self.company_id.representative_id: seller_represent_contract_name = self.company_id.representative_id.contract_name else: @@ -178,6 +344,7 @@ class ContractWizard(models.TransientModel): @api.depends('company_id') def _compute_context_seller_representer_job_name(self): + # TODO: lite refactor if self.company_id.representative_id: seller_represent_job_name = self.company_id.representative_id.function else: @@ -186,6 +353,7 @@ class ContractWizard(models.TransientModel): @api.depends('company_id') def _compute_context_seller_representer_name(self): + # TODO: lite refactor if self.company_id.representative_id: seller_represent_name = self.company_id.representative_id.name else: @@ -194,6 +362,7 @@ class ContractWizard(models.TransientModel): @api.depends('order_id') def _compute_context_summ_rub(self): + # TODO: lite refactor if self.order_id: amount = math.modf(self.order_id.amount_total) else: @@ -202,6 +371,7 @@ class ContractWizard(models.TransientModel): @api.depends('order_id') def _compute_context_summ_rub_word(self): + # TODO: lite refactor if self.order_id: amount = math.modf(self.order_id.amount_total) else: @@ -210,6 +380,7 @@ class ContractWizard(models.TransientModel): @api.depends('order_id') def _compute_context_summ_kop(self): + # TODO: lite refactor if self.order_id: amount = math.modf(self.order_id.amount_total) self._context_summ_kop = str(int(amount[0])) @@ -226,7 +397,8 @@ class ContractWizard(models.TransientModel): @api.depends('delivery_terms') def _compute_context_delivery_term_word(self): - self._context_delivery_term_word = numeral.in_words(self.delivery_terms) + self._context_delivery_term_word = numeral.in_words( + self.delivery_terms) @api.depends('payment_terms') def _compute_context_payment_term(self): @@ -236,74 +408,6 @@ class ContractWizard(models.TransientModel): def _compute_context_payment_term_word(self): self._context_payment_term_word = numeral.in_words(self.payment_terms) - _context_name = fields.Char(string='Contract number', compute='_compute_context_name', readonly=True) - _context_date = fields.Char(string='Contract date', compute='_compute_context_date', readonly=True) - _context_partner_contract_name = fields.Char(string='Partner contract name', - compute='_compute_context_partner_contract_name', readonly=True) - _context_partner_adress = fields.Char(compute='_compute_context_partner_adress', readonly=True) - _context_partner_representer_contract_name = fields.Char(string='partner representer contract name', - compute='_compute_context_partner_representer_contract_name', readonly=True) - _context_partner_inn = fields.Char(string='Partner inn', compute='_compute_context_partner_inn', readonly=True) - _context_partner_kpp = fields.Char(string='Partner kpp', compute='_compute_context_partner_kpp', readonly=True) - _context_partner_rs = fields.Char(string='Partner corresponding account', - compute='_compute_context_partner_rs', - readonly=True) - _context_partner_bik = fields.Char(string='Partner bank bik', - compute='_compute_context_partner_bik', - readonly=True) - _context_partner_bank = fields.Char(string='Partner bank name', - compute='_compute_context_partner_bank', - readonly=True) - _context_partner_phone = fields.Char(string='Partner phone', - compute='_compute_context_partner_phone', - readonly=True) - _context_partner_representer_name = fields.Char(string='Partner representer name', - compute='_compute_context_partner_representer_name', - readonly=True) - _context_seller_contract_name = fields.Char(string='Seller contract name', - compute='_compute_context_seller_contract_name', - readonly=True) - _context_seller_adress = fields.Char(string='Seller full adress', - compute='_compute_context_seller_adress', - readonly=True) - _context_seller_representer_contract_job_name = fields.Char(string='Seller representer contract job name', - compute='_compute_context_seller_representer_contract_job_name', readonly=True) - _context_seller_representer_contract_name = fields.Char(string='Seller representer contract name', - compute='_compute_context_seller_representer_contract_name', - readonly=True) - _context_seller_inn = fields.Char(string='Seller inn', compute='_compute_context_seller_inn', readonly=True) - _context_seller_kpp = fields.Char(string='Seller kpp', compute='_compute_context_seller_kpp', readonly=True) - _context_seller_rs = fields.Char(string='Seller corresponding account', - compute='_compute_context_seller_rs', - readonly=True) - _context_seller_bik = fields.Char(string='Seller bank bik', compute='_compute_context_seller_bik', readonly=True) - _context_seller_bank = fields.Char(string='Seller bank name', compute='_compute_context_seller_bank', readonly=True) - _context_seller_phone = fields.Char(string='Seller phone', compute='_compute_context_seller_phone', readonly=True) - _context_seller_representer_job_name = fields.Char(string='Seller representer job name', - compute='_compute_context_seller_representer_job_name', - readonly=True) - _context_seller_representer_name = fields.Char(string='Seller representer name', - compute='_compute_context_seller_representer_name', readonly=True) - _context_summ_rub = fields.Char(string='Contract summ(rub)', compute='_compute_context_summ_rub', readonly=True) - _context_summ_rub_word = fields.Char(string='Contract summ(rub), word', - compute='_compute_context_summ_rub_word', - readonly=True) - _context_summ_kop = fields.Char(string='Contract summ(kop)', compute='_compute_context_summ_kop', readonly=True) - _context_summ_word = fields.Char(string='Contract summ word', compute='_compute_context_summ_word', readonly=True) - _context_delivery_term = fields.Char(string='Contract delivery term', - compute='_compute_context_delivery_term', - readonly=True) - _context_delivery_term_word = fields.Char(string='Contract delivery term word', - compute='_compute_context_delivery_term_word', - readonly=True) - _context_payment_term = fields.Char(string='Contract payment term', - compute='_compute_context_payment_term', readonly=True) - _context_payment_term_word = fields.Char(string='Contract payment term word', - compute='_compute_context_payment_term_word', readonly=True) - _context_partner_passport_data = fields.Char(string='Partner passport data', - compute='_compute_partner_passport_data', - readonly=True) - @api.onchange('partner_id') def _compute_partner_passport_data(self): return self.partner_id.passport_data @@ -349,7 +453,8 @@ class ContractWizard(models.TransientModel): annex_terms = '' counter = 1 for line in self.annex_lines: - annex_terms = annex_terms + '{}) {}\n'.format(counter, line.description) + annex_terms = annex_terms + \ + '{}) {}\n'.format(counter, line.description) counter += 1 context = {'name': self.contract_id.name, 'current_date': contract_date.strftime('%d %b %Y'), @@ -392,7 +497,8 @@ class ContractWizard(models.TransientModel): odoo_data_dir = config.get("data_dir") odoo_bd = config.get("db_name") filename = self.template.store_fname - full_path = '{}/filestore/{}/{}'.format(odoo_data_dir, odoo_bd, filename) + full_path = '{}/filestore/{}/{}'.format( + odoo_data_dir, odoo_bd, filename) context = self._generate_context() doc = DocxTemplate(full_path) doc.render(context) @@ -406,3 +512,16 @@ class ContractWizard(models.TransientModel): self.contract_id.name), 'target': 'self', } + + +class AnnexLine(models.TransientModel): + _name = 'res.partner.contract.annex.line' + + @api.onchange('annex_type') + def _get_default_description(self): + self.description = self.annex_type.description + + annex_type = fields.Many2one( + 'res.partner.contract.annex.type' + ) + description = fields.Text() diff --git a/models/models.py b/models/models.py deleted file mode 100644 index cb10295..0000000 --- a/models/models.py +++ /dev/null @@ -1,118 +0,0 @@ -# -*- coding: utf-8 -*- - -from datetime import datetime - -from odoo import models, fields, api - - -class PartnerContract(models.Model): - - _name = 'res.partner.contract' - - name = fields.Char( - string='Contract number', - help='Number of contract, letters and digits',) - date = fields.Date( - string='Date of conclusion', - help='Date, when contract was concluded', - default=datetime.now().date(), - required=True) - partner_id = fields.Many2one( - 'res.partner', - string='Contract Partner', - help='Contract partner', - default=lambda self: self.env.context['active_id'], - required=True) - order_ids = fields.One2many( - 'sale.order', - 'contract_id', - string='Annexes', - help='Annexes to this contract') - - def _calculate_contract_name(self, _date): - contract_date = datetime.strptime(_date, '%Y-%m-%d') - date_part = contract_date.strftime('%d%m-%y') - today_contracts = self.search([('date', '=', contract_date.date())]) - if len(today_contracts) > 0: - last_contract_number = int(today_contracts[-1].name.split('-')[2]) + 1 - else: - last_contract_number = 1 - return '{}-{}'.format(date_part, last_contract_number) - - @api.onchange('date') - def _change_contract_name(self): - """ - Procedure for forming contract name - :return: contract name in format "DDMM-YY-№" - """ - - self.name = self._calculate_contract_name(self.date) - - @api.model - def create(self, vals): - datetime_now = datetime.now().strftime("%Y-%m-%d") - vals['name'] = self._calculate_contract_name(datetime_now) - return super(PartnerContract, self).create(vals) - - -class AnnexType(models.Model): - - _name = 'res.partner.contract.annex.type' - - name = fields.Char(string='Annex template name') - description = fields.Text(string='Annex template description') - - -class ResPartner(models.Model): - - _inherit = 'res.partner' - - client_contract_ids = fields.One2many( - 'res.partner.contract', - 'partner_id', - string='Contracts', - help='Contracts for this partner') - contract_count = fields.Integer( - compute='_compute_contract_count', - string='# of contracts') - contract_name = fields.Char(string='Contract name', help='Name, as it would be in contract') - contract_job_name = fields.Char(string='Contract job name', help='Job position as it would be in contract') - representative_id = fields.Many2one('res.partner', string='Representative', help='Person, who represents company') - passport_data = fields.Char(string='Passport', help='Passport data') - full_adress = fields.Char(compute='_compute_full_adress') - bank_account = fields.Many2one('res.partner.bank', string='Bank account') - signature = fields.Binary(string='Client signature') - - @api.one - @api.depends('street', 'street2', 'city', 'state_id', 'zip', 'country_id') - def _compute_full_adress(self): - if self.zip: - full_adress = '{}, {}, {}, {} {}'.format(self.zip, self.country_id.name, self.city, self.street, - self.street2) - else: - full_adress = '{}, {}, {} {}'.format(self.country_id.name, self.city, self.street, - self.street2) - self.full_adress = full_adress - - @api.one - @api.depends('self.client_contract_ids') - def _compute_contract_count(self): - self.contract_count = len(self.client_contract_ids) - - -class SaleOrder(models.Model): - - _inherit = 'sale.order' - - contract_id = fields.Many2one( - 'res.partner.contract', - string='Contract', - help='Contract, assigned to this order') - - -class ContractTemplate(models.Model): - - _name = 'res.partner.contract.template' - _inherit = 'ir.attachment' - - is_contract_template = fields.Boolean(srting='Is this document contract template?', default=True) diff --git a/models/res_partner.py b/models/res_partner.py new file mode 100644 index 0000000..20b6b5e --- /dev/null +++ b/models/res_partner.py @@ -0,0 +1,64 @@ +from odoo import api, fields, models + + +class ResPartner(models.Model): + _inherit = 'res.partner' + + bank_account = fields.Many2one( + 'res.partner.bank', + string='Bank account' + ) + client_contract_ids = fields.One2many( + 'res.partner.contract', + 'partner_id', + string='Contracts', + help='Contracts for this partner' + ) + contract_count = fields.Integer( + compute='_compute_contract_count', + string='# of contracts' + ) + contract_job_name = fields.Char( + string='Contract job name', + help='Job position as it would be in contract' + ) + contract_name = fields.Char( + string='Contract name', + help='Name, as it would be in contract' + ) + full_adress = fields.Char( + compute='_compute_full_adress' + ) + passport_data = fields.Char( + string='Passport', + help='Passport data' + ) + representative_id = fields.Many2one( + 'res.partner', + string='Representative', + help='Person, who represents company' + ) + signature = fields.Binary( + string='Client signature' + ) + + @api.one + @api.depends('street', 'street2', 'city', 'state_id', 'zip', 'country_id') + def _compute_full_adress(self): + # TODO: lite rewrite + if self.zip: + full_adress = '{}, {}, {}, {} {}'.format( + self.zip, self.country_id.name, self.city, + self.street, self.street2 + ) + else: + full_adress = '{}, {}, {} {}'.format( + self.country_id.name, self.city, + self.street, self.street2 + ) + self.full_adress = full_adress + + @api.one + @api.depends('self.client_contract_ids') + def _compute_contract_count(self): + self.contract_count = len(self.client_contract_ids) diff --git a/models/res_partner_contract.py b/models/res_partner_contract.py new file mode 100644 index 0000000..896aac0 --- /dev/null +++ b/models/res_partner_contract.py @@ -0,0 +1,85 @@ +from datetime import datetime + +from odoo import api, fields, models + + +class PartnerContract(models.Model): + + _name = 'res.partner.contract' + + name = fields.Char( + string='Contract number', + help='Number of contract, letters and digits', + ) + date = fields.Date( + string='Date of conclusion', + help='Date, when contract was concluded', + default=datetime.now().date(), + required=True + ) + order_ids = fields.One2many( + 'sale.order', + 'contract_id', + string='Annexes', + help='Annexes to this contract' + ) + partner_id = fields.Many2one( + 'res.partner', + string='Contract Partner', + help='Contract partner', + default=lambda self: self.env.context['active_id'], + required=True + ) + + @api.onchange('date') + def _change_contract_name(self): + """ + Procedure for forming contract name + :return: contract name in format "DDMM-YY-№" + """ + self.name = self._calculate_contract_name(self.date) + + @api.model + def create(self, vals): + + datetime_now = datetime.now().strftime("%Y-%m-%d") + vals['name'] = self._calculate_contract_name(datetime_now) + + return super(PartnerContract, self).create(vals) + + def _calculate_contract_name(self, _date): + + contract_date = datetime.strptime(_date, '%Y-%m-%d') + date_part = contract_date.strftime('%d%m-%y') + + today_contracts = self.search([ + ('date', '=', contract_date.date()), + ]) + if len(today_contracts) > 0: + last_contract_number = int( + today_contracts[-1].name.split('-')[2]) + 1 + else: + last_contract_number = 1 + + return '{}-{}'.format(date_part, last_contract_number) + + +class AnnexType(models.Model): + _name = 'res.partner.contract.annex.type' + + name = fields.Char( + string='Annex template name' + ) + description = fields.Text( + string='Annex template description' + ) + + +class ContractTemplate(models.Model): + _name = 'res.partner.contract.template' + _inherit = 'ir.attachment' + + is_contract_template = fields.Boolean( + srting='Is this document contract template?', + default=True + ) # TODO: srting -> string diff --git a/models/sale_order.py b/models/sale_order.py new file mode 100644 index 0000000..f9be364 --- /dev/null +++ b/models/sale_order.py @@ -0,0 +1,11 @@ +from odoo import fields, models + + +class SaleOrder(models.Model): + _inherit = 'sale.order' + + contract_id = fields.Many2one( + 'res.partner.contract', + string='Contract', + help='Contract, assigned to this order' + ) diff --git a/views/contract_wizard.xml b/views/contract_wizard.xml index f8a6a9d..3bcdb8b 100644 --- a/views/contract_wizard.xml +++ b/views/contract_wizard.xml @@ -1,4 +1,4 @@ - + - - - - \ No newline at end of file diff --git a/views/res_partner.xml b/views/res_partner.xml index 6652c6d..96cb8d4 100644 --- a/views/res_partner.xml +++ b/views/res_partner.xml @@ -1,4 +1,4 @@ - + diff --git a/views/templates.xml b/views/templates.xml index a89b022..e890c60 100644 --- a/views/templates.xml +++ b/views/templates.xml @@ -1,7 +1,7 @@ - +