718 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			Python
		
	
	
			
		
		
	
	
			718 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			Python
		
	
	
| # -*- coding: utf-8 -*-
 | |
| ##############################################################################
 | |
| #
 | |
| #    datenpol gmbh
 | |
| #    Copyright (C) 2013-TODAY datenpol gmbh (<http://www.datenpol.at/>)
 | |
| #
 | |
| #    This program is free software: you can redistribute it and/or modify
 | |
| #    it under the terms of the GNU Affero General Public License as
 | |
| #    published by the Free Software Foundation, either version 3 of the
 | |
| #    License, or (at your option) any later version.
 | |
| #
 | |
| #    This program is distributed in the hope that it will be useful,
 | |
| #    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
| #    GNU Affero General Public License for more details.
 | |
| #
 | |
| #    You should have received a copy of the GNU Affero General Public License
 | |
| #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | |
| #
 | |
| ##############################################################################
 | |
| import json
 | |
| 
 | |
| import requests
 | |
| from odoo.addons.component.core import Component
 | |
| from odoo.addons.queue_job.job import job
 | |
| 
 | |
| from odoo import tools, api, fields, models, _
 | |
| from odoo.exceptions import ValidationError
 | |
| from dateutil.relativedelta import relativedelta
 | |
| 
 | |
| from email.utils import formataddr
 | |
| 
 | |
| import dateutil.parser
 | |
| import datetime
 | |
| 
 | |
| import ssl
 | |
| 
 | |
| try:
 | |
|     import stdnum.eu.vat as stdnum_vat
 | |
| except ImportError:
 | |
|     stdnum_vat = None
 | |
| 
 | |
| class PartnerEventListener(Component):
 | |
|     _name = 'res.partner.listener'
 | |
|     _inherit = 'base.event.listener'
 | |
|     _apply_on = ['res.partner']
 | |
| 
 | |
|     def on_record_write(self, record, fields=None):
 | |
|         if record.active and record.company_type == 'company':
 | |
|             if 'company_type' in fields or 'property_product_pricelist' in fields:
 | |
|                 if record.portal_id:
 | |
|                     pricelist_mode = self.env['ir.config_parameter'].sudo().get_param('pricelist_mode')
 | |
|                     if pricelist_mode == 'partner':
 | |
|                         self.env['res.partner'].with_delay().job_export_portal_price(record)
 | |
|                     else:
 | |
|                         self.env['res.partner'].export_portal_partner_pricelist(record)
 | |
| 
 | |
|     def on_record_create(self, record, fields=None):
 | |
|         if record.active and record.portal_id and record.company_type == 'company':
 | |
|             pricelist_mode = self.env['ir.config_parameter'].sudo().get_param('pricelist_mode')
 | |
|             if pricelist_mode == 'partner':
 | |
|                 self.env['res.partner'].with_delay().job_export_portal_price(record)
 | |
|             else:
 | |
|                 self.env['res.partner'].export_portal_partner_pricelist(record)
 | |
| 
 | |
| class Partner(models.Model):
 | |
|     _name = 'res.partner'
 | |
|     _inherit = ['res.partner', 'dp_custom.helper']
 | |
| 
 | |
|     @api.model
 | |
|     def _default_country_id(self):
 | |
|         return self.env.ref('base.at')
 | |
| 
 | |
|     name2 = fields.Char('Unternehmensname 2')
 | |
|     info_kundennr = fields.Char(string='Info-Kundennr.')
 | |
|     info_uid = fields.Char(string='Info-UID')
 | |
|     endkunde = fields.Boolean(string='Endkunde', help='Beschreibt, ob es ein Endkunde ist')
 | |
|     root = fields.Boolean(string='Stammfirma', help='Diese Firma ist die Stammfirma des Kunden',track_visibility='onchange')
 | |
|     portal_pending = fields.Boolean('Erwarte Zuordnung', help='Wird vom Portal bei neuen Unternehmen gesetzt. '
 | |
|                                                               'Sobald das Unternehmen manuell zugewiesen wurde, '
 | |
|                                                               'wird das Flag wieder entfernt')
 | |
|     line_ids = fields.Many2many(comodel_name='res.line', string='Produktionslinien')
 | |
|     portal_id = fields.Char(string='Portal-ID',copy=False,track_visibility='onchange')
 | |
|     partner_sector_id = fields.Many2one(comodel_name='res.partner.sector', string='Branche')
 | |
|     active = fields.Boolean(track_visibility='onchange')
 | |
|     portal_export_pending = fields.Boolean(string='Portal Export ausständig')
 | |
|     warn_portal_date = fields.Boolean(compute='_get_warn_portal_date', store=False, default=False)
 | |
|     date_vat_check = fields.Date(string='Datum der letzten UID-Prüfung')
 | |
