Se rendre au contenu
Odoo Menu
  • Se connecter
  • Essai gratuit
  • Applications
    Finance
    • Comptabilité
    • Facturation
    • Notes de frais
    • Feuilles de calcul (BI)
    • Documents
    • Signature
    Ventes
    • CRM
    • Ventes
    • PdV Boutique
    • PdV Restaurant
    • Abonnements
    • Location
    Sites web
    • Site Web
    • eCommerce
    • Blog
    • Forum
    • Live Chat
    • eLearning
    Chaîne d'approvisionnement
    • Inventaire
    • Fabrication
    • PLM
    • Achats
    • Maintenance
    • Qualité
    Ressources Humaines
    • Employés
    • Recrutement
    • Congés
    • Évaluations
    • Recommandations
    • Parc automobile
    Marketing
    • Marketing Social
    • E-mail Marketing
    • SMS Marketing
    • Événements
    • Marketing Automation
    • Sondages
    Services
    • Projet
    • Feuilles de temps
    • Services sur Site
    • Assistance
    • Planification
    • Rendez-vous
    Productivité
    • Discussion
    • Intelligence artificielle
    • Internet des Objets
    • VoIP
    • Connaissances
    • WhatsApp
    Applications tierces Odoo Studio Plateforme Cloud d'Odoo
  • Industries
    Commerce de détail
    • Librairie
    • Magasin de vêtements
    • Magasin de meubles
    • Supermarché
    • Quincaillerie
    • Magasin de jouets
    Restauration & Hôtellerie
    • Bar et Pub
    • Restaurant
    • Fast-food
    • Maison d’hôtes
    • Distributeur de boissons
    • Hôtel
    Immobilier
    • Agence immobilière
    • Cabinet d'architecture
    • Construction
    • Gestion immobilière
    • Jardinage
    • Association de copropriétaires
    Consultance
    • Cabinet d'expertise comptable
    • Partenaire Odoo
    • Agence Marketing
    • Cabinet d'avocats
    • Aquisition de talents
    • Audit & Certification
    Fabrication
    • Textile
    • Métal
    • Meubles
    • Alimentation
    • Brasserie
    • Cadeaux d'entreprise
    Santé & Fitness
    • Club de sports
    • Opticien
    • Salle de fitness
    • Praticiens bien-être
    • Pharmacie
    • Salon de coiffure
    Commerce
    • Homme à tout faire
    • Matériel informatique & support
    • Systèmes photovoltaïques
    • Cordonnier
    • Services de nettoyage
    • Services CVC
    Autres
    • Organisation à but non lucratif
    • Agence environnementale
    • Location de panneaux d'affichage
    • Photographie
    • Leasing de vélos
    • Revendeur de logiciel
    Parcourir toutes les industries
  • Communauté
    Apprenez
    • Tutoriels
    • Documentation
    • Certifications
    • Formation
    • Blog
    • Podcast
    Renforcer l'éducation
    • Programme éducatif
    • Business Game Scale-Up!
    • Rendez-nous visite
    Obtenir le logiciel
    • Téléchargement
    • Comparez les éditions
    • Versions
    Collaborer
    • Github
    • Forum
    • Événements
    • Traductions
    • Devenir partenaire
    • Services pour partenaires
    • Enregistrer votre cabinet comptable
    Nos Services
    • Trouver un partenaire
    • Trouver un comptable
    • Rencontrer un conseiller
    • Services de mise en œuvre
    • Références clients
    • Assistance
    • Mises à niveau
    Github Youtube Twitter Linkedin Instagram Facebook Spotify
    +1 (650) 691-3277
    Obtenir une démonstration
  • Tarification
  • Aide
Vous devez être inscrit pour interagir avec la communauté.
Toutes les publications Personnes Badges
Étiquettes (Voir toutl)
odoo accounting v14 pos v15
À propos de ce forum
Vous devez être inscrit pour interagir avec la communauté.
Toutes les publications Personnes Badges
Étiquettes (Voir toutl)
odoo accounting v14 pos v15
À propos de ce forum
Aide

