OdooWiki OCA HUB

Romania - Stock Accounting Retail (Marfa in Magazin)

l10n_ro_stock_account_retail folder_open OCA/l10n-romania open_in_new
Localization Licencia: AGPL-3

Rumanía - Contabilidad de Stock Retail (Marfa in Magazin)

Implementa la contabilidad rumana de mercancías al por menor (gestiunea mărfurilor la preț de vânzare cu amănuntul), tal como se describe en la monografía estándar para el comercio minorista:

  • 371 Mărfuri — existencias valoradas a precio de venta al público con IVA
  • 378 Diferențe de preț la mărfuri — margen comercial (adaosul comercial)
  • 4428 TVA neexigibilă — IVA incluido en el precio de venta al público, aún no repercutido
  • 607 Cheltuieli privind mărfurile — coste de las mercancías vendidas
  • 707 Venituri din vânzarea mărfurilor — ingreso por venta al por menor (registrado desde el POS / factura de venta, no por este módulo)

Este es el núcleo de la familia: define qué es un punto de venta al por menor, de dónde procede el precio de estantería y cómo se registra el margen comercial. El documento de cambio de precio, los informes y el tratamiento del punto de venta residen en módulos propios:

  • l10n_ro_stock_account_retail_price_change — el documento de cambio de precio, su informe y el historial de precios en el producto
  • l10n_ro_stock_account_retail_report — informe de existencias al por menor
  • l10n_ro_stock_account_retail_landed_cost — mantiene 371 al precio de estantería cuando un coste en destino incrementa el coste
  • l10n_ro_stock_account_retail_price_difference — muestra lo que una factura de proveedor deja del margen comercial, antes de su registro
  • l10n_ro_stock_account_retail_picking_report — columnas de coste, margen comercial y precio de estantería en el albarán de recepción de mercancías
  • l10n_ro_stock_account_retail_pos — evita que el asiento de cierre del punto de venta descargue las existencias por segunda vez

Configuración

Un almacén al por menor se configura marcando Retail Warehouse en stock.warehouse y asignando una Retail Pricelist. Todas las ubicaciones internas bajo ese almacén se convierten automáticamente en ubicaciones al por menor.

Las cuentas de margen comercial (378) y de IVA diferido (4428) se resuelven en este orden:

  • stock.location.l10n_ro_account_markup_id / l10n_ro_account_deferred_vat_id, recorriendo hacia arriba las ubicaciones padre, de modo que una tienda se configura una vez y sus estanterías y huecos lo heredan
  • product.template.l10n_ro_account_markup_id / l10n_ro_account_deferred_vat_id (por compañía)
  • product.category.l10n_ro_account_markup_id / l10n_ro_account_deferred_vat_id (por compañía)
  • res.company.l10n_ro_account_markup_id / l10n_ro_account_deferred_vat_id (valores por defecto)

El precio de venta al público se mantiene con IVA incluido

Un precio en una lista de precios al por menor es el PVA: la cifra de la etiqueta de estantería, lo que paga el cliente y lo que soporta la cuenta 371. Los impuestos del producto se utilizan para desglosarlo en la base sobre la que se mide el margen comercial y el IVA diferido incluido en él — nunca para añadir IVA por encima.

Esos impuestos son los impuestos de venta del producto mapeados a través de la posición fiscal de la tienda (l10n_ro_fiscal_position_id en el almacén, la que la contabilidad de stock rumana ya utiliza para mapear las cuentas de valoración). Una compañía que vende tanto al por menor como B2B mantiene un único conjunto de impuestos en el producto y los mapea por tienda — a las variantes con IVA incluido con las que trabaja un TPV, o a otro tipo — y el IVA cargado en 4428 tiene que ser el que esa tienda realmente repercutirá. La misma posición fiscal mapea las tres cuentas que toca un asiento, de modo que una tienda que mantiene sus mercancías en un 371 propio lo declara una vez en lugar de sobrescribir cada producto, categoría y ubicación.

Un mapeo a las variantes con precio incluido de los mismos impuestos no cambia nada: el precio de estantería se lee como IVA incluido independientemente de lo que el impuesto diga de sí mismo, por lo que solo un cambio de tipo mueve el desglose.

Solo la parte de IVA de esos impuestos llega a 4428. Un cargo recaudado para otro — un depósito de envases (SGR), una tasa ecológica — se mantiene fuera del desglose y fuera del valor soportado en 371; nada en un impuesto indica si es IVA, así que marca esos con Not VAT (Retail) en el impuesto (en cada variante a la que una posición fiscal pueda mapear). Los impuestos de venta se tratan como IVA a menos que esté marcado.