|     warn_vat_date = fields.Boolean(compute='_get_warn_date', store=False, default=False)
 | |
|     vat = fields.Char(default='',copy=False)
 | |
|     collective_bill = fields.Boolean(string='Sammelrechnung', default=True)
 | |
|     country_id = fields.Many2one('res.country', string='Country', ondelete='restrict', default=_default_country_id)
 | |
|     commission_account_ids = fields.Many2many(comodel_name='commission.account', string='Provisionsempfänger')
 | |
| #    commission_percentage = fields.Float(string='Provision in %')
 | |
|     partner_flash = fields.Char()
 | |
|     fax = fields.Char(string='Fax')
 | |
|     user_id = fields.Many2one(track_visibility='onchange')
 | |
|     freight_category_id = fields.Many2one(comodel_name='res.partner.freight_category', string='Fracht-Kategorie')
 | |
| 
 | |
| # make pricelist searchable (store=True) --> code copied from: \ext\odoo\addons\product\models\res_partner.py!
 | |
| #     property_product_pricelist = fields.Many2one(
 | |
| #         'product.pricelist', 'Sale Pricelist', compute='_compute_product_pricelist', store=True, default=1,
 | |
| #         inverse="_inverse_product_pricelist", company_dependent=False,  # NOT A REAL PROPERTY
 | |
| #         help="This pricelist will be used, instead of the default one, for sales to the current partner",
 | |
| #         track_visibility='onchange')
 | |
| 
 | |
|     property_product_pricelist = fields.Many2one(
 | |
|         'product.pricelist', 'Sale Pricelist',
 | |
| #        compute='_compute_product_pricelist',
 | |
|         compute='',
 | |
|         store=True,
 | |
|         default=lambda self: self.env['product.pricelist'].search([('company_id', '=', None)], limit=1),
 | |
| #        inverse="_inverse_product_pricelist",
 | |
|         company_dependent=False,  # NOT A REAL PROPERTY
 | |
|         help="This pricelist will be used, instead of the default one, for sales to the current partner",
 | |
|         track_visibility='onchange', required=True)
 | |
| 
 | |
|     portal_managed_pricelist = fields.Boolean(string='Preisliste im Portal verwaltet', default=False, track_visibility='onchange')
 | |
| 
 | |
|     _sql_constraints = [
 | |
|         ('ref_uniq', 'unique(ref)', 'Die Interne Referenz muss eindeutig sein'),
 | |
|         ('portal_id_uniq', 'unique(portal_id)', 'Die Portal-ID muss eindeutig sein')
 | |
|     ]
 | |
| 
 | |
|     @api.depends('name', 'email')
 | |
|     def _compute_email_formatted(self):
 | |
|         for partner in self:
 | |
|             try:
 | |
|                 xmail = partner.email or u"False"
 | |
|                 if isinstance(xmail,str):
 | |
|                     xmail = xmail.encode('idna').decode()
 | |
|                 partner.email_formatted = formataddr((partner.name or u"False", xmail))
 | |
|             except:
 | |
|                 partner.email_formatted = partner.email
 | |
| 
 | |
|     @api.multi
 | |
|     @api.constrains('property_product_pricelist')
 | |
|     def _check_property_product_pricelist(self):
 | |
|         for record in self:
 | |
|             if not record.parent_id.id and not record.property_product_pricelist:
 | |
| # Here we have to set partner_id.property_product_pricelist if it es empty and a parent_id is existing - else we rise an error
 | |
|                 raise ValidationError(_("Ungültige Preisliste!"))
 | |
| 
 | |
|     @api.multi
 | |
|     def _get_warn_portal_date(self):
 | |
|         for record in self:
 | |
|             if not record.active and record.portal_pending:
 | |
|                 date_today = fields.Date.from_string(fields.Date.context_today(self))
 | |
|                 warn_date = date_today - relativedelta(days=+2)
 | |
|                 try:
 | |
|                     check_date = dateutil.parser.parse(record.create_date).date()
 | |
|                 except:
 | |
|                     check_date = date_today
 | |
|                 if check_date < warn_date:
 | |
|                     record.warn_portal_date = True
 | |
|                 else:
 | |
|                     record.warn_portal_date = False
 | |
|             else:
 | |
|                 record.warn_portal_date = False
 | |
| 
 | |
| 
 | |
|     @api.multi
 | |
|     def _get_warn_date(self):
 | |
|         for record in self:
 | |
|             if record.date_vat_check:
 | |
|                 date_today = fields.Date.from_string(fields.Date.context_today(self))
 | |
|                 warn_date = date_today - relativedelta(months=+3)
 | |
|                 try:
 | |
|                     check_date = dateutil.parser.parse(record.date_vat_check).date()
 | |
|                 except:
 | |
|                     check_date = date_today - relativedelta(months=+36)
 | |
|                 if check_date < warn_date:
 | |
