1
0
forked from Rudoo/L10n_ru
L10n_ru/l10n_ru_contract/models/contract_customer.py
2025-01-17 20:45:47 +03:00

335 lines
15 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
from odoo import api, fields, models, exceptions, tools, _
import pymorphy2
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
from .crutch_fields_header import IP_CONTACT_HEADER, ENTITY_CONTRACT_HEADER, INDIVIDUAL_CONTRACT_HEADER
class PartnerContractCustomer(models.Model):
_name = 'partner.contract.customer'
_inherit = ['mail.thread', 'mail.activity.mixin', 'mail.render.mixin']
def get_dateend(self):
if self.date_start:
six_months = fields.Datetime.from_string(self.date_start) + relativedelta(months=+11)
else:
six_months = datetime.today() + relativedelta(months=+11)
return fields.Datetime.to_string(six_months)
name = fields.Char(string=_('Номер'))
date_start = fields.Date(string=_('Дата договора'), required=True, default=fields.Datetime.now())
partner_id = fields.Many2one('res.partner', string=_('Контрагент'), required=True)
sec_partner_id = fields.Many2one('res.partner', string=_('Контрагент как в заказе'))
company_id = fields.Many2one('res.company', string=_('Компания'), required=True)
name_print = fields.Char(string=_('Имя для печати'), compute='_get_name_print')
name_print1 = fields.Char(string=_('Имя для печати, И.П.'), compute='_get_name_printip')
date_end = fields.Date(string=_('Дата окончания'), required=True, default=get_dateend)
name_dirprint = fields.Char(string=_('Имя нашего директора для печати'))
name_dirprint1 = fields.Char(string=_('Имя нашего директора для печати И.П.'))
lines = fields.One2many('contract.line', 'contract_id', string=_('Договорные цены'))
type = fields.Selection(
[('customer', 'С покупателем'),
('supplier', 'С поставщиком'),
('other', 'Прочие расчеты'),
],
string=_('Тип договора'), default='customer', required=True)
saleorder_id = fields.Many2one('sale.order', string=_('Заказ/Сделка'))
stamp = fields.Boolean(string=_('Печать и подпись'))
signed = fields.Boolean(string=_('Договор подписан'))
state = fields.Selection(
[('draft', 'Черновик'),
('progress', 'На согласовании'),
('signed', 'Подписан, действует'),
('closed', 'Истёк'),
],
string=_('Статус'), default='draft', group_expand='_expand_states', index=True
)
is_template = fields.Boolean(_('Это шаблон'))
copy_from = fields.Many2one('partner.contract.customer', string=_('Копировать из этого шаблона'))
profile_id = fields.Many2one('contract.profile', string=_('Вид договора'), required=True)
credit_limit = fields.Float(string=_('Лимит кредита'))
guid_1s = fields.Char(_('Код договора из 1С'))
buh_code = fields.Char(_('Код договора из бухгалтерии'))
payment_term_id = fields.Many2one('account.payment.term', string=_('Условие оплаты'))
manager_id = fields.Many2one('res.users', string=_('Менеджер по продажам'))
accountant_id = fields.Many2one('res.users', string=_('Бухгалтер по взаиморасчетам'))
time_to_delivery_from = fields.Datetime(_('Время доставки от'))
time_to_delivery_to = fields.Datetime(_('Время доставки до'))
day_of_delivery = fields.Float(_('Дни доставки'))
day_of_otgruzki = fields.Float(_('Дни отгрузки'))
channel_id = fields.Many2one('saleorder.channel', string=_('Канал продаж'))
team_id = fields.Many2one('crm.team', string=_('Команда продаж'))
order_days_ids = fields.Many2many(comodel_name='contract.day', relation='orderdays', string=_('Дни доставки'),
column1='contract_id', column2='day_id')
shipment_days_ids = fields.Many2many(comodel_name='contract.day', relation='shipmentdays', string=_('Дни отгрузки'),
column1='contract_id',
column2='day_id')
# Доработка хедера договора
partner_type = fields.Selection(string=_('Тип контрагента'), selection=[
('person', 'Физ. лицо'),
('company_ip', 'ИП'),
('company', 'Юр. лицо')
], required=True)
contract_header = fields.Html(_('Шапка договора'))
@api.onchange('partner_type')
def generate_contract_header(self):
self.ensure_one()
self.render_model = 'partner.contract.customer'
if self.partner_type == 'company_ip':
self.contract_header = IP_CONTACT_HEADER
elif self.partner_type == 'person':
self.contract_header = INDIVIDUAL_CONTRACT_HEADER
else:
self.contract_header = ENTITY_CONTRACT_HEADER
# # Рендер Jinja выражение типа {{object.field}}
result = self._render_template(self.contract_header, self.render_model, res_ids=[self.id])
result = tools.html_sanitize(result[self.id])
self.contract_header = result
@api.onchange('sec_partner_id')
def set_pid(self):
self.partner_id = self.sec_partner_id.parent_id if self.sec_partner_id.parent_id else self.sec_partner_id
def _expand_states(self, states, domain):
return [key for key, val in type(self).state.selection]
def copy_it(self):
if self.copy_from:
for line in self.copy_from.lines:
line.copy({'contract_id': self.id})
def _get_name_print(self):
morph = pymorphy2.MorphAnalyzer()
self.name_print = False
director = self.env['res.partner'].search([('parent_id', '=', self.partner_id.id), ('type', '=', 'director')],
limit=1)
if director:
if len(director.name.split(' ')) == 3:
lastname_old, firstname_old, middlename_old = director.name.split(' ')
if lastname_old:
lastname_n = morph.parse(lastname_old)[0]
if lastname_n.inflect({'gent'}):
lastname_n = lastname_n.inflect({'gent'}).word
else:
lastname_n = lastname_old
else:
lastname_n = ''
if firstname_old:
firstname_n = morph.parse(firstname_old)[0]
firstname_n = firstname_n.inflect({'gent'}).word
else:
firstname_n = ''
if middlename_old:
middlename_n = morph.parse(middlename_old)[0]
middlename_n = middlename_n.inflect({'gent'}).word
else:
middlename_n = ''
name_print = lastname_n + ' ' + firstname_n + ' ' + middlename_n
self.name_print = name_print.title()
def _get_name_print1(self):
# morph = pymorphy2.MorphAnalyzer()
director = self.company_id.chief_id.partner_id if self.company_id.chief_id else False
# raise exceptions.UserError(str(director))
self.name_dirprint = False
if director:
if len(director.name.split(' ')) == 3:
lastname_old, firstname_old, middlename_old = director.name.split(' ')
if lastname_old:
lastname_n = morph.parse(lastname_old)[0]
lastname_n = lastname_n.inflect({'gent'}).word
else:
lastname_n = ''
if firstname_old:
firstname_n = morph.parse(firstname_old)[0]
firstname_n = firstname_n.inflect({'gent'}).word
else:
firstname_n = ''
if middlename_old:
middlename_n = morph.parse(middlename_old)[0]
middlename_n = middlename_n.inflect({'gent'}).word
else:
middlename_n = ''
name_print = lastname_n + ' ' + firstname_n + ' ' + middlename_n
self.name_dirprint = name_print.title()
@api.model
def create(self, values):
res = super(PartnerContractCustomer, self).create(values)
if values.get('is_template'):
return res
if values.get('type') == 'customer':
sequence_code = 'partner.contract.customer.sequence'
elif values.get('type') == 'supplier':
sequence_code = 'partner.contract.supplier.sequence'
else:
return res
name = self.env['ir.sequence'].next_by_code(sequence_code)
res.update({
'name': name,
})
return res
# @api.model
def write(self, values):
if 'state' in values:
if self.state != values['state']:
msg = 'Статус: ' + dict(self._fields['state'].selection).get(self.state) + ' -> ' + dict(
self._fields['state'].selection).get(values['state'])
self.message_post(body=msg)
res = super(PartnerContractCustomer, self).write(values)
return res
def _get_name_print1ip(self):
self.name_dirprint1 = self.company_id.chief_id.partner_id.name if self.company_id.chief_id else False
def _get_name_printip(self):
self.name_print1 = False
director = self.env['res.partner'].search([('parent_id', '=', self.partner_id.id), ('type', '=', 'director')],
limit=1)
if director:
self.name_print1 = director.name
def print_supp(self):
# self.filtered(lambda s: s.state == 'draft').write({'state': 'sent'})
return self.env['report'].get_action(self, 'mta_base.action_mtacontractsupp_report')
def print_contract_cust(self):
if self.saleorder_id:
return self.saleorder_id.print_contract()
else:
raise exceptions.UserError(_(
'Вы не можете напечатать договор с Клиентом, потому что нет связи с Заказом. Нужно зайти в Заказ и привязать этот договор.'))
def contract_action_confirm(self):
if self.state == 'draft':
self.state = 'progress'
elif self.state == 'progress':
self.state = 'signed'
def contract_in_draft(self):
self.state = 'draft'
@api.onchange('name')
def set_comp_and_partn(self):
context = self._context
order_id = context.get('sale_order_id')
if order_id:
sale_order = self.env['sale.order'].browse(order_id)
self.company_id = sale_order.company_id
self.partner_id = sale_order.partner_id
@api.onchange('profile_id')
def set_payment(self):
if self.profile_id.payment_term_id:
self.payment_term_id = self.profile_id.payment_term_id
# @api.constrains('name')
def check_name(self):
obj = self.search([('name', '=', self.name), ('id', '!=', self.id), ('state', '!=', 'closed')])
if obj:
raise exceptions.ValidationError(_('Договор с таким номером уже существует'))
"""
@api.constrains('profile_id')
def check_profile_id(self):
contracts = self.search([('partner_id', '=', self.partner_id.id), ('id', '!=', self.id)])
if contracts:
profiles_in_contracts = contracts.profile_id
# raise exceptions.ValidationError(profiles_in_contracts.ids)
if profiles_in_contracts:
ads = self.env['contract.allowed.profiles'].search(
[('allowed_profiles', 'in', profiles_in_contracts.ids)])
if ads:
raise exceptions.ValidationError((self.profile_id.name, ads.name))
# raise exceptions.ValidationError(contracts)
"""
class Partner(models.Model):
_inherit = 'res.partner'
contract_count = fields.Integer(string=_('Договоры'), compute='get_count_contract')
pol = fields.Selection(string=_("Пол"), selection=[('m', 'Муж.'), ('j', 'Жен'), ], required=False)
type = fields.Selection(selection_add=[('director', 'Директор')])
def get_count_contract(self):
contract = self.env['partner.contract.customer']
self.contract_count = contract.search_count([('partner_id', '=', self.id)])
def action_view_contract(self):
action = self.env.ref('contract.contract_customer_action').read()[0]
action['domain'] = [('partner_id', '=', self.id)]
return action
class ContractLine(models.Model):
_name = 'contract.line'
contract_id = fields.Many2one('partner.contract.customer', string='Order Reference', required=True,
ondelete='cascade', index=True, copy=False)
_order = "sequence desc"
# name = fields.Text(string='Название для договора')
# price_unit = fields.Float('Цена', default=0.0)
# product_uom = fields.Many2one('uom.uom', string='Единица измерения')
# product_id = fields.Many2one('product.product', string='Услуга', domain=[('sale_ok', '=', True)], change_default=True, ondelete='restrict')
sequence = fields.Integer('Порядок')
name = fields.Char('Номер пункта')
punct = fields.Html('Текст пункта')
@api.onchange('product_id')
def set_name(self):
self.name = self.product_id.name
class AllowedProfiles(models.Model):
_name = 'contract.allowed.profiles'
name = fields.Char(string=_('Одновременно включены следующие виды договоров:'))
allowed_profiles = fields.Many2many('contract.profile', string=_('Виды договоров'), required=True)
@api.onchange('allowed_profiles')
def set_name(self):
self.name = ''
for profile in self.allowed_profiles:
self.name += profile.name + ' + '
if self.name:
if self.name[-2] == '+':
self.name = self.name[:-2]
class ContractProfile(models.Model):
_name = 'contract.profile'
name = fields.Char(string=_('Вид договора'), required=True)
payable_account_id = fields.Many2one('account.account', string=_('Счет кредиторской задолженности'), required=True)
receivable_account_id = fields.Many2one('account.account', string=_('Счет дебиторской задолженности'), required=True)
max_receivable_id = fields.Float(string=_('Максимальная деб. задолженность'), required=True)
payment_term_id = fields.Many2one('account.payment.term', string=_('Условие оплаты'), required=True)
journal_id = fields.Many2one('account.journal', string=_('Журнал'), required=True)
class ContractDay(models.Model):
_name = 'contract.day'
name = fields.Char(_('День'))