El precio de estantería tiene que proceder de una regla en la lista de precios al por menor del almacén. No hay respaldo sobre el precio de venta del producto: ese es un precio sin IVA en una configuración rumana estándar, por lo que registrarlo como un PVA pondría la cifra equivocada en 371, subestimaría el margen comercial y calcularía el IVA diferido sobre una base distinta — silenciosamente. Un producto sin precio en la lista de precios al por menor de la tienda se rechaza en su lugar.

Flujo contable

El estándar l10n_ro_stock_account sigue registrando el coste. Este módulo añade el tramo del margen comercial cuando un stock.move cruza la frontera al por menor:

  • Hacia una ubicación al por menor: Dr 371 / Cr 378 (margen comercial) y Dr 371 / Cr 4428 (IVA)
  • Desde una ubicación al por menor: Dr 378 / Cr 371 y Dr 4428 / Cr 371
  • Entre dos almacenes al por menor: se registran ambos tramos, el origen liberando su propio margen comercial y el destino cargando el suyo. Una transferencia de varios pasos alcanza el mismo resultado por sí sola, al no ser la ubicación de tránsito una al por menor.
  • Los movimientos que permanecen dentro de un mismo almacén al por menor no registran nada.

Se rechaza un precio de estantería por debajo del coste, ya que registra un margen comercial negativo; una tienda que legítimamente vende por debajo del coste marca Allow Selling Below Cost en el almacén.

El libro mayor del margen comercial

Odoo 19 no tiene stock.valuation.layer: un movimiento soporta su coste en stock.move.value y nada más. El margen comercial y el IVA diferido que se sitúan entre el coste y el precio de estantería no tienen por tanto dónde residir, y recalcularlos desde la lista de precios actual cuando las mercancías salen es incorrecto en cuanto el precio se ha movido entretanto — la liberación no coincide con lo cargado, y la diferencia permanece en 378 y 4428 para siempre.

l10n.ro.retail.markup.line es el libro auxiliar que los mantiene. Cada evento que cambia lo que soporta 371 escribe una fila: un movimiento que cruza la frontera, un cambio de precio registrado, más adelante un coste en destino o una diferencia de precio de compra. Una liberación se toma siempre del saldo soportado, prorrateado sobre la cantidad que lo soporta — el coeficient de repartizare a adaosului comercial aplicado por movimiento — de modo que la última unidad que sale cierra ambas cuentas a cero.

Las devoluciones se liquidan contra el movimiento que devuelven, no contra el precio de hoy, de modo que una devolución de venta repone exactamente lo que la venta liberó.

El libro mayor es visible en Inventory → Reporting → Retail Markup Ledger, y stock.quant publica la parte soportada por cada quant junto a su coste.

Demo

demo/setup_demo.py construye una tienda al por menor rumana completa y la recorre por todos los casos que maneja la familia - transferencias, ventas, devoluciones, sububicaciones, una tienda de liquidación, cambios de precio, costes en destino, una diferencia de precio de compra, una sesión de punto de venta y ambos documentos imprimibles. Ejecútalo con odoo-bin shell -d < demo/setup_demo.py. Cada sección está protegida por el módulo que ejercita, por lo que se ejecuta solo con el núcleo y cubre más a medida que se instala más de la familia.

Traducción automática al español (DeepSeek) de la descripción original de OCA, que está en inglés.

auto_awesome Qué hace este módulo

Generado por IA a partir del código · Odoo 20.0

Añade contabilidad de mercancías minoristas rumanas a Odoo: las tiendas pueden mantener existencias a precio de estantería (IVA incluido) y Odoo registra automáticamente el margen comercial y el IVA diferido cuando las mercancías entran o salen de un almacén minorista.

Este módulo permite a una empresa rumana gestionar una tienda ("marfă în magazin") en la que el stock se lleva al precio de estantería, IVA incluido, en lugar de a coste. Un almacén se marca como Retail Warehouse y se le asigna una Retail Pricelist; el precio de estantería de cada producto debe provenir de una regla de precio de esa pricelist, de lo contrario Odoo rechaza el movimiento de stock con un mensaje claro.