|                     record.warn_vat_date = True
 | |
|                 else:
 | |
|                     record.warn_vat_date = False
 | |
|             else:
 | |
|                 record.warn_vat_date = True
 | |
| 
 | |
| 
 | |
|     @api.multi
 | |
|     def action_check_vat(self):
 | |
|         for record in self:
 | |
|             if record.vat:
 | |
|                 vat_country, vat_number = self._split_vat(record.vat)
 | |
|                 try:
 | |
|                     my_vat = self.self.env.user.company_id.vat
 | |
|                     my_vat = my_vat.replace(' ','')
 | |
|                     result = stdnum_vat.check_vies_approx(vat_country+vat_number,my_vat)
 | |
|                 except Exception as ex:
 | |
|                     # Avoid blocking the client when the service is unreachable/unavailable
 | |
|                     raise ValidationError("UID-Prüfung: %s, Service ist nicht verfügbar - %s" % (record.vat,ex))
 | |
|                     return {}
 | |
| 
 | |
|                 if not result['valid']:
 | |
|                     vat_valid = self.vies_vat_check(vat_country, vat_number)
 | |
|                     if not vat_valid:
 | |
|                         raise ValidationError(
 | |
|                             _("UID-INVALID: Die UID '%s' ist ungültig oder hat ein falsches Format") % record.vat)
 | |
| 
 | |
|                 record.date_vat_check = fields.Date.today()
 | |
| 
 | |
|                 myresult= dict(result)
 | |
|                 msg_post = ('<b>UID-Nr geprüft:</b><br>%s%s<br>%s<br>%s<br>%s<br>Abfrage-Nr: %s<br>Valid: %s') % \
 | |
|                            (myresult.get('countryCode',''),myresult.get('vatNumber','')\
 | |
|                            ,myresult.get('traderName','k.A.')\
 | |
|                            ,myresult.get('traderCompanyType','k.A.')\
 | |
|                            ,myresult.get('traderAddress','k.A.')\
 | |
|                            ,myresult.get('requestIdentifier','k.A.')\
 | |
|                            ,myresult.get('valid', 'k.A.'))
 | |
|                 record.message_post(body=msg_post)
 | |
| 
 | |
|     @api.multi
 | |
|     @api.constrains('is_company', 'vat')
 | |
|     def _check_unique_vat(self):
 | |
|         for record in self:
 | |
|             if not record.vat or (not record.is_company and record.parent_id):
 | |
|                 continue
 | |
|             partners = self.search([('is_company', '=', True),
 | |
|                                     ('vat', '=', self.vat),
 | |
|                                     ('company_id', '=', self.company_id.id),
 | |
|                                     ('id', '!=', self.id)])
 | |
|             if partners:
 | |
|                 raise ValidationError(_("UID-Exists: Es sind bereits folgende Unternehmen mit der selben USt. ID "
 | |
|                                         "vorhanden: %s") % [p.name for p in partners])
 | |
| 
 | |
|     @api.model
 | |
|     def portal_create_company(self, vals):
 | |
|         """
 | |
|         SST-01
 | |
|         :param vals:
 | |
|         :return:
 | |
|         """
 | |
| 
 | |
| #        portal_url = tools.config.get('portal_url')
 | |
| #        portal_url = self.env['ir.config_parameter'].sudo().get_param('ribbon.name')
 | |
| #        portal_url = self.env['ir.config_parameter'].get_param('ribbon.name')
 | |
| 
 | |
|         self.with_context(sst_1=True).check_not_specified_fields(vals)
 | |
|         vals = self.correct_values(vals)
 | |
|         portal_prefix = self.env.user.company_id.portal_prefix
 | |
|         if portal_prefix:
 | |
|             vals['portal_id'] = portal_prefix + '.' + vals['portal_id']
 | |
|         if not vals.get('active', False):
 | |
|             vals['active'] = False
 | |
|         vals['is_company'] = True
 | |
|         vals['portal_pending'] = True
 | |
|         vals.setdefault('root',True)
 | |
| 
 | |
|         # send mail activity to usergroup(with group 'informieren bei neuem Portalkunden, if new company was created
 | |
|         recordset = self.create(vals)
 | |
|         users = self.env.ref('dp_custom.group_inform_on_new_company').users
 | |
| 
 | |
|         for user in users:
 | |
|             values = {
 | |
|                 'user_id': user.id,
 | |
|                 'date_deadline': fields.Date.today(),
 | |
|                 'activity_type_id': self.env.ref('mail.mail_activity_data_todo').id,
 | |
|                 'activity_category': 'default',
 | |
|                 'res_id': recordset.id,
 | |
|                 'res_model': recordset._name,
 | |
|                 'res_model_id': self.env.ref('base_partner_sequence.model_res_partner').id,
 | |
|                 'summary': 'Es wurde ein neuer Portalkunde angelegt'
 | |
|             }
 | |
