def produce_product_qty(self): move_obj = self.env['stock.move'] seq_obj = self.env['ir.sequence'] for data in self: sequence_search = seq_obj.search([('code', '=', 'stock.lot.serial') ]) if not sequence_search: raise ValidationError(_('Not Sequence Setting')) if sequence_search.category.id == data.product_id.categ_id.id: next_number = sequence_search.next_by_id() else: next_number = '' lot_ids = [] lot_vals = { 'name': next_number, 'product_id': data.product_id.id, 'count_for_print': data.new_quantity, 'produce_date': time.strftime('%Y-%m-%d %H:%M:%S') } ####One Lot Number new_lot = self.env['stock.production.lot'].create(lot_vals) lot_ids.append(new_lot.id) val = { 'product_id': data.product_id.id, 'product_uom': data.product_id.uom_id.id, 'name': "Produced " + data.product_id.name, 'location_id': data.product_id.property_stock_production.id, 'location_dest_id': data.location_id.id, 'product_uom_qty': data.new_quantity, 'restrict_lot_id': new_lot.id if new_lot else False, } move_id = move_obj.create(val) move_id.action_done() move_id.write({'picking_type_id': 1}) bom_ids = self.env['mrp.bom'].search([ '|', ('product_tmpl_id', '=', data.product_id.id), ('product_id', '=', data.product_id.id) ]) group_mrp_user_id = self.env['ir.model.data'].xmlid_to_res_id( 'mrp.group_mrp_user') partner_location_id = self.env['stock.location'].search([ ('usage', '=', 'customer') ]) for bom in bom_ids: if group_mrp_user_id and bom: if bom.bom_line_ids: for line in bom.bom_line_ids: if line.product_id.qty_available >= data.new_quantity: deduct_val = { 'product_id': line.product_id.id, 'product_uom': line.product_id.uom_id.id, 'name': "Deducted " + line.product_id.name, 'location_id': data.location_id.id, 'location_dest_id': partner_location_id.id, 'product_uom_qty': data.new_quantity, 'restrict_lot_id': new_lot.id if new_lot else False, } move_id = move_obj.create(deduct_val) move_id.action_done() move_id.write({'picking_type_id': 1}) else: raise ValidationError( _('Material ' + line.product_id.name + ' have not enough stock.')) datas = {'ids': lot_ids} datas['model'] = 'stock.produce.product.qty' return self.env['report'].get_action( new_lot, 'central_kitchen.report_lot_barcode_custom')
def _check_amount(self): if self.amount < 0: raise ValidationError(_('The payment amount cannot be negative.'))
def _inverse_identification(self, field_name, category_code): """Inverse for an identification field. This method will create a new record, or modify the existing one in order to allow for the associated field to work like a Char. If a category does not exist of the correct code, it will be created using `category_code` as both the `name` and `code` values. If the value of the target field is unset, the associated ID will be deactivated in order to preserve history. Example: .. code-block:: python social_security = fields.Char( compute=lambda s: s._compute_identification( 'social_security', 'SSN', ), inverse=lambda s: s._inverse_identification( 'social_security', 'SSN', ), search=lambda s, *a: s._search_identification( 'SSN', *a ), ) Args: field_name (str): Name of field to set. category_code (str): Category code of the Identification type. """ for record in self: id_number = record.identities.filtered( lambda r: r.category_id.code == category_code ) record_len = len(id_number) # Record for category is not existent. if record_len == 0: name = record[field_name] if not name: # No value to set continue category = self.env["openg2p.beneficiary.id_category"].search( [ ("code", "=", category_code), ] ) if not category: category = self.env["openg2p.beneficiary.id_category"].create( { "code": category_code, "name": category_code, } ) self.env["openg2p.beneficiary.id_number"].create( { "beneficiary_id": record.id, "category_id": category.id, "name": name, } ) # There was an identification record singleton found. elif record_len == 1: value = record[field_name] if value: id_number.name = value else: id_number.active = False # Guard against writing wrong records. else: raise ValidationError( _( "This %s has multiple IDs of this type (%s), so a write " "via the %s field is not possible. In order to fix this, " "please use the IDs tab.", ) % (record._name, category_code, field_name) )
def extract_data(self, model, values): dest_model = request.env[model.sudo().model] data = { 'record': {}, # Values to create record 'attachments': [], # Attached files 'custom': '', # Custom fields values 'meta': '', # Add metadata if enabled } authorized_fields = model.sudo()._get_form_writable_fields() error_fields = [] custom_fields = [] for field_name, field_value in values.items(): # If the value of the field if a file if hasattr(field_value, 'filename'): # Undo file upload field name indexing field_name = field_name.split('[', 1)[0] # If it's an actual binary field, convert the input file # If it's not, we'll use attachments instead if field_name in authorized_fields and authorized_fields[field_name]['type'] == 'binary': data['record'][field_name] = base64.b64encode(field_value.read()) field_value.stream.seek(0) # do not consume value forever if authorized_fields[field_name]['manual'] and field_name + "_filename" in dest_model: data['record'][field_name + "_filename"] = field_value.filename else: field_value.field_name = field_name data['attachments'].append(field_value) # If it's a known field elif field_name in authorized_fields: try: input_filter = self._input_filters[authorized_fields[field_name]['type']] data['record'][field_name] = input_filter(self, field_name, field_value) except ValueError: error_fields.append(field_name) # If it's a custom field elif field_name != 'context': custom_fields.append((field_name, field_value)) data['custom'] = "\n".join([u"%s : %s" % v for v in custom_fields]) # Add metadata if enabled # ICP for retrocompatibility if request.env['ir.config_parameter'].sudo().get_param('website_form_enable_metadata'): environ = request.httprequest.headers.environ data['meta'] += "%s : %s\n%s : %s\n%s : %s\n%s : %s\n" % ( "IP" , environ.get("REMOTE_ADDR"), "USER_AGENT" , environ.get("HTTP_USER_AGENT"), "ACCEPT_LANGUAGE" , environ.get("HTTP_ACCEPT_LANGUAGE"), "REFERER" , environ.get("HTTP_REFERER") ) # This function can be defined on any model to provide # a model-specific filtering of the record values # Example: # def website_form_input_filter(self, values): # values['name'] = '%s\'s Application' % values['partner_name'] # return values if hasattr(dest_model, "website_form_input_filter"): data['record'] = dest_model.website_form_input_filter(request, data['record']) missing_required_fields = [label for label, field in authorized_fields.items() if field['required'] and not label in data['record']] if any(error_fields): raise ValidationError(error_fields + missing_required_fields) return data
def check_unique_hid(self): for rec in self: if rec.hid: if self.env['res.users'].search_count([('hid', '=', rec.hid)]) > 1: raise ValidationError(_('This HID already exists.'))
def _check_ticket_seats_limit(self): for record in self: if record.event_ticket_id.seats_max and record.event_ticket_id.seats_available < 0: raise ValidationError( _('No more available seats for this ticket'))
def check_searchable_field(self): nosearch_fields = self._get_nosearch_fields() if self.custom_type in nosearch_fields and self.search_ok: raise ValidationError( _("Selected custom field type '%s' is not searchable" % self.custom_type))
def button_submit(self): for rec in self: search_id = self.env['reimbursement'].search([('employee_id', '=', rec.employee_id.id), ('name', '=', rec.name), ('state', 'not in', ['draft','rejected'])]) index = False for emp in search_id: if rec.from_date <= emp.from_date or rec.from_date >= emp.to_date: if rec.to_date <= emp.from_date or rec.to_date >= emp.to_date: if not (rec.from_date <= emp.from_date and rec.to_date >= emp.to_date): index = True else: raise ValidationError("This reimbursement is already applied for this duration, please correct the dates") else: raise ValidationError("This reimbursement is already applied for this duration, please correct the dates") else: raise ValidationError("This reimbursement is already applied for this duration, please correct the dates") else: index = True if index == True: rec.claim_date = datetime.now().date() if rec.claim_date_from < rec.claim_date: if rec.name != 'briefcase': if rec.name == 'lunch' and int(rec.net_amount) <= 0: raise ValidationError( "Approved Amount must be greater than zero") elif rec.name == 'telephone' and int(rec.Approved_amount) <= 0: raise ValidationError( "Approved Amount must be greater than zero") elif rec.name == 'mobile' and int(rec.Approved_amount) <= 0: raise ValidationError( "Approved Amount must be greater than zero") elif rec.name == 'medical' and int(rec.total_amount) <= 0: raise ValidationError( "Total Amount must be greater than zero") elif rec.name == 'quarterly' and int(rec.amount_phone) <= 0: raise ValidationError( "Total Amount must be greater than zero") else: if rec.claim_date_from > rec.claim_date or rec.claim_date > rec.claim_date_to: gr_id = self.env['reimbursement.configuration'].search( [('name', '=', rec.name), ('group_ids.users', '=', self.env.user.id), ('open', '=', True)], order='name desc', limit=1) if gr_id: rec.write({'state': 'waiting_for_approval'}) else: raise ValidationError("You can claim for %s" % rec.name + " between %s" % rec.claim_date_from + " and %s" % rec.claim_date_to) else: rec.write({'state': 'waiting_for_approval'}) else: if int(rec.brief_amount) <= 0: raise ValidationError( "Amount must be greater than zero") else: rec.write({'state': 'waiting_for_approval'}) else: if rec.name != 'briefcase': raise ValidationError( "You are not allowed to take the future reimbursement") else: if int(rec.brief_amount) <= 0: raise ValidationError( "Amount must be greater than zero") else: rec.write({'state': 'waiting_for_approval'})
def saee_send_shipping(self, pickings): base_url = self.get_base_url(pickings) cod_amount = 0.0 # if (pickings.sale_id.payment_gateway_id and pickings.sale_id.payment_gateway_id.code in ["cod", "COD"]) or ( # pickings.sale_id.eg_magento_payment_method_id and pickings.sale_id.eg_magento_payment_method_id.code in [ # "cod", "COD"]): if (pickings.sale_id.eg_magento_payment_method_id and pickings.sale_id.eg_magento_payment_method_id.code in ["cod", "COD"]): if not pickings.invoice_id.residual and self.env.user.has_group( 'eg_send_to_shipper.send_to_shipper_restriction'): raise ValidationError( "Shipment Can not be created with 0 COD amount!!!") cod_amount = pickings.invoice_id.residual # if pickings.sale_id.payment_gateway_id and pickings.sale_id.payment_gateway_id.code in ["cod", "COD"]: # # cod_amount = pickings.sale_id.amount_total # # # # for inv in self.env['account.invoice'].search([('origin', '=', pickings.sale_id.name)]): # # if inv.state == "paid": # # cod_amount = cod_amount - inv.amount_total # # elif inv.state == "open": # # if inv.amount_total != inv.residual and inv.residual > 0: # # cod_amount = cod_amount - (inv.amount_total - inv.residual) # # Note: To take amount from newly generated invoice # cod_amount = pickings.invoice_id.residual if pickings and pickings.carrier_id.delivery_type == "saee": carrier_id = pickings.carrier_id else: carrier_id = self.env['delivery.carrier'].search( [('delivery_type', '=', 'saee')], limit=1) headers = {'Content-Type': "application/json;charset=utf-8"} partner_id = pickings.partner_id mobile = partner_id.mobile or partner_id.phone if not mobile: mobile = partner_id.parent_id.mobile or partner_id.parent_id.phone mobile2 = partner_id.phone or partner_id.mobile if not mobile2: mobile2 = partner_id.parent_id.phone or partner_id.parent_id.mobile c_city = partner_id.city or '' final_city = "" for t in c_city.split(): result = regex.sub(u'[^\p{Latin}]', u'', t) if final_city: final_city = final_city + " " + result else: final_city = result c_city = final_city payload = { "secret": carrier_id.saee_secret or False, "ordernumber": pickings.origin or '', "cashondelivery": cod_amount, "name": partner_id.name, "mobile": mobile or '', "mobile2": mobile2 or '', "streetaddress": partner_id.street, "streetaddress2": partner_id.street2 or '', # "city":partner_id.city, "city": c_city, "state": partner_id.state_id.name, "zipcode": partner_id.zip or '', "weight": pickings.shipping_weight or 1.0, "quantity": pickings.number_of_packages or 1, } res = requests.post("%snew" % base_url, json=payload, headers=headers) res.raise_for_status() data_dict = res.json() waybill = data_dict.get("waybill", False) if not waybill: raise Warning("%s" % data_dict) self.saee_print_waybill(data_dict.get('waybill'), cod_amount, base_url, pickings) return { 'exact_price': cod_amount, 'tracking_number': data_dict.get('waybill'), }
def _check_replaced_by_id(self): if not self._check_recursion(parent="replaced_by_id"): raise ValidationError( _('You cannot create recursive "Replaced by" chains.') )
def _check_demand_product_ids(self): for rec in self: if rec.demand_product_ids and rec.product_id not in rec.demand_product_ids: raise ValidationError( _("Buffered product must be considered as demand.") )
def _constrain_amount(self): for rec in self: if rec.amount <= 0.0: raise ValidationError(_('The amount must always be positive.'))
def check_dates(self): if self.filtered(lambda leave: leave.date_from > leave.date_to): raise ValidationError(_('The start date of the leave must be earlier end date.'))
def _check_time_efficiency(self): for record in self: if record.time_efficiency == 0: raise ValidationError(_('The efficiency factor cannot be equal to 0.'))
def _check_parent_id(self): if not self._check_recursion(): raise ValidationError(_('You cannot create a recursive salary structure.'))
def _check_parent_id(self): for employee in self: if not employee._check_recursion(): raise ValidationError( _('You cannot create a recursive hierarchy.'))
def _check_parent_id(self): if not self._check_recursion(): raise ValidationError(_('Error! You cannot create recursive hierarchy of Salary Rule Category.'))
def _check_parent_id(self): if not self._check_recursion(): raise ValidationError( _('You cannot create recursive departments.'))
def action_submit_sheet(self): if not self.user_id or not self.petty_cash_account_id: raise ValidationError(_("You must select a valid custodian and petty cash account.")) return super(HrExpenseSheet, self).action_submit_sheet()
def check_argentinian_invoice_taxes(self): """ We make theis function to be used as a constraint but also to be called from other models like vat citi """ # only check for argentinian localization companies _logger.info('Running checks related to argentinian documents') # we consider argentinian invoices the ones from companies with # localization localization and that belongs to a journal with # use_documents argentinian_invoices = self.filtered( lambda r: (r.localization == 'argentina' and r.use_documents)) if not argentinian_invoices: return True # check partner has responsability so it will be assigned on invoice # validate without_responsability = argentinian_invoices.filtered( lambda x: not x.commercial_partner_id.afip_responsability_type_id) if without_responsability: raise ValidationError( _('The following invoices has a partner without AFIP ' 'responsability:\r\n\r\n' '%s') % ('\r\n'.join([ '[%i] %s' % (i.id, i.display_name) for i in without_responsability ]))) # we check all invoice tax lines has tax_id related # we exclude exempt vats and untaxed (no gravados) wihtout_tax_id = argentinian_invoices.mapped('tax_line_ids').filtered( lambda r: not r.tax_id) if wihtout_tax_id: raise ValidationError( _("Some Invoice Tax Lines don't have a tax_id asociated, please " "correct them or try to refresh invoice. Tax lines: %s") % (', '.join(wihtout_tax_id.mapped('name')))) # check codes has argentinian tax attributes configured tax_groups = argentinian_invoices.mapped( 'tax_line_ids.tax_id.tax_group_id') unconfigured_tax_groups = tax_groups.filtered( lambda r: not r.type or not r.tax or not r.application) if unconfigured_tax_groups: raise ValidationError( _("You are using argentinian localization and there are some tax" " groups that are not configured. Tax Groups (id): %s" % (', '.join( unconfigured_tax_groups.mapped(lambda x: '%s (%s)' % (x.name, x.id)))))) # for invoice in argentinian_invoices: # # TODO usar round # # TODO tal vez debamos usar esto para un chequeo de suma de # # importes y demas, tener en cuenta caso de importaciones # # tal como esta este chequeo da error si se agregan impuestos # # manuales # if abs(invoice.vat_base_amount - invoice.amount_untaxed) > 0.1: # raise ValidationError(_( # "Invoice with ID %i has some lines without vat Tax ") % ( # invoice.id)) # verificamos facturas de compra que deben reportar cuit y no lo tienen # configurado without_cuit = argentinian_invoices.filtered( lambda x: x.type in ['in_invoice', 'in_refund' ] and x.document_type_id. purchase_cuit_required and not x.commercial_partner_id.cuit) if without_cuit: raise ValidationError( _('Las siguientes partners no tienen configurado CUIT: %s') % (', '.join(without_cuit.mapped('commercial_partner_id.name')))) # facturas que no debería tener ningún iva y tienen not_zero_alicuot = argentinian_invoices.filtered( lambda x: x.type in ['in_invoice', 'in_refund'] and x. document_type_id.purchase_alicuots == 'zero' and any( [t.tax_id.tax_group_id.afip_code != 0 for t in x.vat_tax_ids])) if not_zero_alicuot: raise ValidationError( _('Las siguientes facturas tienen configurados IVA incorrecto. ' 'Debe utilizar IVA no corresponde.\n*Facturas: %s') % (', '.join(not_zero_alicuot.mapped('display_name')))) # facturas que debería tener iva y tienen no corresponde zero_alicuot = argentinian_invoices.filtered( lambda x: x.type in ['in_invoice', 'in_refund'] and x. document_type_id.purchase_alicuots == 'not_zero' and any( [t.tax_id.tax_group_id.afip_code == 0 for t in x.vat_tax_ids])) if zero_alicuot: raise ValidationError( _('Las siguientes facturas tienen IVA no corresponde pero debe ' 'seleccionar una alícuota correcta (No gravado, Exento, Cero, ' '10,5, etc).\n*Facturas: %s') % (', '.join(zero_alicuot.mapped('display_name')))) # Check except vat invoice afip_exempt_codes = ['Z', 'X', 'E', 'N', 'C'] for invoice in argentinian_invoices: special_vat_taxes = invoice.tax_line_ids.filtered( lambda r: r.tax_id.tax_group_id.afip_code in [1, 2, 3]) if (special_vat_taxes and invoice.fiscal_position_id.afip_code not in afip_exempt_codes): raise ValidationError( _("If you have choose a 0, exempt or untaxed 'tax', or " "you must choose a fiscal position with afip code in %s.\n" "* Invoice [%i] %s") % (afip_exempt_codes, invoice.id, invoice.display_name)) # esto es, por eje, si hay un producto con 100% de descuento para # única alicuota, entonces el impuesto liquidado da cero y se # obliga reportar con alicuota 0, entonces se exige tmb cod de op. # esta restriccion no es de FE si no de aplicativo citi zero_vat_lines = invoice.tax_line_ids.filtered( lambda r: ((r.tax_id.tax_group_id.afip_code in [4, 5, 6, 8, 9] and r.currency_id.is_zero(r.amount)))) if (zero_vat_lines and invoice.fiscal_position_id.afip_code not in afip_exempt_codes): raise ValidationError( _("Si hay líneas con IVA declarado 0, entonces debe elegir " "una posición fiscal con código de afip '%s'.\n" "* Invoice [%i] %s") % (afip_exempt_codes, invoice.id, invoice.display_name))
def check_substate_id_consistency(self): for mixin_obj in self: if mixin_obj.substate_id and mixin_obj.substate_id.model != self._name: raise ValidationError( _("This substate is not define for this object but for %s") % mixin_obj.substate_id.model)
def create_bill(self): self.purchase_id.down_payment_by = self.down_payment_by self.purchase_id.amount = self.amount if self.purchase_id.down_payment_by in ['fixed', 'percentage']: if self.amount <= 0: raise ValidationError(_('''Amount must be positive''')) if self.purchase_id.down_payment_by == 'percentage': payment = self.purchase_id.amount_total * self.purchase_id.amount / 100 else: payment = self.amount if self.purchase_id.total_invoices_amount == 0: if payment > self.purchase_id.amount_total: raise ValidationError( _('''You are trying to pay: %s, but\n You can not pay more than: %s''' ) % (payment, self.purchase_id.amount_total)) if self.purchase_id.total_invoices_amount == self.purchase_id.amount_total: raise ValidationError( _('''Bills worth %s already created for this purchase order, check attached bills''' ) % (self.purchase_id.amount_total)) if self.purchase_id.total_invoices_amount > 0: remaining_amount = self.purchase_id.amount_total - self.purchase_id.total_invoices_amount if payment > remaining_amount: raise ValidationError( _('''You are trying to pay: %s, but\n You have already paid: %s for purchase order worth: %s''' ) % (payment, self.purchase_id.total_invoices_amount, self.purchase_id.amount_total)) if payment > self.purchase_id.amount_total: raise ValidationError( _('''You are trying to pay: %s, but\n You can not pay more than: %s''' ) % (payment, self.purchase_id.amount_total)) ir_param = self.env['ir.config_parameter'] product = ir_param.sudo().get_param( 'dev_purchase_down_payment.down_payment_product_id') journal_id = self.env['account.journal'].search( [('type', '=', 'purchase'), ('company_id', '=', self.purchase_id.company_id.id)], limit=1) if journal_id: self.purchase_id.dp_journal_id = journal_id.id else: raise ValidationError( _('''Please configure at least one Purchase Journal for %s Company''' ) % (self.purchase_id.company_id.name)) if not product: raise ValidationError( _('''Please configure Advance Payment Product into : Purchase > Settings''' )) action = self.env.ref('account.action_move_in_invoice_type') result = action.read()[0] create_bill = self.env.context.get('create_bill', False) # override the context to get rid of the default filtering result['context'] = { 'default_type': 'in_invoice', 'default_company_id': self.purchase_id.company_id.id, 'default_purchase_id': self.purchase_id.id, } # choose the view_mode accordingly if len(self.purchase_id.invoice_ids) > 1 and not create_bill: result['domain'] = "[('id', 'in', " + str( self.purchase_id.invoice_ids.ids) + ")]" else: res = self.env.ref('account.view_move_form', False) result['views'] = [(res and res.id or False, 'form')] # Do not set an invoice_id if we want to create a new bill. if not create_bill: result['res_id'] = self.purchase_id.invoice_ids.id or False result['context']['default_origin'] = self.purchase_id.name result['context']['default_reference'] = self.purchase_id.partner_ref return result
def _check_zip(self): for position in self: if self.zip_from and self.zip_to and position.zip_from > position.zip_to: raise ValidationError( _('Invalid "Zip Range", please configure it properly.'))
def _check_python_code(self): for r in self.sudo(): msg = test_python_expr(expr=r.template_post_init.strip(), mode="exec") if msg: raise ValidationError(msg)
def _check_company(self): if any(user.company_ids and user.company_id not in user.company_ids for user in self): raise ValidationError( _('The chosen company is not in the allowed companies for this user' ))
def _check_category_recursion(self): if not self._check_recursion(): raise ValidationError(_('You cannot create recursive categories.'))
def _validar_stock(self): if self.stock < 0: raise ValidationError('No hay suficiente stock')
def _check_parent_rule_id(self): if not self._check_recursion(parent='parent_rule_id'): raise ValidationError(_('Error! You cannot create recursive hierarchy of Salary Rules.'))
def unlink(self): for rec in self: if rec.irremovable: raise ValidationError('Vous ne pouvez pas supprimer ce tag') return super(AccountAnalyticTag, self).unlink()
def _unlink_except_master_data(self): time_product = self.env.ref('sale_timesheet.time_product') if time_product.product_tmpl_id in self: raise ValidationError( _('The %s product is required by the Timesheet app and cannot be archived/deleted.' ) % time_product.name)