Cuando las mercancías entran en una ubicación retail, Odoo divide el precio de estantería en coste, margen y IVA diferido y contabiliza el margen y el IVA en las cuentas configuradas en la ubicación, el producto, la categoría o la compañía (con la posición fiscal de la tienda aplicada). Cuando las mercancías salen, libera exactamente lo que se cargó, usando un libro mayor corriente, de modo que la última unidad que sale deja ambas cuentas a cero. Las devoluciones revierten los importes originales en lugar del precio de hoy.

  • Un nuevo informe "Retail Markup Ledger" (en Inventory reporting) lista cada apunte de margen e IVA diferido por producto, almacén y fecha.
  • Una pantalla "Retail Markup Opening Balance" (Inventory configuration) permite cargar el margen y el IVA iniciales del stock existente de la tienda y contabilizarlos.
  • Stock on hand muestra Retail Value, Markup y Deferred VAT para los responsables de stock.
  • Una opción de almacén "Allow Selling Below Cost" omite la comprobación que bloquea un precio de estantería inferior al coste.
  • Los impuestos de venta se pueden marcar como "Not VAT (Retail)" para que los depósitos o las tasas ecológicas queden fuera del desglose.

Afecta a productos, categorías de producto, ubicaciones, almacenes, movimientos de stock, stock on hand, impuestos y ajustes contables de la compañía.

Menús que añade

Retail Markup LedgerRetail Markup Opening Balance
Modelos y campos (12)
  • stock.move · amplía un modelo existentel10n_ro_retail_markup_line_ids (Retail Markup Ledger)
  • account.tax · amplía un modelo existentel10n_ro_retail_non_vat (Not VAT (Retail))
  • res.company · amplía un modelo existentel10n_ro_account_markup_id (Default Retail Markup Account (378)), l10n_ro_account_deferred_vat_id (Default Retail Deferred VAT Account (4428))
  • stock.quant · amplía un modelo existentel10n_ro_retail_value (Retail Value (371)), l10n_ro_retail_vat_value (Deferred VAT (4428)), l10n_ro_retail_markup_value (Markup (378))
  • stock.location · amplía un modelo existentel10n_ro_retail (Retail Location), l10n_ro_account_markup_id (Markup Account (378)), l10n_ro_account_deferred_vat_id (Deferred VAT Account (4428))
  • stock.warehouse · amplía un modelo existentel10n_ro_retail (Retail Warehouse), l10n_ro_retail_pricelist_id (Retail Pricelist), l10n_ro_retail_allow_negative_markup (Allow Selling Below Cost)
  • product.category · amplía un modelo existentel10n_ro_account_markup_id (Markup Account (378)), l10n_ro_account_deferred_vat_id (Deferred VAT Account (4428))
  • product.template · amplía un modelo existentel10n_ro_account_markup_id (Markup Account (378)), l10n_ro_account_deferred_vat_id (Deferred VAT Account (4428))
  • res.config.settings · amplía un modelo existentel10n_ro_account_markup_id, l10n_ro_account_deferred_vat_id
  • l10n.ro.retail.markup.line · modelo nuevovat (Deferred VAT (4428)), cost (Cost (371)), date, markup (Markup (378)), move_id (Stock Move), quantity, reference, company_id, product_id, location_id, origin_type, retail_value (Retail Value (371)), warehouse_id, account_move_id, company_currency_id
  • l10n.ro.retail.opening.balance · modelo nuevodate, line_ids (Lines), company_id, journal_id, has_shortfall, warehouse_ids (Shops)
  • l10n.ro.retail.opening.balance.line · modelo nuevovat (Deferred VAT (4428)), cost, markup (Markup (378)), quantity, wizard_id, below_cost (Priced Below Cost), company_id, price_unit (Shelf Price / Unit), product_id, currency_id, warehouse_id

Texto generado por IA (DeepSeek) al leer el código de la versión 20.0 en GitHub; puede contener errores, así que verifícalo en el código antes de decidir. El módulo es muy grande y solo se ha leído una parte del código. Ver el código en GitHub

Disponibilidad por versión

Revisado: 2026-11-03
Confirmado (verificado en repositorio y rama) Estimado (sin verificar) Sin información

Estado de confirmación: 2 confirmadas, 7 sin información de 9 versiones.

Fuentes · Odoo 20.0

Confirmado el 2026-11-03 en la rama 20.0 de OCA/l10n-romania.

terminal Instalación y uso

Sin información verificada

Las instrucciones de instalación, el paquete de distribución, las dependencias y los pasos de configuración no se muestran porque todavía no se han verificado en la documentación del módulo para ninguna versión.

info

Datos importados de GitHub: esta ficha refleja la última revisión del catálogo, no una consulta en directo. Verifica siempre en la documentación del módulo y en staging antes de instalar en producción.