|             self.env['mail.activity'].create(values)
 | |
| 
 | |
|         return True
 | |
| 
 | |
|     @api.model
 | |
|     def portal_create_company____1(self, vals):
 | |
|         """
 | |
|         SST-01
 | |
|         :param vals:
 | |
|         :return:
 | |
|         """
 | |
|         self.with_context(sst_1=True).check_not_specified_fields(vals)
 | |
|         vals = self.correct_values(vals)
 | |
|         if not vals.get('active', False):
 | |
|             vals['active'] = False
 | |
|         vals['is_company'] = True
 | |
|         vals['portal_pending'] = True
 | |
| 
 | |
|         # send mail activity to usergroup(with group 'informieren bei neuem Portalkunden, if new company was created
 | |
|         recordset = self.create(vals)
 | |
|         users = self.env.ref('dp_custom.group_inform_on_new_company').users
 | |
| 
 | |
|         for user in users:
 | |
|             values = {
 | |
|                 'user_id': user.id,
 | |
|                 'date_deadline': fields.Date.today(),
 | |
|                 'activity_type_id': self.env.ref('mail.mail_activity_data_todo').id,
 | |
|                 'activity_category': 'default',
 | |
|                 'res_id': recordset.id,
 | |
|                 'res_model': recordset._name,
 | |
|                 'res_model_id': self.env.ref('base_partner_sequence.model_res_partner').id,
 | |
|                 'summary': 'Es wurde ein neuer Portalkunde angelegt'
 | |
|             }
 | |
|             self.env['mail.activity'].create(values)
 | |
| 
 | |
|         return True
 | |
| 
 | |
|     @api.model
 | |
|     def portal_create_contact(self, vals):
 | |
|         """
 | |
|         SST-14
 | |
|         :param vals:
 | |
|         :return:
 | |
|         """
 | |
|         self.with_context(sst_14=True).check_not_specified_fields(vals)
 | |
|         vals = self.correct_values(vals)
 | |
|         portal_prefix = self.env.user.company_id.portal_prefix
 | |
|         if portal_prefix:
 | |
|             vals['portal_id'] = portal_prefix + '.' + vals['portal_id']
 | |
|         return self.create(vals).id
 | |
| 
 | |
|     @api.model
 | |
|     def pg_create_company(self, vals):
 | |
|         """
 | |
|         SST-11
 | |
|         :param vals:
 | |
|         :return:
 | |
|         """
 | |
|         self.with_context(sst_11=True).check_not_specified_fields(vals)
 | |
|         vals = self.correct_values(vals)
 | |
|         partner = self.with_context(active_test=False).search([('ref', '=', vals['ref'])])
 | |
|         if partner:
 | |
|             if not partner.is_company:
 | |
|                 raise ValidationError(
 | |
|                     _("Der Partner mit der Internen Referenz '%s' ist kein Unternehmen") % vals['ref'])
 | |
|             partner.write(vals)
 | |
|         else:
 | |
|             if not vals.get('is_company', False):
 | |
|                 vals['is_company'] = True
 | |
|             partner = self.create(vals)
 | |
|             partner.property_account_fiscal_position = self.env['account.fiscal.position'].get_fiscal_position(
 | |
|                 partner.id)
 | |
|         return True
 | |
| 
 | |
|     @api.model
 | |
|     def portal_update_pricelist(self, vals):
 | |
|         """
 | |
|         SST-16
 | |
|         :param vals:
 | |
|         :return:
 | |
|         """
 | |
|         self.with_context(sst_16=True).check_not_specified_fields(vals)
 | |
|         vals = self.with_context(sst_16=True).correct_values(vals)
 | |
|         portal_prefix = self.env.user.company_id.portal_prefix
 | |
|         if portal_prefix:
 | |
|             vals['portal_id'] = portal_prefix + '.' + vals['portal_id']
 | |
| 
 | |
|         partner = self.with_context(active_test=False).search([('portal_id', '=', vals['portal_id'])])
 | |
|         if partner:
 | |
|             if not partner.is_company:
 | |
|                 raise ValidationError(
 | |
|                     _("Der Partner mit der Internen Referenz '%s' ist kein Unternehmen") % vals['ref'])
 | |
|             partner.write(vals)
 | |
|         return True
 | |
| 
 | |
|     @api.model
 | |
|     def correct_values(self, vals):
 | |
|         if vals.get('country_id', False):
 | |
|             country = self.env['res.country'].search([('code', '=', vals['country_id'])])
 | |
|             if country:
 | |
|                 vals['country_id'] = country.id
 | |
|             else:
 | |
|                 raise ValidationError(
 | |
|                     _("Das Land mit dem ISO-Code \'%s\' kann nicht zugeordnet werden") % vals['country_id'])
 | |
