def check_field(self): pool = Pool() invalid_fields = ('many2one', 'one2one', 'reference', 'one2many', 'many2many') path = self.field.split('.') Model = pool.get('lims.notebook.line') field_name = path.pop(0) if field_name not in Model._fields: raise UserError(gettext('lims.msg_rule_condition_field', field=self.field)) field = Model._fields[field_name] if not path and field._type in invalid_fields: raise UserError(gettext('lims.msg_rule_condition_field', field=self.field)) while path: if field._type != 'many2one': raise UserError(gettext('lims.msg_rule_condition_field', field=self.field)) Model = pool.get(field.model_name) field_name = path.pop(0) if field_name not in Model._fields: raise UserError(gettext('lims.msg_rule_condition_field', field=self.field)) field = Model._fields[field_name] if not path and field._type in invalid_fields: raise UserError(gettext('lims.msg_rule_condition_field', field=self.field))
def check_context(self): if not self.model_context: return try: value = PYSONDecoder().decode(self.model_context) except Exception: raise UserError( gettext('shine.invalid_context', context=self.model_context, dataset=self.rec_name)) if isinstance(value, PYSON): if not value.types() == set([dict]): raise UserError( gettext('shine.invalid_context', context=self.model_context, dataset=self.rec_name)) elif not isinstance(value, dict): raise UserError( gettext('shine.invalid_context', context=self.model_context, dataset=self.rec_name)) else: try: fields.context_validate(value) except Exception: raise UserError( gettext('shine.invalid_context', context=self.model_context, dataset=self.rec_name))
def parse(cls, report, records, data, localcontext): """ Replace the report with the report selected in Account Move """ if len(records) > 1: raise UserError( "This report can only be generated for 1 record at a time" ) move = records[0] if not move.enable_check_printing: raise UserError( "Check Printing not enabled for this Account Move." ) if not move.check_number: raise UserError( "Check Number not valid." ) if not move.state == 'posted': raise UserError( "You must Post the move before printing check." ) # Use Account Move's check template report = move.journal.check_template return super(Check, cls).parse( report, records, data, localcontext )
def get_line(self): if self.edi_invoice.type_ == '381': # CREDIT: return self.get_line_credit() if self.references is None or len(self.references) != 1: raise UserError( gettext('account_invoice_edi.confirm_invoice_with_reference', line=self.description)) move, = self.references invoice_lines = [x for x in move.origin.invoice_lines if not x.invoice] if not invoice_lines or len(invoice_lines) != 1: raise UserError( gettext('account_invoice_edi.confirm_invoice_with_invoice', line=self.description)) invoice_line, = invoice_lines # JUst invoice wat system expect to see differences. # invoice_line.gross_unit_price = self.gross_price or self.unit_price # invoice_line.unit_price = self.unit_price # if self.unit_price and self.gross_price: # invoice_line.discount = Decimal(1 - # self.unit_price/self.gross_price).quantize(Decimal('.01')) # else: # invoice_line.unit_price = Decimal( # self.base_amount / self.quantity).quantize(Decimal('0.0001')) self.invoice_line = invoice_line return invoice_line
def parseNumber(self): self.skipWhitespace() strValue = '' decimal_found = False char = '' while self.hasNext(): char = self.peek() if char == '.': if decimal_found: raise UserError( gettext('lims.msg_extra_period', index=str(self._index))) decimal_found = True strValue += '.' elif char in '0123456789': strValue += char else: break self._index += 1 if len(strValue) == 0: if char == '': raise UserError(gettext('lims.msg_unexpected_end')) else: raise UserError( gettext('lims.msg_number_expected', index=str(self._index), character=char)) return float(strValue)
def check_complete_file(cls, parties): pool = Pool() Address = pool.get('party.address') for party in parties: if not party.complete_file: continue has_email = Address.search_count([ ('party', '=', party.id), ('email', 'not in', (None, '')), ]) if has_email < 1: raise UserError( gettext('lims_industry.msg_party_no_email', party=party.rec_name)) has_phone = Address.search_count([ ('party', '=', party.id), ('phone', 'not in', (None, '')), ]) if has_phone < 1: raise UserError( gettext('lims_industry.msg_party_no_phone', party=party.rec_name)) if not party.tax_identifier: raise UserError( gettext('lims_industry.msg_party_no_tax_identifier', party=party.rec_name))
def check_default(self): if self.quality: return if self.by_default: typifications = self.search([ ('product_type', '=', self.product_type.id), ('matrix', '=', self.matrix.id), ('analysis', '=', self.analysis.id), ('valid', '=', True), ('by_default', '=', True), ('id', '!=', self.id), ]) if typifications: raise UserError(gettext('lims.msg_default_typification')) else: if self.valid: typifications = self.search([ ('product_type', '=', self.product_type.id), ('matrix', '=', self.matrix.id), ('analysis', '=', self.analysis.id), ('valid', '=', True), ('id', '!=', self.id), ]) if not typifications: raise UserError( gettext('lims.msg_not_default_typification'))
def check_domain(self): if not self.model_domain: return try: value = PYSONDecoder().decode(self.model_domain) except Exception: raise UserError( gettext('shine.invalid_domain', domain=self.model_domain, dataset=self.rec_name)) if isinstance(value, PYSON): if not value.types() == set([list]): raise UserError( gettext('shine.invalid_domain', domain=self.model_domain, dataset=self.rec_name)) elif not isinstance(value, list): raise UserError( gettext('shine.invalid_domain', domain=self.model_domain, dataset=self.rec_name)) else: try: fields.domain_validate(value) except Exception: raise UserError( gettext('shine.invalid_domain', domain=self.model_domain, dataset=self.rec_name))
def default_get(cls, fields, with_rec_name=True): pool = Pool() Line = pool.get('account.move.line') PaymentType = pool.get('account.payment.type') defaults = super(CompensationMoveStart, cls).default_get(fields, with_rec_name) party = None company = None amount = Decimal('0.0') lines = Line.browse(Transaction().context.get('active_ids', [])) for line in lines: amount += line.debit - line.credit if not party: party = line.party elif party != line.party: raise UserError( gettext('account_bank.different_parties', party=line.party.rec_name, line=line.rec_name)) if not company: company = line.account.company if (company and company.currency.is_zero(amount) and len(set([x.account for x in lines])) == 1): raise UserError(gettext('account_bank.normal_reconcile')) if amount > 0: defaults['payment_kind'] = 'receivable' else: defaults['payment_kind'] = 'payable' defaults['bank_account'] = None if party: defaults['party'] = party.id if (defaults['payment_kind'] in ['receivable', 'both'] and party.customer_payment_type): defaults['payment_type'] = party.customer_payment_type.id elif (defaults['payment_kind'] in ['payable', 'both'] and party.supplier_payment_type): defaults['payment_type'] = party.supplier_payment_type.id if defaults.get('payment_type'): payment_type = PaymentType(defaults['payment_type']) defaults['account_bank'] = payment_type.account_bank self = cls() self.payment_type = payment_type self.party = party self._get_bank_account() defaults['account_bank_from'] = ( self.on_change_with_account_bank_from()) defaults['bank_account'] = (self.bank_account.id if self.bank_account else None) if amount > 0: defaults['account'] = (party.account_receivable.id if party.account_receivable else None) else: defaults['account'] = (party.account_payable.id if party.account_payable else None) return defaults
def check_selection(self, active_ids): StatementLine = Pool().get('account.bank.statement.line') if not active_ids: raise UserError(gettext('create_transactions.no_active_ids')) lines = StatementLine.browse(active_ids) if any([line.state != 'confirmed' for line in lines]): raise UserError(gettext('create_transactions.invalid_state')) if any([line.reconciled for line in lines]): raise UserError( gettext('create_transactions.must_not_be_reconciled'))
def transition_revert(self): pool = Pool() ThirdCheck = pool.get('account.third.check') Move = pool.get('account.move') MoveLine = pool.get('account.move.line') Period = pool.get('account.period') period_id = Period.find(1, date=self.start.date) for check in ThirdCheck.browse(Transaction().context.get( 'active_ids')): if check.state not in ['deposited', 'delivered']: raise UserError(gettext( 'account_check_ar.msg_check_not_deposited', check=check.name)) if not check.account_bank_out.journal.third_check_account: raise UserError(gettext( 'account_voucher_ar.msg_no_journal_check_account', journal=check.account_bank_out.journal.name)) move, = Move.create([{ 'journal': check.account_bank_out.journal.id, 'period': period_id, 'date': self.start.date, 'description': 'Cheque: ' + check.name, }]) lines = [] lines.append({ 'account': check.account_bank_out.debit_account.id, 'move': move.id, 'journal': check.account_bank_out.journal.id, 'period': period_id, 'debit': _ZERO, 'credit': check.amount, 'date': self.start.date, }) lines.append({ 'account': check.account_bank_out.journal.third_check_account.id, 'move': move.id, 'journal': check.account_bank_out.journal.id, 'period': period_id, 'debit': check.amount, 'credit': _ZERO, 'date': self.start.date, }) MoveLine.create(lines) ThirdCheck.write([check], { 'account_bank_out': None, 'state': 'reverted', }) Move.post([move]) return 'end'
def get_afip_rate(self, service='wsfex'): ''' get rate from afip webservice. ''' pool = Pool() Company = pool.get('company.company') company_id = Transaction().context.get('company') if not company_id: logger.error('The company is not defined') raise UserError( gettext('account_invoice_ar.msg_company_not_defined')) company = Company(company_id) # authenticate against AFIP: ta = company.pyafipws_authenticate(service=service) if service == 'wsfe': ws = WSFEv1() if company.pyafipws_mode_cert == 'homologacion': WSDL = 'https://wswhomo.afip.gov.ar/wsfev1/service.asmx?WSDL' elif company.pyafipws_mode_cert == 'produccion': WSDL = ( 'https://servicios1.afip.gov.ar/wsfev1/service.asmx?WSDL') elif service == 'wsfex': ws = WSFEXv1() if company.pyafipws_mode_cert == 'homologacion': WSDL = 'https://wswhomo.afip.gov.ar/wsfexv1/service.asmx?WSDL' elif company.pyafipws_mode_cert == 'produccion': WSDL = ( 'https://servicios1.afip.gov.ar/wsfexv1/service.asmx?WSDL') else: logger.critical('AFIP ws is not yet supported! %s', service) raise UserError( gettext('account_invoice_ar.msg_webservice_not_supported', service=service)) cache = Company.get_cache_dir() ws.LanzarExcepciones = True try: ws.Conectar(wsdl=WSDL, cache=cache, cacert=True) except Exception as e: msg = ws.Excepcion + ' ' + str(e) logger.error('WSAA connecting to afip: %s' % msg) raise UserError( gettext('account_invoice_ar.msg_wsaa_error', msg=msg)) ws.SetTicketAcceso(ta) ws.Cuit = company.party.vat_number if not self.currency.afip_code: logger.error('AFIP code is empty %s', self.currency.code) raise UserError(gettext('account_invoice_ar.msg_afip_code_empty')) self.rate = Decimal(ws.GetParamCtz('DOL')) self.date = datetime.datetime.strptime(ws.FchCotiz, '%Y%m%d').date()
def validate(cls, locations): super(Location, cls).validate(locations) for location in locations: if (location.parent and location.parent.unique_children and len(location.parent.childs) > 1): raise UserError( gettext('stock_location_only_child.msg_only_child', location=location.rec_name)) if location.unique_children and len(location.childs) > 1: raise UserError( gettext('stock_location_only_child.msg_only_child', location=location.rec_name))
def check_formulas(self): any_formula = False for formula in self.formulas: if formula.store: any_formula = True icon = formula.expression_icon if icon and icon != 'green': raise UserError( gettext('shine.invalid_formula', sheet=self.rec_name, formula=formula.rec_name)) if not any_formula: raise UserError(gettext('shine.no_formulas', sheet=self.rec_name))
def check_icons(self): was_icon = False for formula in self.formulas: if formula.type == 'icon': if was_icon: raise UserError( gettext('shine.consecutive_icons', sheet=self.rec_name)) was_icon = True else: was_icon = False if was_icon: raise UserError(gettext('shine.last_icon', sheet=self.rec_name))
def transition_held(self): pool = Pool() ThirdCheck = pool.get('account.third.check') Move = pool.get('account.move') MoveLine = pool.get('account.move.line') Date = pool.get('ir.date') Period = pool.get('account.period') date = Date.today() period_id = Period.find(1, date) for check in ThirdCheck.browse(Transaction().context.get( 'active_ids')): if check.state != 'draft': raise UserError(gettext( 'account_check_ar.msg_check_not_draft', check=check.name)) if not self.start.journal.third_check_account: raise UserError(gettext( 'account_voucher_ar.msg_no_journal_check_account', journal=self.start.journal.name)) move, = Move.create([{ 'journal': self.start.journal.id, 'period': period_id, 'date': date, 'description': 'Cheque: ' + check.name, }]) lines = [] lines.append({ 'account': self.start.journal.third_check_account.id, 'move': move.id, 'journal': self.start.journal.id, 'period': period_id, 'debit': check.amount, 'credit': _ZERO, 'date': date, 'maturity_date': check.date, }) lines.append({ 'account': self.start.credit_account.id, 'move': move.id, 'journal': self.start.journal.id, 'period': period_id, 'debit': _ZERO, 'credit': check.amount, 'date': date, }) MoveLine.create(lines) ThirdCheck.write([check], {'state': 'held'}) Move.post([move]) return 'end'
def confirm(cls, sales): Warning = Pool().get('res.user.warning') # make sure noone is able to confirm a sale with shipment or invoice methods we do not want for sale in sales: if sale.shipment_method != 'order': raise UserError('Liefermethode ungültig') if sale.invoice_method != 'shipment': raise UserError('Rechnungmethode ungültig') if not sale.payment_term: raise UserError('Keine Zahlungsbedingungen angegeben!') # first check if we have a line without product and issue a warning warning_name = 'saleline_noproduct,%s' % cls need_fixing = [] for sale in sales: if not sale.party.pn_name or len(sale.party.pn_name.strip()) < 1: raise UserError( 'Verkaufsparteien müssen einen PN Namen zugewiesen haben.') for line in sale.lines: if not line.product: need_fixing.append(line.rec_name) if Warning.check(warning_name): if need_fixing: msg = 'Position ohne Produkt gefunden!!' #msg += '\n'.join(need_fixing) raise UserWarning(warning_name, msg) # check if we already have an order fromt his customer for this date with the same sale_date_extra warning_sale_date_extra = 'sale_date_extra,%s' % cls warn_sale_date = [] for sale in sales: others = Pool().get('sale.sale').search([ ('sale_folder_postfix', '=', sale.sale_folder_postfix), ('party', '=', sale.party), ('sale_date', '=', sale.sale_date), ('number', '!=', sale.number), ]) for s in others: warn_sale_date.append(s.number) if Warning.check(warning_sale_date_extra): if warn_sale_date: msg = 'Verkauf für diesen Kunden mit gleichem Bestelldatum und Bestellordner Zusatz existiert bereits:' msg += '\n'.join(warn_sale_date) raise UserWarning(warning_sale_date_extra, msg) # give the users a warning before actually confirming an order and creating shipments,.. confirm_warning = 'sale_confirm,%s' % cls if Warning.check(confirm_warning): raise UserWarning( confirm_warning, 'Bestätigen des Verkaufs erzeugt einen Lieferschein - fortfahren?' ) super(Sale, cls).confirm(sales)
def create_stock_moves(cls, ambulatory_cares, lines): pool = Pool() Move = pool.get('stock.move') Date = pool.get('ir.date') moves = [] for ambulatory in ambulatory_cares: for medicament in lines['medicaments']: move_info = {} move_info['origin'] = str(ambulatory) move_info['product'] = medicament.medicament.name.id move_info['uom'] = medicament.medicament.name.default_uom.id move_info['quantity'] = medicament.quantity move_info['from_location'] = ambulatory.care_location.id move_info['to_location'] = \ ambulatory.patient.name.customer_location.id move_info['unit_price'] = \ medicament.medicament.name.list_price if medicament.lot: if medicament.lot.expiration_date \ and medicament.lot.expiration_date < Date.today(): raise UserError('Expired medicaments') move_info['lot'] = medicament.lot.id moves.append(move_info) for medical_supply in lines['supplies']: move_info = {} move_info['origin'] = str(ambulatory) move_info['product'] = medical_supply.product.id move_info['uom'] = medical_supply.product.default_uom.id move_info['quantity'] = medical_supply.quantity move_info['from_location'] = ambulatory.care_location.id move_info['to_location'] = \ ambulatory.patient.name.customer_location.id move_info['unit_price'] = medical_supply.product.list_price if medical_supply.lot: if medical_supply.lot.expiration_date \ and medical_supply.lot.expiration_date < Date.today(): raise UserError('Expired supplies') move_info['lot'] = medical_supply.lot.id moves.append(move_info) new_moves = Move.create(moves) Move.write(new_moves, { 'state': 'done', 'effective_date': Date.today(), }) return True
def check_quotation_confirmed(self): confirmed = [x for x in self.prices if x.state == 'confirmed'] if confirmed and len(confirmed) > 1: raise UserError( gettext( 'product_dynamic_configurator_sale_opportunity.msg_only_one_quotation_confirmed_allowed' ))
def check_owners(cls, accounts): with Transaction().set_context(_check_access=False): pool = Pool() IrModel = pool.get('ir.model') Field = pool.get('ir.model.field') account_ids = [a.id for a in accounts] for value in cls._check_owners_related_models: model_name, field_name = value Model = pool.get(model_name) records = Model.search([(field_name, 'in', account_ids)]) model, = IrModel.search([('model', '=', model_name)]) field, = Field.search([ ('model.model', '=', model_name), ('name', '=', field_name), ], limit=1) for record in records: target = record.account_bank_from account = getattr(record, field_name) if target not in account.owners: raise UserError( gettext('account_bank.modify_with_related_model', account=account.rec_name, model=model.name, field=field.field_description, name=record.rec_name))
def transition_start(self): Sample = Pool().get('lims.sample') if not Transaction().context['active_ids']: raise UserError( gettext('lims_quality_control.msg_records_not_selected')) samples = Sample.browse(Transaction().context['active_ids']) for sample in samples: if sample.test_state != 'done': raise UserError( gettext('lims_quality_control.msg_not_test_sample')) if sample.countersample: raise UserError( gettext('lims_quality_control.msg_has_countersample')) return 'ask'
def __init__(self, merchant_id, test=False, pass_code=None, hash_key=None): """ :param merchant_id: Pass the merchant’s unique Beanstream identification number. Please note that Beanstream issues one merchant ID per currency. If the merchant is processing in both Canadian and US dollars, you will need to complete one full integration per merchant ID number. .. tip:: Note that this field is different from the merchantid field used in the Beanstream Process Transaction API :param test: Boolean to indicate if this is a test request. :param pass_code: Specify the API access passcode that has been generated on the payment profile configuration page. :param hash_key: Specify the Hash Key that has been saved in Beanstream account. """ self.merchant_id = merchant_id self.test = test if not pass_code and not hash_key: # Atleast one should be there raise UserError('Beanstream Error:', 'No validation method provided') self.pass_code = pass_code self.hash_key = hash_key
def create_profile_using_stripe_token(cls, user_id, gateway_id, token, address_id=None): """ Create a Payment Profile using token """ Party = Pool().get('party.party') PaymentGateway = Pool().get('payment_gateway.gateway') PaymentProfile = Pool().get('party.payment_profile') party = Party(user_id) gateway = PaymentGateway(gateway_id) assert gateway.provider == 'stripe' stripe.api_key = gateway.stripe_api_key try: customer = stripe.Customer.create( source=token, description=party.name, ) card = customer.sources.data[0] except (stripe.error.CardError, stripe.error.InvalidRequestError, stripe.error.AuthenticationError, stripe.error.APIConnectionError, stripe.error.StripeError), exc: raise UserError(exc.json_body['error']['message'])
def check_access(cls): pool = Pool() ModelAccess = pool.get('ir.model.access') ActionWizard = pool.get('ir.action.wizard') User = pool.get('res.user') context = Transaction().context if Transaction().user == 0: return with Transaction().set_context(_check_access=True): model = context.get('active_model') if model and model != 'ir.ui.menu': ModelAccess.check(model, 'read') groups = set(User.get_groups()) wizard_groups = ActionWizard.get_groups( cls.__name__, action_id=context.get('action_id')) if wizard_groups: if not groups & wizard_groups: raise UserError('Calling wizard %s is not allowed!' % cls.__name__) elif model and model != 'ir.ui.menu': Model = pool.get(model) if (not callable(getattr(Model, 'table_query', None)) or Model.write.__func__ != ModelSQL.write.__func__): ModelAccess.check(model, 'write')
def _validate_facturae(self, xml_string, schema_file_path=None): """ Inspired by https://github.com/pedrobaeza/l10n-spain/blob/d01d049934db55130471e284012be7c860d987eb/l10n_es_facturae/wizard/create_facturae.py """ logger = logging.getLogger('account_invoice_facturae') if not schema_file_path: schema_file_path = os.path.join(module_path(), DEFAULT_FACTURAE_SCHEMA) with open(schema_file_path, encoding='utf-8') as schema_file: facturae_schema = etree.XMLSchema(file=schema_file) logger.debug("%s loaded" % schema_file_path) try: facturae_schema.assertValid(etree.fromstring(xml_string)) logger.debug("Factura-e XML of invoice %s validated", self.rec_name) except Exception as e: logger.warning("Error validating generated Factura-e file", exc_info=True) logger.debug(xml_string) raise UserError( gettext('account_invoice_facturae.invalid_factura_xml_file', invoice=self.rec_name, message=e)) return True
def get_pricelist_shipping_cost(self): """ Return pricelist shipping cost """ Product = Pool().get('product.product') Carrier = Pool().get('carrier') Company = Pool().get('company.company') carrier, = Carrier.search([('carrier_cost_method', '=', 'pricelist')]) total = Decimal('0') company = Transaction().context.get('company') if not company: raise UserError("Company not in context.") default_currency = Company(company).currency with Transaction().set_context(customer=self.customer.id, price_list=carrier.price_list.id, currency=default_currency.id): for move in self.outgoing_moves: total += \ Product.get_sale_price([move.product])[move.product.id] * \ Decimal(move.quantity) return total, default_currency.id
def check_alias(self): for symbol in self.alias: if not symbol in VALID_SYMBOLS: raise UserError( gettext('shine.invalid_alias', symbol=symbol, name=self.name))
def validate(cls, massedits): super(MassEdit, cls).validate(massedits) for massedit in massedits: Model = Pool().get(massedit.model.model) if not issubclass(Model, ModelSQL): raise UserError( gettext('massedit.not_modelsql', model=massedit.rec_name))
def check_service_invoice(cls, lines): for line in lines: if (line.origin and line.origin.__name__ == 'lims.service' and not line.economic_offer): raise UserError( gettext('lims_account_invoice.msg_delete_service_invoice', service=line.origin.rec_name))
def assign(self, grouping=('product',)): pool = Pool() Move = pool.get('stock.move') Lang = pool.get('ir.lang') lang = Lang.get() if self.quantity is not None: if not (0 <= self.quantity <= self.move.quantity): uom = self.move.product.default_uom raise ValidationError(gettext( 'stock_assign_manual.msg_invalid_quantity', quantity=lang.format_number( self.move_quantity, uom.digits))) quantity = self.move.uom.round(self.quantity) remainder = self.move.uom.round(self.move.quantity - quantity) self.move.quantity = quantity self.move.save() if remainder: Move.copy([self.move], {'quantity': remainder}) key = json.loads(self.place) values = self._apply(key, grouping) quantity = self.move.quantity Move.assign_try([self.move], with_childs=False, grouping=grouping) if self.move.state != 'assigned': # Restore initial values as assign_try may have saved the move for field, value in values.items(): setattr(self.move, field, value) self.move.save() if self.move.quantity == quantity: raise UserError(gettext( 'stock_assign_manual.msg_assign_failed', move=self.move.rec_name, place=self.place_string))