How to filter Barcode Wise Stock Report by Branch (Location) in Odoo18?

S'inscrire

Recevez une notification lorsqu'il y a de l'activité sur ce poste

Cette question a été signalée
report
1 Répondre
1914 Vues
Avatar
Ashilkrishna

Hi,

I have created a custom Barcode Wise Stock Report (Excel) using a wizard in Odoo.

The report is working correctly, but I need to filter the data based on selected branch (location).

🔹 Requirement:

  • Add a field in wizard to select branch (location)
  • When exporting Excel, it should show data only for selected branch
<?xml version="1.0" encoding="utf-8"?>
<odoo>

<!-- ================= FORM VIEW ================= -->

<record id="view_barcode_stock_report_form" model="ir.ui.view">
<field name="name">barcode.stock.report.form</field>
<field name="model">barcode.stock.report.wizard</field>
<field name="arch" type="xml">

<form string="Barcode Wise Stock Report">

<group>
<group>
<field name="from_date" required="1"/>
<field name="to_date" required="1"/>
<field name="categ_ids" widget="many2many_tags"/>
<field name="company_ids" widget="many2many_tags"/>
</group>
</group>

<footer>

<button name="action_export_excel"
type="object"
string="Export Excel"
class="btn-primary"/>

<button string="Cancel"
special="cancel"
class="btn-secondary"/>

</footer>

</form>

</field>
</record>

<!-- ================= ACTION ================= -->

<record id="action_barcode_stock_report" model="ir.actions.act_window">
<field name="name">Barcode Wise Stock Report</field>
<field name="res_model">barcode.stock.report.wizard</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>




<!-- ================= MENU ================= -->

<!-- Appears inside Inventory → Reporting -->

<menuitem id="menu_barcode_stock_report"
name="Barcode Wise Stock Report"
parent="stock.menu_warehouse_report"
action="action_barcode_stock_report"
sequence="52"/>




</odoo>
from odoo import models, fields, _
from odoo.exceptions import ValidationError
import io
import base64
import xlsxwriter
from datetime import datetime, time


class BarcodeStockReportWizard(models.TransientModel):
_name = 'barcode.stock.report.wizard'
_description = 'Barcode Wise Stock Report'

from_date = fields.Date(required=True)
to_date = fields.Date(required=True)

categ_ids = fields.Many2many('product.category', string="Categories")

# NEW FIELD (BRANCH FILTER)
location_ids = fields.Many2many(
'stock.location',
string="Branch",
domain=[('usage', '=', 'internal')]
)

file = fields.Binary()
file_name = fields.Char()

# -------------------------------------------------------
# VARIANT FETCH
# -------------------------------------------------------

def _get_variant_map(self, products):
variant_map = {}

for product in products:
size = ""
color = ""
batch = ""

for val in product.product_template_attribute_value_ids:
attr = val.attribute_id.name.lower()
value = val.product_attribute_value_id.name

if 'size' in attr:
size = value
elif 'color' in attr or 'colour' in attr:
color = value
elif 'batch' in attr:
batch = value

variant_map[product.id] = (size, color, batch)

return variant_map

# -------------------------------------------------------
# MAIN EXPORT
# -------------------------------------------------------

def action_export_excel(self):

if self.from_date > self.to_date:
raise ValidationError("From Date must be less than To Date.")

output = io.BytesIO()
workbook = xlsxwriter.Workbook(output, {'constant_memory': True})
sheet = workbook.add_worksheet("Barcode Stock")

bold = workbook.add_format({'bold': True})

headers = [
"BARCODE","ITEM","CODE","BATCH","MFG. DATE","UNIT",
"PURCHASE RATE","MRP","SELLING RATE","WHOLESALE RATE",
"OPENING STOCK","PURCHASE","SALE","SALES RETURN",
"CURRENT BALANCE","DAYS","SUPPLIER","BRAND","CATEGORY",
"ARTICLE NO","RANGE","DEPARTMENT","MATERIAL","TYPE",
"COLOUR","SIZE"
]

for col, header in enumerate(headers):
sheet.write(0, col, header, bold)
sheet.set_column(col, col, 22)