| 
 | |
|         if vals.get('line_ids', False):
 | |
|             line_ids = self.env['res.line'].search([('name', 'in', vals['line_ids'])])
 | |
|             if line_ids:
 | |
|                 vals['line_ids'] = [(6, 0, line_ids.ids)]
 | |
|             else:
 | |
|                 raise ValidationError(
 | |
|                     _("Die Produktionslinie mit dem Code \'%s\' kann nicht zugeordnet werden") % vals['line_ids'])
 | |
| 
 | |
|         if vals.get('lang', False):
 | |
|             temp = vals['lang']
 | |
|             vals['lang'] = False
 | |
|             for selection in self.fields_get('lang')['lang']['selection']:
 | |
|                 if selection[0].startswith(temp):
 | |
|                     vals['lang'] = selection[0]
 | |
|                     break
 | |
|             if not vals['lang']:
 | |
|                 raise ValidationError(_("Die Sprache mit dem Code \'%s\' kann nicht zugeordnet werden") % temp)
 | |
| 
 | |
|         if vals.get('partner_sector_id', False):
 | |
|             branche = self.env['res.partner.sector'].search(
 | |
|                 [('name', '=', vals['partner_sector_id'])])
 | |
|             if branche:
 | |
|                 vals['partner_sector_id'] = branche.id
 | |
|             else:
 | |
|                 raise ValidationError(_("Die Branche \'%s\' kann nicht zugeordnet werden") % vals['partner_sector_id'])
 | |
| 
 | |
|         if vals.get('property_payment_term_id', False):
 | |
|             payment_term = self.env['account.payment.term'].search(
 | |
|                 [('code', '=', vals['property_payment_term_id'])])
 | |
|             if payment_term:
 | |
|                 vals['property_payment_term_id'] = payment_term.id
 | |
|             else:
 | |
|                 raise ValidationError(
 | |
|                     _("Die Zahlungsbedingung mit dem Code \'%s\' kann nicht zugeordnet werden") % vals[
 | |
|                         'property_payment_term_id'])
 | |
| 
 | |
| #        if self.env.context.get('sst_1', False) or  self.env.context.get('sst_16', False):
 | |
|         if vals.get('property_product_pricelist_id', False):
 | |
|             # product_pricelist = self.env['product.pricelist'].search(
 | |
|             #     [('name', '=', vals['property_product_pricelist']),('id', '=', vals['property_product_pricelist_id'])])
 | |
|             product_pricelist = self.env['product.pricelist'].search(
 | |
|                 [('id', '=', vals['property_product_pricelist_id'])])
 | |
|             if product_pricelist:
 | |
|                 vals['property_product_pricelist'] = vals['property_product_pricelist_id']
 | |
|                 del vals['property_product_pricelist_id']
 | |
|             else:
 | |
|                 raise ValidationError(_("Die Preisliste \'%s\' mit der ID \'%s\' ist nicht vorhanden") %
 | |
|                                       (vals['property_product_pricelist'],vals['property_product_pricelist_id']))
 | |
|         elif vals.get('property_product_pricelist', False):
 | |
|             product_pricelist = self.env['product.pricelist'].search(
 | |
|                 [('currency_id.name', '=', vals['property_product_pricelist'])])
 | |
|             if product_pricelist:
 | |
|                 vals['property_product_pricelist'] = product_pricelist[0].id
 | |
|             else:
 | |
|                 raise ValidationError(_("Die Preisliste mit der Währung \'%s\' kann nicht zugeordnet werden") % vals[
 | |
|                     'property_product_pricelist'])
 | |
| 
 | |
|         if vals.get('retail_partner_id', False):
 | |
|             retail_partner = self.env['res.partner'].search(
 | |
|                 [('id', '=', vals['retail_partner_id'])])
 | |
|             if retail_partner:
 | |
|                 vals['retail_partner_id'] = retail_partner.id
 | |
|             else:
 | |
|                 raise ValidationError(
 | |
|                     _("Der Händler mit der Internen Referenz \'%s\' kann nicht zugeordnet werden") % vals[
 | |
|                         'retail_partner_id'])
 | |
| 
 | |
|         if vals.get('incoterm', False):
 | |
|             incoterm = self.env['stock.incoterms'].search(
 | |
|                 [('code', '=', vals['incoterm'])])
 | |
|             if incoterm:
 | |
|                 vals['sale_incoterm_id'] = incoterm.id
 | |
|                 del vals['incoterm']
 | |
|             else:
 | |
|                 raise ValidationError(
 | |
|                     _("Die Lieferbedingung mit dem Code \'%s\' kann nicht zugeordnet werden") % vals['incoterm'])
 | |
| 
 | |
|         if vals.get('company_odoo_id', False):
 | |
