diff --git a/GEMINI.md b/GEMINI.md index 7a40a21..da0960e 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -240,4 +240,87 @@ Esto envía la cadena `"{'default_categ_id': ref(...)}"` al cliente, que no pued }"/> ``` Al usar `eval`, Odoo ejecuta la expresión en el servidor, reemplaza `ref(...)` por el ID numérico correspondiente, y envía un diccionario JSON válido al cliente. + +### Herencia de Vistas y XPath + +Al heredar vistas para modificarlas, es crucial que las expresiones `XPath` sean precisas. Un error común es hacer referencia a campos o estructuras que han cambiado en la nueva versión de Odoo. + +**Ejemplo de Error:** +Al intentar modificar las líneas de una orden de venta (`sale.order`), una expresión XPath que funcionaba en versiones anteriores puede fallar en Odoo 18. + +**Expresión Incorrecta (para Odoo < 18):** +```xml + + [('is_analysis', '=', True)] + ``` +Esta expresión falla por dos razones: +1. La vista de líneas ahora usa `` en lugar de ``. +2. El campo del producto en las líneas de venta es `product_id`, no `product_template_id`. + +**Expresión Correcta (para Odoo 18):** +Para hacer la expresión más robusta y compatible, se puede usar `//` para buscar en cualquier nivel descendiente. +```xml + + [('is_analysis', '=', True)] + +``` +Esta expresión busca el campo `product_id` dentro del campo `order_line`, sin importar si está dentro de una etiqueta `` o ``, haciendo la herencia más resistente a cambios menores de estructura. + +--- + +## Consultar la Base de Datos con un Script + +Interactuar con la base de datos directamente usando `psql` a través de `docker-compose exec` puede ser complicado debido a la forma en que el shell maneja las comillas. Una alternativa más robusta y confiable es utilizar un script de Python que aproveche el ORM de Odoo. + +### Procedimiento + +1. **Crear un Script de Python:** + Crea un script que se conecte a la base de datos y ejecute la consulta deseada. + + **Ejemplo (`verify_products.py`):** + ```python + import odoo + import json + + def verify_lab_order_products(cr): + cr.execute(""" + SELECT + so.name AS order_name, + sol.id AS line_id, + pt.name->>'en_US' AS product_name, + pt.is_analysis + FROM + sale_order so + JOIN + sale_order_line sol ON so.id = sol.order_id + JOIN + product_product pp ON sol.product_id = pp.id + JOIN + product_template pt ON pp.product_tmpl_id = pt.id + WHERE + so.is_lab_request = TRUE; + """) + return cr.fetchall() + + if __name__ == '__main__': + db_name = 'lims_demo' + registry = odoo.registry(db_name) + with registry.cursor() as cr: + results = verify_lab_order_products(cr) + print(json.dumps(results, indent=4)) + ``` + +2. **Copiar el Script al Contenedor:** + Usa el comando `docker cp` para copiar el script al contenedor de Odoo. + ```bash + docker cp verify_products.py lims_odoo:/tmp/verify_products.py + ``` + +3. **Ejecutar el Script:** + Ejecuta el script dentro del contenedor usando `docker-compose exec`. + ```bash + docker-compose exec odoo python3 /tmp/verify_products.py + ``` + +Este método evita los problemas de entrecomillado y permite ejecutar consultas complejas de manera confiable. diff --git a/create_lab_requests.py b/create_lab_requests.py new file mode 100644 index 0000000..227645e --- /dev/null +++ b/create_lab_requests.py @@ -0,0 +1,53 @@ +import odoo +import json + +def create_lab_requests(cr): + env = odoo.api.Environment(cr, odoo.SUPERUSER_ID, {}) + + # Delete unwanted demo sale orders + unwanted_orders = env['sale.order'].search([('name', 'in', ['S00001', 'S00002', 'S00003', 'S00004', 'S00005', 'S00006', 'S00007', 'S00008', 'S00009', 'S00010', 'S00011', 'S00012', 'S00013', 'S00014', 'S00015', 'S00016', 'S00017', 'S00018', 'S00019', 'S00020', 'S00021', 'S00022'])]) + for order in unwanted_orders: + try: + order.action_cancel() + except Exception: + pass + try: + unwanted_orders.unlink() + except Exception: + pass + + # Get patient and doctor + patient1 = env.ref('lims_management.demo_patient_1') + doctor1 = env.ref('lims_management.demo_doctor_1') + patient2 = env.ref('lims_management.demo_patient_2') + + # Get analysis products + hemograma = env.ref('lims_management.analysis_hemograma') + perfil_lipidico = env.ref('lims_management.analysis_perfil_lipidico') + + # Create Lab Request 1 + env['sale.order'].create({ + 'partner_id': patient1.id, + 'doctor_id': doctor1.id, + 'is_lab_request': True, + 'order_line': [ + (0, 0, {'product_id': hemograma.product_variant_id.id, 'product_uom_qty': 1}), + (0, 0, {'product_id': perfil_lipidico.product_variant_id.id, 'product_uom_qty': 1}) + ] + }) + + # Create Lab Request 2 + env['sale.order'].create({ + 'partner_id': patient2.id, + 'is_lab_request': True, + 'order_line': [ + (0, 0, {'product_id': hemograma.product_variant_id.id, 'product_uom_qty': 1}) + ] + }) + +if __name__ == '__main__': + db_name = 'lims_demo' + registry = odoo.registry(db_name) + with registry.cursor() as cr: + create_lab_requests(cr) + cr.commit() \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 3538b1c..51252a8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -24,6 +24,7 @@ services: - ./lims_management:/mnt/extra-addons/lims_management - ./odoo.conf:/etc/odoo/odoo.conf - ./init_odoo.py:/app/init_odoo.py + - ./create_lab_requests.py:/app/create_lab_requests.py command: ["/usr/bin/python3", "/app/init_odoo.py"] environment: HOST: db diff --git a/documents/logs/Quotation - S00021.pdf b/documents/logs/Quotation - S00021.pdf new file mode 100644 index 0000000..7787fae Binary files /dev/null and b/documents/logs/Quotation - S00021.pdf differ diff --git a/documents/logs/Quotation - S00022.pdf b/documents/logs/Quotation - S00022.pdf new file mode 100644 index 0000000..7a423fc Binary files /dev/null and b/documents/logs/Quotation - S00022.pdf differ diff --git a/documents/logs/producto.json b/documents/logs/producto.json new file mode 100644 index 0000000..21a115d --- /dev/null +++ b/documents/logs/producto.json @@ -0,0 +1,169 @@ +{ + "account_tag_ids": [], + "active": true, + "activity_date_deadline": false, + "activity_exception_decoration": false, + "activity_exception_icon": false, + "activity_ids": [], + "activity_state": false, + "activity_summary": false, + "activity_type_icon": false, + "activity_type_id": false, + "activity_user_id": false, + "analysis_type": false, + "attribute_line_ids": [], + "barcode": false, + "can_image_1024_be_zoomed": false, + "categ_id": [ + 10, + "All / Home Construction" + ], + "color": 0, + "combo_ids": [], + "company_id": false, + "cost_currency_id": [ + 1, + "USD" + ], + "cost_method": "standard", + "create_date": "2025-07-14 07:23:12", + "create_uid": [ + 1, + "OdooBot" + ], + "currency_id": [ + 1, + "USD" + ], + "default_code": false, + "description": false, + "description_picking": false, + "description_pickingin": false, + "description_pickingout": false, + "description_purchase": false, + "description_sale": false, + "display_name": "Furniture Assembly", + "expense_policy": "no", + "fiscal_country_codes": "US", + "has_available_route_ids": false, + "has_configurable_attributes": false, + "has_message": true, + "id": 29, + "image_1024": false, + "image_128": false, + "image_1920": false, + "image_256": false, + "image_512": false, + "incoming_qty": 0, + "invoice_policy": "order", + "is_analysis": false, + "is_favorite": false, + "is_product_variant": false, + "is_storable": false, + "list_price": 2000, + "location_id": false, + "lot_valuated": false, + "message_attachment_count": 0, + "message_follower_ids": [], + "message_has_error": false, + "message_has_error_counter": 0, + "message_has_sms_error": false, + "message_ids": [ + 188, + 114 + ], + "message_is_follower": false, + "message_needaction": false, + "message_needaction_counter": 0, + "message_partner_ids": [], + "my_activity_date_deadline": false, + "name": "Furniture Assembly", + "nbr_moves_in": 0, + "nbr_moves_out": 0, + "nbr_reordering_rules": 0, + "optional_product_ids": [], + "outgoing_qty": 0, + "packaging_ids": [], + "pricelist_item_count": 0, + "product_document_count": 0, + "product_document_ids": [], + "product_properties": [], + "product_tag_ids": [], + "product_tooltip": "Invoice ordered quantities as soon as this service is sold.", + "product_variant_count": 1, + "product_variant_id": [ + 38, + "Furniture Assembly" + ], + "product_variant_ids": [ + 38 + ], + "property_account_expense_id": false, + "property_account_income_id": false, + "property_stock_inventory": [ + 14, + "Virtual Locations/Inventory adjustment" + ], + "property_stock_production": [ + 15, + "Virtual Locations/Production" + ], + "purchase_ok": true, + "qty_available": 0, + "reordering_max_qty": 0, + "reordering_min_qty": 0, + "responsible_id": [ + 1, + "OdooBot" + ], + "route_from_categ_ids": [], + "route_ids": [], + "sale_delay": 0, + "sale_line_warn": "no-message", + "sale_line_warn_msg": false, + "sale_ok": true, + "sales_count": 0, + "seller_ids": [], + "sequence": 1, + "service_tracking": "no", + "service_type": "manual", + "show_forecasted_qty_status_button": false, + "show_on_hand_qty_status_button": false, + "standard_price": 2500, + "supplier_taxes_id": [], + "tax_string": " ", + "taxes_id": [], + "technical_specifications": false, + "tracking": "none", + "type": "service", + "uom_category_id": [ + 3, + "Working Time" + ], + "uom_id": [ + 4, + "Hours" + ], + "uom_name": "Hours", + "uom_po_id": [ + 4, + "Hours" + ], + "valid_product_template_attribute_line_ids": [], + "valuation": "manual_periodic", + "value_range_ids": [], + "variant_seller_ids": [], + "virtual_available": 0, + "visible_expense_policy": false, + "volume": 0, + "volume_uom_name": "m³", + "warehouse_id": false, + "website_message_ids": [], + "weight": 0, + "weight_uom_name": "kg", + "write_date": "2025-07-14 07:23:55", + "write_uid": [ + 1, + "OdooBot" + ] +} \ No newline at end of file diff --git a/documents/logs/s00021.json b/documents/logs/s00021.json new file mode 100644 index 0000000..ad1053f --- /dev/null +++ b/documents/logs/s00021.json @@ -0,0 +1,158 @@ +{ + "access_token": false, + "access_url": "/my/orders/21", + "access_warning": "", + "activity_date_deadline": false, + "activity_exception_decoration": false, + "activity_exception_icon": false, + "activity_ids": [], + "activity_state": false, + "activity_summary": false, + "activity_type_icon": false, + "activity_type_id": false, + "activity_user_id": false, + "amount_invoiced": 0, + "amount_paid": 0, + "amount_tax": 0, + "amount_to_invoice": 2589, + "amount_total": 2589, + "amount_undiscounted": 2589, + "amount_untaxed": 2589, + "authorized_transaction_ids": [], + "available_product_document_ids": [ + 2 + ], + "campaign_id": false, + "client_order_ref": false, + "commitment_date": false, + "company_id": [ + 1, + "My Company (San Francisco)" + ], + "company_price_include": "tax_excluded", + "country_code": "US", + "create_date": "2025-07-14 07:24:01", + "create_uid": [ + 1, + "OdooBot" + ], + "currency_id": [ + 1, + "USD" + ], + "currency_rate": 1, + "customizable_pdf_form_fields": false, + "date_order": "2025-07-14 07:24:02", + "delivery_count": 0, + "delivery_status": false, + "display_name": "S00021", + "doctor_id": [ + 46, + "Dr. Luis Herrera" + ], + "duplicated_order_ids": [], + "effective_date": false, + "expected_date": "2025-07-14 07:26:23", + "fiscal_position_id": false, + "has_active_pricelist": false, + "has_archived_products": false, + "has_message": true, + "id": 21, + "incoterm": false, + "incoterm_location": false, + "invoice_count": 0, + "invoice_ids": [], + "invoice_status": "no", + "is_expired": false, + "is_lab_request": true, + "is_pdf_quote_builder_available": true, + "journal_id": false, + "json_popover": "{\"popoverTemplate\": \"sale_stock.DelayAlertWidget\", \"late_elements\": []}", + "locked": false, + "medium_id": false, + "message_attachment_count": 0, + "message_follower_ids": [], + "message_has_error": false, + "message_has_error_counter": 0, + "message_has_sms_error": false, + "message_ids": [ + 310 + ], + "message_is_follower": false, + "message_needaction": false, + "message_needaction_counter": 0, + "message_partner_ids": [], + "my_activity_date_deadline": false, + "name": "S00021", + "note": false, + "order_line": [ + 45, + 46 + ], + "origin": false, + "partner_credit_warning": "", + "partner_id": [ + 44, + "Ana Torres" + ], + "partner_invoice_id": [ + 44, + "Ana Torres" + ], + "partner_shipping_id": [ + 44, + "Ana Torres" + ], + "payment_term_id": false, + "pending_email_template_id": false, + "picking_ids": [], + "picking_policy": "direct", + "prepayment_percent": 1, + "pricelist_id": false, + "procurement_group_id": false, + "quotation_document_ids": [], + "reference": false, + "require_payment": true, + "require_signature": true, + "sale_order_option_ids": [], + "sale_order_template_id": false, + "show_json_popover": false, + "show_update_fpos": false, + "show_update_pricelist": false, + "signature": false, + "signed_by": false, + "signed_on": false, + "source_id": false, + "state": "draft", + "tag_ids": [], + "tax_calculation_rounding_method": "round_per_line", + "tax_country_id": [ + 233, + "United States" + ], + "tax_totals": { + "currency_id": 1 + }, + "team_id": [ + 1, + "Sales" + ], + "terms_type": "plain", + "transaction_ids": [], + "type_name": "Quotation", + "user_id": [ + 1, + "OdooBot" + ], + "validity_date": "2025-08-13", + "warehouse_id": [ + 1, + "YourCompany" + ], + "website_message_ids": [], + "write_date": "2025-07-14 07:24:04", + "write_uid": [ + 1, + "OdooBot" + ] +} \ No newline at end of file diff --git a/documents/metadata.json b/documents/metadata.json new file mode 100644 index 0000000..62826b2 --- /dev/null +++ b/documents/metadata.json @@ -0,0 +1,650 @@ +{ + "sale_order": [ + [ + "id", + "integer" + ], + [ + "message_main_attachment_id", + "integer" + ], + [ + "access_token", + "character varying" + ], + [ + "name", + "character varying" + ], + [ + "origin", + "character varying" + ], + [ + "client_order_ref", + "character varying" + ], + [ + "reference", + "character varying" + ], + [ + "state", + "character varying" + ], + [ + "date_order", + "timestamp without time zone" + ], + [ + "validity_date", + "date" + ], + [ + "commitment_date", + "timestamp without time zone" + ], + [ + "expected_date", + "timestamp without time zone" + ], + [ + "user_id", + "integer" + ], + [ + "partner_id", + "integer" + ], + [ + "partner_invoice_id", + "integer" + ], + [ + "partner_shipping_id", + "integer" + ], + [ + "pricelist_id", + "integer" + ], + [ + "currency_id", + "integer" + ], + [ + "analytic_account_id", + "integer" + ], + [ + "order_line", + "integer" + ], + [ + "invoice_count", + "integer" + ], + [ + "invoice_status", + "character varying" + ], + [ + "note", + "text" + ], + [ + "amount_untaxed", + "numeric" + ], + [ + "amount_tax", + "numeric" + ], + [ + "amount_total", + "numeric" + ], + [ + "currency_rate", + "numeric" + ], + [ + "payment_term_id", + "integer" + ], + [ + "fiscal_position_id", + "integer" + ], + [ + "company_id", + "integer" + ], + [ + "team_id", + "integer" + ], + [ + "signature", + "text" + ], + [ + "signed_by", + "character varying" + ], + [ + "signed_on", + "timestamp without time zone" + ], + [ + "create_uid", + "integer" + ], + [ + "create_date", + "timestamp without time zone" + ], + [ + "write_uid", + "integer" + ], + [ + "write_date", + "timestamp without time zone" + ], + [ + "sale_order_template_id", + "integer" + ], + [ + "incoterm", + "integer" + ], + [ + "picking_policy", + "character varying" + ], + [ + "warehouse_id", + "integer" + ], + [ + "procurement_group_id", + "integer" + ], + [ + "campaign_id", + "integer" + ], + [ + "medium_id", + "integer" + ], + [ + "source_id", + "integer" + ], + [ + "delivery_count", + "integer" + ], + [ + "is_lab_request", + "boolean" + ], + [ + "doctor_id", + "integer" + ] + ], + "sale_order_line": [ + [ + "id", + "integer" + ], + [ + "order_id", + "integer" + ], + [ + "name", + "text" + ], + [ + "sequence", + "integer" + ], + [ + "invoice_status", + "character varying" + ], + [ + "price_unit", + "numeric" + ], + [ + "price_subtotal", + "numeric" + ], + [ + "price_tax", + "double precision" + ], + [ + "price_total", + "numeric" + ], + [ + "price_reduce", + "numeric" + ], + [ + "tax_id", + "integer" + ], + [ + "price_reduce_taxinc", + "numeric" + ], + [ + "price_reduce_taxexcl", + "numeric" + ], + [ + "discount", + "numeric" + ], + [ + "product_id", + "integer" + ], + [ + "product_template_id", + "integer" + ], + [ + "product_uom_category_id", + "integer" + ], + [ + "product_uom", + "integer" + ], + [ + "product_uom_qty", + "numeric" + ], + [ + "product_uom_readonly", + "boolean" + ], + [ + "qty_delivered_method", + "character varying" + ], + [ + "qty_delivered", + "numeric" + ], + [ + "qty_delivered_manual", + "numeric" + ], + [ + "qty_to_invoice", + "numeric" + ], + [ + "qty_invoiced", + "numeric" + ], + [ + "untaxed_amount_invoiced", + "numeric" + ], + [ + "untaxed_amount_to_invoice", + "numeric" + ], + [ + "salesman_id", + "integer" + ], + [ + "currency_id", + "integer" + ], + [ + "company_id", + "integer" + ], + [ + "order_partner_id", + "integer" + ], + [ + "is_expense", + "boolean" + ], + [ + "is_downpayment", + "boolean" + ], + [ + "state", + "character varying" + ], + [ + "customer_lead", + "double precision" + ], + [ + "display_type", + "character varying" + ], + [ + "create_uid", + "integer" + ], + [ + "create_date", + "timestamp without time zone" + ], + [ + "write_uid", + "integer" + ], + [ + "write_date", + "timestamp without time zone" + ], + [ + "analytic_distribution", + "jsonb" + ], + [ + "analytic_line_ids", + "integer" + ], + [ + "is_service", + "boolean" + ], + [ + "sale_order_option_ids", + "integer" + ], + [ + "linked_line_id", + "integer" + ], + [ + "product_packaging_id", + "integer" + ], + [ + "product_packaging_qty", + "numeric" + ], + [ + "product_packaging_description", + "text" + ] + ], + "product_template": [ + [ + "id", + "integer" + ], + [ + "message_main_attachment_id", + "integer" + ], + [ + "sequence", + "integer" + ], + [ + "name", + "jsonb" + ], + [ + "description", + "jsonb" + ], + [ + "description_purchase", + "text" + ], + [ + "description_sale", + "jsonb" + ], + [ + "type", + "character varying" + ], + [ + "categ_id", + "integer" + ], + [ + "currency_id", + "integer" + ], + [ + "cost_currency_id", + "integer" + ], + [ + "list_price", + "numeric" + ], + [ + "volume", + "double precision" + ], + [ + "weight", + "double precision" + ], + [ + "sale_ok", + "boolean" + ], + [ + "purchase_ok", + "boolean" + ], + [ + "uom_id", + "integer" + ], + [ + "uom_po_id", + "integer" + ], + [ + "company_id", + "integer" + ], + [ + "active", + "boolean" + ], + [ + "color", + "integer" + ], + [ + "default_code", + "character varying" + ], + [ + "can_image_1024_be_zoomed", + "boolean" + ], + [ + "create_uid", + "integer" + ], + [ + "create_date", + "timestamp without time zone" + ], + [ + "write_uid", + "integer" + ], + [ + "write_date", + "timestamp without time zone" + ], + [ + "service_type", + "character varying" + ], + [ + "sale_line_warn", + "character varying" + ], + [ + "sale_line_warn_msg", + "text" + ], + [ + "expense_policy", + "character varying" + ], + [ + "visible_expense_policy", + "boolean" + ], + [ + "invoice_policy", + "character varying" + ], + [ + "sale_delay", + "double precision" + ], + [ + "tracking", + "character varying" + ], + [ + "description_picking", + "text" + ], + [ + "description_pickingout", + "text" + ], + [ + "description_pickingin", + "text" + ], + [ + "responsible_id", + "integer" + ], + [ + "property_stock_production", + "integer" + ], + [ + "property_stock_inventory", + "integer" + ], + [ + "service_tracking", + "character varying" + ], + [ + "is_analysis", + "boolean" + ], + [ + "analysis_type", + "character varying" + ], + [ + "technical_specifications", + "text" + ] + ], + "product_product": [ + [ + "id", + "integer" + ], + [ + "message_main_attachment_id", + "integer" + ], + [ + "product_tmpl_id", + "integer" + ], + [ + "default_code", + "character varying" + ], + [ + "barcode", + "character varying" + ], + [ + "combination_indices", + "character varying" + ], + [ + "volume", + "double precision" + ], + [ + "weight", + "double precision" + ], + [ + "active", + "boolean" + ], + [ + "can_be_expensed", + "boolean" + ], + [ + "create_uid", + "integer" + ], + [ + "create_date", + "timestamp without time zone" + ], + [ + "write_uid", + "integer" + ], + [ + "write_date", + "timestamp without time zone" + ], + [ + "lst_price", + "numeric" + ], + [ + "standard_price", + "numeric" + ], + [ + "property_stock_production", + "integer" + ], + [ + "property_stock_inventory", + "integer" + ] + ] +} diff --git a/get_metadata.py b/get_metadata.py new file mode 100644 index 0000000..181744f --- /dev/null +++ b/get_metadata.py @@ -0,0 +1,21 @@ +import odoo +import json + +def get_table_metadata(cr, table_name): + cr.execute(""" + SELECT column_name, data_type + FROM information_schema.columns + WHERE table_name = %s + """, (table_name,)) + return cr.fetchall() + +if __name__ == '__main__': + db_name = 'lims_demo' + registry = odoo.registry(db_name) + with registry.cursor() as cr: + metadata = {} + tables = ['sale_order', 'sale_order_line', 'product_template', 'product_product'] + for table in tables: + metadata[table] = get_table_metadata(cr, table) + + print(json.dumps(metadata, indent=4)) diff --git a/init_odoo.py b/init_odoo.py index ba8762c..5c0d251 100644 --- a/init_odoo.py +++ b/init_odoo.py @@ -58,7 +58,46 @@ try: sys.exit(result.returncode) print("Inicialización de Odoo completada exitosamente.") - sys.exit(0) + + # --- Lógica para crear datos de demostración personalizados --- + print("Creando solicitudes de laboratorio de demostración...") + sys.stdout.flush() + + with open("/app/create_lab_requests.py", "r") as f: + script_content = f.read() + + # Reutilizamos el entorno de Odoo para ejecutar un script + create_requests_command = f""" + odoo shell -c {ODOO_CONF} -d {DB_NAME} <<'EOF' +{script_content} +EOF + """ + + try: + result = subprocess.run( + create_requests_command, + shell=True, + capture_output=True, + text=True, + check=False + ) + + print("--- Create Lab Requests stdout ---") + print(result.stdout) + print("--- Create Lab Requests stderr ---") + print(result.stderr) + sys.stdout.flush() + + if result.returncode != 0: + print(f"Fallo al crear las solicitudes de laboratorio con código de salida {result.returncode}") + sys.exit(result.returncode) + + print("Solicitudes de laboratorio de demostración creadas exitosamente.") + sys.exit(0) + + except Exception as e: + print(f"Ocurrió un error inesperado al crear las solicitudes de laboratorio: {e}") + sys.exit(1) except FileNotFoundError: print("Error: El comando 'odoo' no se encontró. Asegúrate de que la imagen del contenedor es correcta y odoo está en el PATH.") diff --git a/lims_management/__manifest__.py b/lims_management/__manifest__.py index 00cceeb..b17245a 100644 --- a/lims_management/__manifest__.py +++ b/lims_management/__manifest__.py @@ -16,7 +16,7 @@ 'website': "https://gitea.grupoconsiti.com/luis_portillo/clinical_laboratory", 'category': 'Industries', 'version': '18.0.1.0.0', - 'depends': ['base', 'product'], + 'depends': ['base', 'product', 'sale'], 'data': [ 'security/lims_security.xml', 'security/ir.model.access.csv', @@ -24,11 +24,12 @@ 'data/product_category.xml', 'views/partner_views.xml', 'views/analysis_views.xml', + 'views/sale_order_views.xml', 'views/menus.xml', ], 'demo': [ - 'demo/lims_demo.xml', - 'demo/analysis_demo.xml', + 'demo/z_lims_demo.xml', + 'demo/z_analysis_demo.xml', ], 'installable': True, 'application': True, diff --git a/lims_management/data/sale_demo_cleanup.xml b/lims_management/data/sale_demo_cleanup.xml new file mode 100644 index 0000000..fc38641 --- /dev/null +++ b/lims_management/data/sale_demo_cleanup.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/lims_management/demo/analysis_demo.xml b/lims_management/demo/z_analysis_demo.xml similarity index 100% rename from lims_management/demo/analysis_demo.xml rename to lims_management/demo/z_analysis_demo.xml diff --git a/lims_management/demo/lims_demo.xml b/lims_management/demo/z_lims_demo.xml similarity index 100% rename from lims_management/demo/lims_demo.xml rename to lims_management/demo/z_lims_demo.xml diff --git a/lims_management/models/__init__.py b/lims_management/models/__init__.py index cdf3ffc..4ffd5f7 100644 --- a/lims_management/models/__init__.py +++ b/lims_management/models/__init__.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- from . import partner from . import product -from . import analysis_range \ No newline at end of file +from . import analysis_range +from . import sale_order \ No newline at end of file diff --git a/lims_management/models/__pycache__/__init__.cpython-312.pyc b/lims_management/models/__pycache__/__init__.cpython-312.pyc index ddb34cf..51f1d65 100644 Binary files a/lims_management/models/__pycache__/__init__.cpython-312.pyc and b/lims_management/models/__pycache__/__init__.cpython-312.pyc differ diff --git a/lims_management/models/__pycache__/analysis_range.cpython-312.pyc b/lims_management/models/__pycache__/analysis_range.cpython-312.pyc index dc8ed33..5cdb964 100644 Binary files a/lims_management/models/__pycache__/analysis_range.cpython-312.pyc and b/lims_management/models/__pycache__/analysis_range.cpython-312.pyc differ diff --git a/lims_management/models/__pycache__/partner.cpython-312.pyc b/lims_management/models/__pycache__/partner.cpython-312.pyc index 8282316..cb379f7 100644 Binary files a/lims_management/models/__pycache__/partner.cpython-312.pyc and b/lims_management/models/__pycache__/partner.cpython-312.pyc differ diff --git a/lims_management/models/__pycache__/product.cpython-312.pyc b/lims_management/models/__pycache__/product.cpython-312.pyc index 6e5e283..b04b788 100644 Binary files a/lims_management/models/__pycache__/product.cpython-312.pyc and b/lims_management/models/__pycache__/product.cpython-312.pyc differ diff --git a/lims_management/models/__pycache__/sale_order.cpython-312.pyc b/lims_management/models/__pycache__/sale_order.cpython-312.pyc new file mode 100644 index 0000000..82b79cf Binary files /dev/null and b/lims_management/models/__pycache__/sale_order.cpython-312.pyc differ diff --git a/lims_management/models/sale_order.py b/lims_management/models/sale_order.py new file mode 100644 index 0000000..a9217b4 --- /dev/null +++ b/lims_management/models/sale_order.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from odoo import models, fields + +class SaleOrder(models.Model): + _inherit = 'sale.order' + + is_lab_request = fields.Boolean( + string="Is a Laboratory Request", + default=False, + copy=False, + help="Technical field to identify if the sale order is a laboratory request." + ) + + doctor_id = fields.Many2one( + 'res.partner', + string="Referring Doctor", + domain="[('is_doctor', '=', True)]", + help="The doctor who referred the patient for this laboratory request." + ) diff --git a/lims_management/security/ir.model.access.csv b/lims_management/security/ir.model.access.csv index c12dc28..a326f43 100644 --- a/lims_management/security/ir.model.access.csv +++ b/lims_management/security/ir.model.access.csv @@ -1,2 +1,3 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_lims_analysis_range_user,lims.analysis.range.user,model_lims_analysis_range,base.group_user,1,1,1,1 +access_sale_order_receptionist,sale.order.receptionist,sale.model_sale_order,group_lims_receptionist,1,1,1,0 diff --git a/lims_management/views/menus.xml b/lims_management/views/menus.xml index e4dc041..678716b 100644 --- a/lims_management/views/menus.xml +++ b/lims_management/views/menus.xml @@ -53,6 +53,28 @@ action="action_lims_doctor" sequence="30"/> + + + Solicitudes de Laboratorio + sale.order + list,form + [('is_lab_request', '=', True)] + {'default_is_lab_request': True} + + + Crea una nueva solicitud de laboratorio + + + + + + + + + + + + + sale.order.form.inherit.lims + sale.order + + + + + + + Paciente + + + [('is_analysis', '=', True)] + + + + + + + sale.order.tree.inherit.lims + sale.order + + + + + + + + + + diff --git a/verify_products.py b/verify_products.py new file mode 100644 index 0000000..a2b3a4f --- /dev/null +++ b/verify_products.py @@ -0,0 +1,30 @@ +import odoo +import json + +def verify_lab_order_products(cr): + cr.execute(""" + SELECT + so.name AS order_name, + sol.id AS line_id, + pt.name->>'en_US' AS product_name, + pt.is_analysis + FROM + sale_order so + JOIN + sale_order_line sol ON so.id = sol.order_id + JOIN + product_product pp ON sol.product_id = pp.id + JOIN + product_template pt ON pp.product_tmpl_id = pt.id + WHERE + so.is_lab_request = TRUE; + """) + return cr.fetchall() + +if __name__ == '__main__': + db_name = 'lims_demo' + registry = odoo.registry(db_name) + with registry.cursor() as cr: + results = verify_lab_order_products(cr) + + print(json.dumps(results, indent=4))
+ Crea una nueva solicitud de laboratorio +