from_dt = datetime.combine(self.from_date, time.min)
to_dt = datetime.combine(self.to_date, time.max)

# ---------------------------------------------------
# PRODUCTS FILTER ( COMPANY ADDED)
# ---------------------------------------------------

domain = [
('barcode', '!=', False),
('product_tmpl_id.type', '=', 'consu'),
('can_be_expensed', '=', False),
]

if self.categ_ids:
domain.append(('categ_id', 'child_of', self.categ_ids.ids))



products = self.env['product.product']\
.with_context(prefetch_fields=False)\
.search(domain)

if not products:
raise ValidationError(_("No products found."))

product_ids = tuple(products.ids)
tmpl_ids = tuple(products.mapped('product_tmpl_id').ids)

variant_map = self._get_variant_map(products)

# ---------------------------------------------------
# WHOLESALE PRICE
# ---------------------------------------------------

wholesale_map = {}

if tmpl_ids:
self.env.cr.execute("""
SELECT DISTINCT ON (product_tmpl_id)
product_tmpl_id,
wholesale_price
FROM prepurchase_line
WHERE product_tmpl_id IN %s
ORDER BY product_tmpl_id, id DESC
""", [tmpl_ids])

for tmpl_id, price in self.env.cr.fetchall():
wholesale_map[tmpl_id] = price or 0.0

# ---------------------------------------------------
# STOCK QUERY ( COMPANY FILTER ADDED)
# ---------------------------------------------------

stock_map = {}

if product_ids:

company_ids = tuple(self.company_ids.ids)

self.env.cr.execute("""
SELECT
sm.product_id,

SUM(CASE
WHEN sm.date < %s
AND dest.usage='internal'
THEN sm.product_uom_qty ELSE 0 END)

-

SUM(CASE
WHEN sm.date < %s
AND src.usage='internal'
THEN sm.product_uom_qty ELSE 0 END)
AS opening,

SUM(CASE
WHEN sm.date >= %s
AND sm.date <= %s
AND dest.usage='internal'
THEN sm.product_uom_qty ELSE 0 END)
AS purchase,

SUM(CASE
WHEN sm.date >= %s
AND sm.date <= %s
AND src.usage='internal'
THEN sm.product_uom_qty ELSE 0 END)
AS sale,

SUM(CASE
WHEN sm.origin_returned_move_id IS NOT NULL
THEN sm.product_uom_qty ELSE 0 END)
AS return_qty

FROM stock_move sm
JOIN stock_location src ON sm.location_id = src.id
JOIN stock_location dest ON sm.location_dest_id = dest.id

WHERE sm.state='done'
AND sm.product_id IN %s
AND sm.company_id IN %s -- IMPORTANT FIX

GROUP BY sm.product_id
""", (
from_dt, from_dt,
from_dt, to_dt,
from_dt, to_dt,
product_ids,
company_ids
))

for pid, opening, purchase, sale, ret in self.env.cr.fetchall():
stock_map[pid] = {
'opening': opening or 0,
'purchase': purchase or 0,
'sale': sale or 0,
'return': ret or 0,
}

# ---------------------------------------------------
# EXCEL WRITE (UNCHANGED)
# ---------------------------------------------------

row = 1
today = fields.Date.today()

for product in products:

tmpl = product.product_tmpl_id
stock = stock_map.get(product.id, {})

opening = stock.get('opening', 0)
purchase = stock.get('purchase', 0)
sale = stock.get('sale', 0)
ret = stock.get('return', 0)

closing = opening + purchase + ret - sale

size, color, batch = variant_map.get(product.id, ("","",""))

supplier = tmpl.seller_ids[0].partner_id.name if tmpl.seller_ids else ""
wholesale = wholesale_map.get(tmpl.id, 0.0)

brand = product.brand_id.name if hasattr(product,'brand_id') and product.brand_id else ""
department = product.department_id.name if hasattr(product,'department_id') and product.department_id else ""
material = product.material_id.name if hasattr(product,'material_id') and product.material_id else ""