|             parent_id = self.env['res.partner'].with_context(active_test=False).search(
 | |
|                 [('id', '=', vals['company_odoo_id'])])
 | |
|             if parent_id:
 | |
|                 vals['parent_id'] = parent_id.id
 | |
|                 vals['street'] = parent_id.street
 | |
|                 vals['street2'] = parent_id.street2
 | |
|                 vals['city'] = parent_id.city
 | |
|                 vals['zip'] = parent_id.zip
 | |
|                 vals['country_id'] = parent_id.country_id.id
 | |
|                 vals['supplier'] = parent_id.supplier
 | |
|                 vals['customer'] = parent_id.customer
 | |
|                 vals['lang'] = parent_id.lang
 | |
|                 del vals['company_odoo_id']
 | |
|             else:
 | |
|                 raise ValidationError(_("Unternehmen mit Odoo-ID \'%s\' existiert nicht") % vals['company_odoo_id'])
 | |
| 
 | |
|         if vals.get('carrier_id', False):
 | |
|             carrier_id = self.env['delivery.carrier'].search([('name', '=', vals['carrier_id'])])
 | |
|             if carrier_id:
 | |
|                 vals['property_delivery_carrier_id'] = carrier_id.id
 | |
|                 del vals['carrier_id']
 | |
|             else:
 | |
|                 raise ValidationError(
 | |
|                     _("Die Auslieferungsmethode mit dem Namen \'%s\' existiert nicht") % vals['carrier_id'])
 | |
| 
 | |
|         if 'fiscal_position' in vals:
 | |
|             if not vals.get('fiscal_position', False):
 | |
|                 vals['property_account_position_id'] = False
 | |
|                 del vals['fiscal_position']
 | |
|             else:
 | |
|                 property_account_position_id = self.env['account.fiscal.position'].search(
 | |
|                     [('name', '=', vals['fiscal_position'])])
 | |
|                 if property_account_position_id:
 | |
|                     vals['property_account_position_id'] = property_account_position_id.id
 | |
|                     del vals['fiscal_position']
 | |
|                 else:
 | |
|                     raise ValidationError(
 | |
|                         _("Steuerzuorndung \'%s\' kann nicht zugeordnet werden") % vals['fiscal_position'])
 | |
| 
 | |
|         return vals
 | |
| 
 | |
|     @api.model
 | |
|     def _get_specified_fields(self):
 | |
|         common_list = ['street', 'street2', 'zip', 'city', 'country_id', 'fax', 'phone', 'mobile',
 | |
|                        'endkunde', 'line_ids', 'lang', 'portal_id', 'email', 'opt_out',
 | |
|                        'property_product_pricelist', 'property_product_pricelist_id', 'portal_managed_pricelist','root']
 | |
|         if self.env.context.get('sst_1', False):
 | |
|             common_list.extend(['name', 'name2', 'info_kundennr', 'info_uid', 'comment', 'retail_partner_id'])
 | |
|             return common_list
 | |
|         elif self.env.context.get('sst_11', False):
 | |
|             common_list.extend(
 | |
|                 ['name', 'ref', 'partner_sector_id', 'info_uid', 'comment', 'vat', 'property_payment_term_id',
 | |
|                  'date_vat_check', 'active', 'retail_partner_id',
 | |
|                  'is_retailer', 'name2', 'carrier_id', 'collective_bill', 'fiscal_position', 'partner_flash'])
 | |
|             return common_list
 | |
|         elif self.env.context.get('sst_14', False):
 | |
|             common_list = ['firstname', 'lastname', 'midname', 'email', 'company_odoo_id', 'portal_id', 'opt_out', 'property_product_pricelist','root']
 | |
|             return common_list
 | |
|         elif self.env.context.get('sst_16', False):
 | |
|             common_list = ['company_odoo_id', 'portal_id', 'portal_managed_pricelist','property_product_pricelist','property_product_pricelist_id']
 | |
|             return common_list
 | |
|         elif self.env.context.get('delivery_partner', False):
 | |
|             common_list = ['firstname', 'lastname', 'midname', 'street', 'street2', 'zip', 'city', 'country_id', 'fax',
 | |
|                            'phone', 'mobile', 'email', 'portal_id', 'property_product_pricelist']
 | |
|             return common_list
 | |
|         else:
 | |
|             return super(Partner, self)._get_specified_fields()
 | |
| 
 | |
|     @api.model
 | |
|     def cron_export_portal_prices(self):
 | |
|         """
 | |
|         SST-02
 | |
|         :return:
 | |
|         """
 | |
|         partners = self.search([('portal_export_pending', '=', True), ('company_id', '=', self.env.user.company_id.id)])
 | |
|         for partner in partners:
 | |
|             pricelist_mode = self.env['ir.config_parameter'].sudo().get_param('pricelist_mode')
 | |
|             if pricelist_mode == 'partner':
 | |
