def _check_date(self): if self.issued_date > self.return_date: raise ValidationError(_( 'Return Date cannot be set before Issued Date.'))
def next_state(self, state): """ Avanza al siguiente estado del flow del cheque si corresponde """ next_state = OWN_CHECK_NEXT_STATES.get(state) if not next_state: raise ValidationError("No se puede avanzar el estado del cheque") self.write({'state': next_state})
def constraint_amount(self): for check in self: if check.amount <= 0.0: raise ValidationError("El importe del cheque debe ser mayor a 0")
def cancel_payment(self): """ Lo que deberia pasar con el cheque cuando se cancela una orden de pago.. """ if any(check.state != 'handed' for check in self): raise ValidationError("Los cheques de terceros deben estar en estado entregado para cancelar el pago") self.cancel_state('handed')
def cancel_payment(self): """ Lo que deberia pasar con el cheque cuando se cancela el pago.. """ if any(check.state != 'handed' for check in self): raise ValidationError("Los cheques propios deben estar en estado entregado para cancelar el pago") self.cancel_state('handed') self.write({'destination_payment_id': None})
def unlink(self): for check in self: if check.state != 'draft': raise ValidationError("Solo se pueden borrar cheques en estado borrador") super(AccountThirdCheck, self).unlink()
def post_payment(self): """ Lo que deberia pasar con el cheque cuando se valida un pago.. """ if any(check.state != 'wallet' for check in self): raise ValidationError("Los cheques de terceros entregados deben estar en cartera") self.next_state('wallet_handed')
def _check_fees_amount(self): if self.fees_method == 'by_amount': if self.fees_amount <= self.financing_id.amount_invoiced: raise ValidationError('Fee amount must be greater than %s' % self.financing_id.amount_invoiced)
def _check_installment_amount(self): if any([i.amount <= 0 for i in self.installment_ids]): raise ValidationError( _('Negative or zero installment amount not allowed!'))
def _check_interest_rate(self): if self.interest_rate < 0: raise ValidationError('Interest rate must be greater than 0')
def _check_fees_number(self): if self.fees_method == 'by_fees': if self.fees_number <= 0: raise ValidationError('Fees number must be greater than 0')
def _check_amount_pending(self): if self.amount_pending <= 0: raise ValidationError('Amount must be greater than 0')
def _check_duration(self): if len(str(self.duration)) > 3: raise ValidationError(_("You can not enter duration more than \ three digits!")) if self.duration <= 0: raise ValidationError(_("Duration must be greater than 0!"))
def action_in_training(self): for rec in self: if not rec.date_of_arrival: raise ValidationError(_("Please add Date of arrival!")) self.state = 'train_completed' return True
def get_REGINFO_CV_CBTE(self): res = [] invoices = self.get_citi_invoices() invoices.check_argentinian_invoice_taxes() if self.type == 'purchase': partners = invoices.mapped('commercial_partner_id').filtered( lambda r: r.main_id_category_id.afip_code in (False, 99) or not r.main_id_number) if partners: raise ValidationError( _("On purchase citi, partner document is mandatory and " "partner document type must be different from 99. " "Partners %s") % partners.ids) for inv in invoices: # only vat taxes with codes 3, 4, 5, 6, 8, 9 # segun: http://contadoresenred.com/regimen-de-informacion-de- # compras-y-ventas-rg-3685-como-cargar-la-informacion/ # empezamos a contar los codigos 1 (no gravado) y 2 (exento) # si no hay alicuotas, sumamos una de esta con 0, 0, 0 en detalle # usamos mapped por si hay afip codes duplicados (ej. manual y # auto) cant_alicuotas = len( inv.vat_tax_ids.filtered(lambda r: r.tax_code_id.afip_code in [3, 4, 5, 6, 8, 9]).mapped( 'tax_code_id.afip_code')) if not cant_alicuotas and inv.vat_tax_ids.filtered( lambda r: r.tax_code_id.afip_code in [0, 1, 2]): cant_alicuotas = 1 row = [ # Campo 1: Fecha de comprobante fields.Date.from_string(inv.date_invoice).strftime('%Y%m%d'), # Campo 2: Tipo de Comprobante. "{:0>3d}".format(inv.document_type_id.afip_code), # Campo 3: Punto de Venta self.get_point_of_sale(inv), # Campo 4: Número de Comprobante # TODO agregar estos casos de uso # Si se trata de un comprobante de varias hojas, se deberá # informar el número de documento de la primera hoja, teniendo # en cuenta lo normado en el artículo 23, inciso a), punto # 6., de la Resolución General N° 1.415, sus modificatorias y # complementarias. # En el supuesto de registrar de manera agrupada por totales # diarios, se deberá consignar el primer número de comprobante # del rango a considerar. "{:0>20d}".format(inv.invoice_number) ] if self.type == 'sale': # Campo 5: Número de Comprobante Hasta. # TODO agregar esto En el resto de los casos se consignará el # dato registrado en el campo 4 row.append("{:0>20d}".format(inv.invoice_number)) else: # Campo 5: Despacho de importación if inv.document_type_id.afip_code == 66: row.append((inv.afip_document_number or inv.number or '').rjust(16, '0')) else: row.append(''.rjust(16, ' ')) row += [ # Campo 6: Código de documento del comprador. self.get_partner_document_code(inv.commercial_partner_id), # Campo 7: Número de Identificación del comprador self.get_partner_document_number(inv.commercial_partner_id), # Campo 8: Apellido y Nombre del comprador. inv.commercial_partner_id.name.encode('ascii', 'ignore').ljust(30, ' ') [:30], # Campo 9: Importe Total de la Operación. self.format_amount(inv.amount_total, invoice=inv), # Campo 10: Importe total de conceptos que no integran el # precio neto gravado self.format_amount(inv.vat_untaxed, invoice=inv), ] if self.type == 'sale': row += [ # Campo 11: Percepción a no categorizados self.format_amount(sum( inv.tax_line_ids.filtered(lambda r: ( r.tax_code_id.type == 'perception' and r. tax_code_id.tax == 'vat' and r.tax_code_id. application == 'national_taxes')).mapped( 'tax_amount')), invoice=inv), # Campo 12: Importe de operaciones exentas self.format_amount(inv.vat_exempt_amount, invoice=inv), ] else: row += [ # Campo 11: Importe de operaciones exentas self.format_amount(inv.vat_exempt_amount, invoice=inv), # Campo 12: Importe de percepciones o pagos a cuenta del # Impuesto al Valor Agregado self.format_amount(sum( inv.tax_line_ids.filtered(lambda r: ( r.tax_code_id.type == 'perception' and r. tax_code_id.tax == 'vat' and r.tax_code_id. application == 'national_taxes')).mapped( 'tax_amount')), invoice=inv), ] row += [ # Campo 13: Importe de percepciones o pagos a cuenta de # impuestos nacionales self.format_amount(sum( inv.tax_line_ids.filtered(lambda r: ( r.tax_code_id.type == 'perception' and r.tax_code_id. tax != 'vat' and r.tax_code_id.application == 'national_taxes')).mapped('tax_amount')), invoice=inv), # Campo 14: Importe de percepciones de ingresos brutos self.format_amount(sum( inv.tax_line_ids.filtered(lambda r: ( r.tax_code_id.type == 'perception' and r.tax_code_id. application == 'provincial_taxes')).mapped( 'tax_amount')), invoice=inv), # Campo 15: Importe de percepciones de impuestos municipales self.format_amount(sum( inv.tax_line_ids.filtered(lambda r: ( r.tax_code_id.type == 'perception' and r.tax_code_id. application == 'municipal_taxes')).mapped( 'tax_amount')), invoice=inv), # Campo 16: Importe de impuestos internos self.format_amount(sum( inv.tax_line_ids.filtered( lambda r: r.tax_code_id.application == 'internal_taxes' ).mapped('tax_amount')), invoice=inv), # Campo 17: Código de Moneda str(inv.currency_id.afip_code), # Campo 18: Tipo de Cambio self.format_amount(inv.currency_rate or inv.currency_id.with_context( date=inv.date_invoice).compute( 1., inv.company_id.currency_id), padding=10, decimals=6), # Campo 19: Cantidad de alícuotas de IVA str(cant_alicuotas), # Campo 20: Código de operación. # WARNING. segun la plantilla es 0 si no es ninguna # TODO ver que no se informe un codigo si no correpsonde, # tal vez da error inv.fiscal_position_id.afip_code or ' ', ] if self.type == 'sale': row += [ # Campo 21: Otros Tributos self.format_amount(sum( inv.tax_line_ids.filtered( lambda r: r.tax_code_id.application == 'others'). mapped('tax_amount')), invoice=inv), # Campo 22: vencimiento comprobante (no figura en # instructivo pero si en aplicativo) para tique no se # informa (inv.document_type_id.code in ['81', '82', '83'] and '00000000' or fields.Date.from_string( inv.date_due).strftime('%Y%m%d')), ] else: # Campo 21: Crédito Fiscal Computable if self.prorate_tax_credit: if self.prorate_type == 'global': row.append(self.format_amount(0), invoice=inv) else: # row.append(self.format_amount(0)) raise ValidationError( _('by_voucher not implemented yet')) else: row.append(self.format_amount(inv.vat_amount, invoice=inv)) row += [ # Campo 22: Otros Tributos self.format_amount(sum( inv.tax_line_ids.filtered(lambda r: ( r.tax_code_id.application == 'others')).mapped( 'tax_amount')), invoice=inv), # TODO implementar estos 3 # Campo 23: CUIT Emisor / Corredor # Se informará sólo si en el campo "Tipo de Comprobante" se # consigna '033', '058', '059', '060' ó '063'. Si para # éstos comprobantes no interviene un tercero en la # operación, se consignará la C.U.I.T. del informante. Para # el resto de los comprobantes se completará con ceros self.format_amount(0, padding=11, invoice=inv), # Campo 24: Denominación Emisor / Corredor ''.ljust(30, ' ')[:30], # Campo 25: IVA Comisión # Si el campo 23 es distinto de cero se consignará el # importe del I.V.A. de la comisión self.format_amount(0, invoice=inv), ] res.append(''.join(row)) self.REGINFO_CV_CBTE = '\r\n'.join(res)
def validate_quotation(self, cr, uid, ids, context={}): orders_to_invoice = [] inv_obj = self.pool.get('account.invoice') pay_obj = self.pool.get('account.payment') for order in self.browse(cr, uid, ids): if order.state not in ('draft', 'sent'): raise ValidationError( _('The order must be a quotation to be able to validate it. Use revalidate_quotation instead.' )) for line in order.order_line: if line.product_id.type in ('consu', 'product'): raise ValidationError( _('The order has a stockable product. Please check it') ) order.action_confirm() orders_to_invoice.append(order.id) invoice_ids = self.action_invoice_create(cr, uid, orders_to_invoice, final=True) if invoice_ids: if isinstance(invoice_ids, list): invoice_id = invoice_ids[0] else: invoice_id = invoice_ids invoice = inv_obj.browse(cr, uid, invoice_id) invoice.signal_workflow('invoice_open') if context.get('biller_name'): journal_obj = self.pool.get('account.journal') journal_ids = journal_obj.search( cr, uid, [('name', 'ilike', context.get('biller_name'))]) if journal_ids: journal_id = journal_obj.browse(cr, uid, journal_ids) payment_type = 'inbound' payment_methods = journal_id.inbound_payment_method_ids payment_method_id = payment_methods and payment_methods[ 0] or False payment_data = { 'journal_id': journal_id.id, 'payment_type': payment_type, 'payment_method_id': payment_method_id.id, 'amount': invoice.residual, 'biller_customer_id': context.get('biller_customer_id', ''), 'biller_transaction_id': context.get('biller_transaction_id', ''), 'card_code': context.get('card_code', ''), 'biller_data': context.get('biller_data', ''), } pay_id = pay_obj.create(cr, uid, payment_data, context={ 'default_invoice_ids': [(4, invoice_id, None)] }) pay_obj.browse(cr, uid, pay_id).post() else: raise ValidationError(_('The biller sent does not exist')) else: raise ValidationError(_('There is no biller on the dict')) for order in self.browse(cr, uid, ids): order.action_done() return True
def constraint_payments(self): for check in self: if len(check.account_payment_ids) > 1: raise ValidationError("El cheque "+check.name+" ya se encuentra en otro pago")
def validate_subscription(self, cr, uid, ids, context={}): subscriptions_to_invoice = [] inv_obj = self.pool.get('account.invoice') pay_obj = self.pool.get('account.payment') for subscription in self.browse(cr, uid, ids): if subscription.state not in ('draft'): raise ValidationError( _('The subscription must be on draft to validate it. Use rebill_subscription instead.' )) for line in subscription.recurring_invoice_line_ids: if not line.product_id.recurring_invoice: raise ValidationError( _('The subscription needs a subscription product. Please check it' )) subscription.set_open() subscriptions_to_invoice.append(subscription.id) invoice_ids = self.recurring_invoice(cr, uid, subscriptions_to_invoice) if invoice_ids: if isinstance(invoice_ids, list): invoice_id = invoice_ids[0] else: invoice_id = invoice_ids invoice = inv_obj.browse(cr, uid, invoice_id) invoice.signal_workflow('invoice_open') if context.get('biller_name'): journal_obj = self.pool.get('account.journal') journal_ids = journal_obj.search( cr, uid, [('name', 'ilike', context.get('biller_name'))]) if journal_ids: journal_id = journal_obj.browse(cr, uid, journal_ids) payment_type = 'inbound' payment_methods = journal_id.inbound_payment_method_ids payment_method_id = payment_methods and payment_methods[ 0] or False payment_data = { 'journal_id': journal_id.id, 'payment_type': payment_type, 'payment_method_id': payment_method_id.id, 'amount': invoice.residual } if context.get('biller_customer_id'): payment_data['biller_customer_id'] = context.get( 'biller_customer_id', '') if context.get('biller_transaction_id'): payment_data['biller_transaction_id'] = context.get( 'biller_transaction_id', '') if context.get('card_type'): payment_data['card_type'] = context.get( 'card_type', '') if context.get('card_code'): payment_data['card_code'] = context.get( 'card_code', '') if context.get('biller_data'): payment_data['biller_data'] = context.get( 'biller_data', '') pay_id = pay_obj.create(cr, uid, payment_data, context={ 'default_invoice_ids': [(4, invoice_id, None)] }) pay_obj.browse(cr, uid, pay_id).post() else: raise ValidationError(_('The biller sent does not exist')) else: raise ValidationError(_('There is no biller on the dict')) return True
def post_receipt(self, currency_id): """ Lo que deberia pasar con el cheque cuando se valida un recibo.. """ if any(check.state != 'draft' for check in self): raise ValidationError("Los cheques de terceros recibidos deben estar en estado borrador") self.write({'currency_id': currency_id}) self.next_state('draft')
def _check_delay_automove(self): if self.active_move and self.delay_automove <= 0: raise ValidationError( "Value of 'Delay' field must be greater than 0")
def cancel_receipt(self): """ Lo que deberia pasar con el cheque cuando se cancela un recibo.. """ if any(check.state != 'wallet' for check in self): raise ValidationError("Los cheques de terceros recibidos deben estar en cartera para cancelar el pago") self.cancel_state('wallet')
def onchange_title(self, cr, uid, ids, title, context=None): if title and len(title.split('\n')) > 4: raise ValidationError('El titulo no debe sobrepasar de 4 lineas')
def constraint_collect_date(self): for check in self: if check.collect_date and check.collect_date < check.payment_date: raise ValidationError("La fecha de cobro no puede ser menor a la fecha de pago")
def _check_marks(self): if (self.total_pass < 0.0) or (self.total_failed < 0.0): raise ValidationError('Enter proper pass or fail!')
def cancel_state(self, state): """ Vuelve a un estado anterior del flow del cheque si corresponde """ cancel_state = OWN_CHECK_CANCEL_STATES.get(state) if not cancel_state: raise ValidationError("No se puede cancelar el estado del cheque") self.write({'state': cancel_state})
def check_capacity(self): if len(self.student_ids) > self.vehicle_id.capacity: raise ValidationError(_('Students over than vehicle capacity.'))
def constraint_name(self): for check in self: if not check.name.isdigit(): raise ValidationError("El numero del cheque debe contener solo numeros")
def check_places(self): if self.from_stop_id == self.to_stop_id: raise ValidationError(_('To place cannot be equal to From place.'))
def copy(self): raise ValidationError(_('It not possible to duplicate same date the record, pls. create a new one.'))
def _check_prorata(self): if self.prorata and self.method_time != 'number': raise ValidationError( _('Prorata temporis can be applied only for time method "number of depreciations".' ))