sheet.write_row(row, 0, [
product.barcode,
product.name,
"",
batch,
"",
product.uom_id.name,
product.standard_price,
tmpl.list_price,
tmpl.list_price,
wholesale,
opening,
purchase,
sale,
ret,
closing,
"",
supplier,
brand,
tmpl.categ_id.name,
getattr(tmpl,'article_no',""),
getattr(tmpl,'range',""),
department,
material,
getattr(tmpl,'type',""),
color,
size,
])

row += 1

workbook.close()
output.seek(0)

self.file = base64.b64encode(output.read())
self.file_name = "Barcode_Stock_Report.xlsx"

return {
'type': 'ir.actions.act_url',
'url': f'/web/content/?model=barcode.stock.report.wizard&id={self.id}&field=file&download=true&filename={self.file_name}',
'target': 'self',
}

🔹 Issue:

  • Report is showing data from all branches
  • Selected location is not affecting the result

How can I correctly filter stock data using selected location_ids/company_id?

0
Avatar
Ignorer
Avatar
Debbie
Meilleure réponse

Your location filter is declared in the XML but completely ignored in your Python code. That's why it does nothing.

The fix: Add the location domain to your stock_move SQL query.

In your SQL WHERE clause, add this condition:

AND (src.id IN %s OR dest.id IN %s)

Then pass tuple(self.location_ids.ids) twice as parameters (once for src, once for dest).

Corrected SQL snippet:

python

Then in your execute parameters, add:

tuple(self.location_ids.ids), tuple(self.location_ids.ids)

One more thing: If self.location_ids is empty, you should show all locations. Add this check before the SQL:

location_ids = tuple(self.location_ids.ids) if self.location_ids else tuple()

Then only add the location condition if location_ids is not empty.

Bottom line: Your wizard works. You just forgot to join the location filter into the stock move query. Fix that and your branch filter will work perfectly.

Would like to help you out on the issue.

0
Avatar
Ignorer
Vous appréciez la discussion ? Ne vous contentez pas de lire, rejoignez-nous !

Créez un compte dès aujourd'hui pour profiter de fonctionnalités exclusives et échanger avec notre formidable communauté !

S'inscrire
Publications associées Réponses Vues Activité
Bulk Invoice Print - Header and Footer Images Missing on Alternate Pages (Need Exact Copy of Existing Invoice Report)
report
Avatar
Avatar
1
juin 26
692
Report with a different footer in the first page. How to do it?
report
Avatar
Avatar
Avatar
3
avr. 26
3095
How to make snaking column layout for report ?
report
Avatar
0
oct. 24
4238
Report between 2 accounts
report
Avatar
0
août 24
3821
agregar un campo a etiqueta de producto.
report
Avatar
0
janv. 24
4082
Communauté
  • Tutoriels
  • Documentation
  • Forum
Open Source
  • Téléchargement
  • Github
  • Runbot
  • Traductions
Services
  • Hébergement Odoo.sh
  • Assistance
  • Migration
  • Développements personnalisés
  • Éducation
  • Trouver un comptable
  • Trouver un partenaire
  • Devenir partenaire
À propos
  • Notre société
  • Actifs de la marque
  • Contactez-nous
  • Emplois
  • Événements
  • Podcast
  • Blog
  • Clients
  • Informations légales • Confidentialité
  • Sécurité.
الْعَرَبيّة Català 简体中文 繁體中文 (台灣) Čeština Dansk Nederlands English Suomi Français Deutsch हिंदी Bahasa Indonesia Italiano 日本語 한국어 (KR) Lietuvių kalba Język polski Português (BR) română русский язык Slovenský jazyk Slovenščina Español (América Latina) Español Svenska ภาษาไทย Türkçe українська Tiếng Việt

Odoo est une suite d'applications open source couvrant tous les besoins de votre entreprise : CRM, eCommerce, Comptabilité, Inventaire, Point de Vente, Gestion de Projet, etc.

Le positionnement unique d'Odoo est d'être à la fois très facile à utiliser et totalement intégré.

Website made with

Odoo Experience on YouTube

1. Use the live chat to ask your questions.
2. The operator answers within a few minutes.

Live support on Youtube
Watch now