|                 self.with_delay().job_export_portal_price(partner)
 | |
| #               self.job_export_portal_price(partner)
 | |
|             else:
 | |
|                 self.export_portal_partner_pricelist(partner)
 | |
| 
 | |
|             partner.portal_export_pending = False
 | |
| 
 | |
|     @api.multi
 | |
|     @job
 | |
|     def job_export_portal_price(self, partner_id):
 | |
|         """
 | |
|         SST-02
 | |
|         :param partner_id:
 | |
|         :return:
 | |
|         """
 | |
|         if not partner_id.portal_id:
 | |
|             raise ValidationError(_("Der Partner mit der ID %s hat keine Portal-ID") % partner_id.id)
 | |
| 
 | |
|         pricelist = partner_id.property_product_pricelist
 | |
|         data = []
 | |
|         for item in pricelist.item_ids:
 | |
|             if item.compute_price == 'percentage' and item.applied_on in ['3_global', '2_product_category',
 | |
|                                                                           '0_product_variant']:
 | |
|                 code = False
 | |
|                 if item.applied_on == '2_product_category':
 | |
|                     code = item.categ_id.code
 | |
|                 if item.applied_on == '0_product_variant':
 | |
|                     code = item.product_id.product_tmpl_id.default_code
 | |
|                 data.append({
 | |
|                     'customer_id': partner_id.commercial_partner_id.portal_id.split('.')[1],
 | |
|                     'code': code,
 | |
|                     'discount': 1 - (item.percent_price / 100)
 | |
|                 })
 | |
|         if data:
 | |
|             portal_url = tools.config.get('portal_url')
 | |
|             application_id = tools.config.get('portal_secret')
 | |
|             response = requests.post(portal_url + '/api/v1/set-discounts/?secret=' + application_id,
 | |
|                                      data=json.dumps(data))
 | |
|             if response.status_code != 200:
 | |
|                 data = response.json()
 | |
|                 error_string = data.get('errors', [])
 | |
|                 raise ValidationError(_('Meldung vom Portal: Rabatt konnte nicht gesetzt werden. '
 | |
|                                         'Status Code: %s, Reason: %s') % (response.status_code, error_string))
 | |
| 
 | |
|     @api.multi
 | |
|     def export_portal_partner_pricelist(self, partner_id):
 | |
|         """
 | |
|         SST-02a
 | |
|         :param partner_id:
 | |
|         :return:
 | |
|         """
 | |
|         if partner_id.portal_managed_pricelist:
 | |
|             return
 | |
| 
 | |
|         if not partner_id.root:
 | |
| #            raise Warning(_("Der Partner mit der ID %s ist nicht als Stammfirma gekennzeichnet") % (partner_id.id))
 | |
|             return
 | |
| 
 | |
|         if not partner_id.portal_id:
 | |
|             raise ValidationError(_("Der Partner mit der ID %s hat keine Portal-ID") % partner_id.id)
 | |
| 
 | |
|         try:
 | |
|             _create_unverified_https_context = ssl._create_unverified_context
 | |
|         except AttributeError:
 | |
|             # Legacy Python that doesn't verify HTTPS certificates by default
 | |
|             pass
 | |
|         else:
 | |
|             # Handle target environment that doesn't support HTTPS verification
 | |
|             ssl._create_default_https_context = _create_unverified_https_context
 | |
| 
 | |
|         pricelist = partner_id.property_product_pricelist
 | |
|         lPortal_id = partner_id.commercial_partner_id.portal_id.split('.')[1]
 | |
|         data = {
 | |
|             'customer_id': lPortal_id,
 | |
|             'pricelist_id': pricelist.id,
 | |
|             'pricelist_name': pricelist.name,
 | |
|             'portal_prefix': self.env.user.company_id.portal_prefix,
 | |
|             }
 | |
| 
 | |
|         portal_url = tools.config.get('portal_url')
 | |
|         application_id = tools.config.get('portal_secret')
 | |
|         response = requests.post(portal_url + '/api/v1/set-pricelist/?secret=' + application_id,
 | |
|                                  data=json.dumps(data))
 | |
|         if response.status_code != 200:
 | |
|             if response.status_code == 428:
 | |
|                 self.env['product.pricelist.item'].job_export_portal_pricelist(pricelist.id)
 | |
|             else:
 | |
|                 try:
 | |
|                     data = response.json()
 | |
|                     error_string = data.get('errors', [])
 | |
|                 except:
 | |
|                     error_string = response.reason
 | |
| 
 | |
|                 raise ValidationError(_('Meldung vom Portal: Rabatt konnte nicht gesetzt werden. '
 | |
|                                         'Status Code: %s, Reason: %s') % (response.status_code, error_string))
 | |
| 
 | |
|     @api.multi
 | |
|     def write(self, vals):
 | |
|         for partner in self:
 | |
|             if not partner.company_id and partner.user_ids.id and self.env.uid != 1:
 | |
|                 raise ValidationError(_('Dieser Datensatz gehört zu einem Benutzer und darf nur vom System-Administrator bearbeitet werden!'))
 | |
| 
 | |
|         fields_to_check = ['ref', 'portal_id']
 | |
|         for field in fields_to_check:
 | |
|             if field in vals and vals[field] == '':
 | |
|                 vals[field] = False
 | |
|         return super(Partner, self).write(vals)
 | |
| 
 | |
|     @api.multi
 | |
|     def name_get(self):
 | |
|         res = []
 | |
|         for partner in self:
 | |
|             name = partner.name or ''
 | |
|             if partner.name2:
 | |
|                 name += " " + partner.name2
 | |
| 
 | |
|             if partner.company_name or partner.parent_id:
 | |
|                 if not name and partner.type in ['invoice', 'delivery', 'other']:
 | |
|                     name = dict(self.fields_get(['type'])['type']['selection'])[partner.type]
 | |
|                 if not partner.is_company:
 | |
|                     name = "%s, %s" % (partner.commercial_company_name or partner.parent_id.name, name)
 | |
|             if partner.is_company and self._context.get('name_search'):
 | |
|                 name += ' - %s - %s' % (partner.zip, partner.street)
 | |
|             if self._context.get('show_address_only'):
 | |
|                 name = partner._display_address(without_company=True)
 | |
|             if self._context.get('show_address'):
 | |
|                 name = name + "\n" + partner._display_address(without_company=True)
 | |
|             name = name.replace('\n\n', '\n')
 | |
|             name = name.replace('\n\n', '\n')
 | |
|             if self._context.get('show_email') and partner.email:
 | |
|                 name = "%s <%s>" % (name, partner.email)
 | |
|             if self._context.get('html_format'):
 | |
|                 name = name.replace('\n', '<br/>')
 | |
|             res.append((partner.id, name))
 | |
|         return res
 | |
| 
 | |
|     @api.model
 | |
|     def name_search(self, name='', args=None, operator='ilike', limit=100):
 | |
|         return super(Partner, self.with_context(name_search=True)).name_search(name=name, args=args, operator=operator,
 | |
|                                                                                limit=limit)
 | |
| 
 | |
|     @api.model
 | |
|     def search_read(self, domain=None, fields=None, offset=0, limit=None, order=None):
 | |
|         for context_element in self.env.context:
 | |
|             if context_element.startswith('search_default_activities_'):
 | |
|                 return super(Partner, self.with_context(active_test=False)).search_read(domain=domain, fields=fields, offset=offset, limit=limit, order=order)
 | |
|         return super(Partner, self).search_read(domain=domain, fields=fields, offset=offset, limit=limit, order=order)
 | |
| 
 | |
|     @api.depends('company_name', 'parent_id.is_company', 'commercial_partner_id.name')
 | |
|     def _compute_commercial_company_name(self):
 | |
|         res = super(Partner, self)._compute_commercial_company_name()
 | |
|         for partner in self:
 | |
|             p = partner.commercial_partner_id
 | |
|             if p.is_company and p.name2:
 | |
|                 partner.commercial_company_name += " " + p.name2
 | |
|         return res
 | |
| 
 | |
|     @api.multi
 | |
|     def _needsRef(self, vals=None):
 | |
|         return True
 | |
| 
 | |
|     @api.model
 | |
|     def _commercial_fields(self):
 | |
|         res = super(Partner, self)._commercial_fields()
 | |
|         if 'ref' in res:
 | |
|             del res[res.index('ref')]
 | |
|         return res
 | |
| 
 | |
| 
 | |
| class ResPartnerFreightCategory(models.Model):
 | |
|     _name = 'res.partner.freight_category'
 | |
|     _description = 'Fracht-Kategorie'
 | |
|     _order = 'name'
 | |
| 
 | |
|     name = fields.Char(string='Fracht-Kategorie', required=True)
 | |
|     description = fields.Char(string='Beschreibung', required=True)
 | |
| 
 | |
|     _sql_constraints = [
 | |
|         ('name_uniq', 'unique(name)', 'Die Fracht-Kategorie muss eindeutig sein')
 | |
|     ]
 | |
| 
 | |
| 
 | |
| class PartnerSector(models.Model):
 | |
|     _name = 'res.partner.sector'
 | |
|     _description = 'Branche'
 | |
|     _order = 'id,name'
 | |
| 
 | |
|     name = fields.Char(string='Bezeichnung', required=True)
 | |
|     sequence = fields.Integer(string='Sequenz')
 | |
| 
 | |
|     _sql_constraints = [
 | |
|         ('name_uniq', 'unique(name)', 'Die Bezeichnung muss eindeutig sein')
 | |
|     ]
 |