# Generated by Django 5.2.8 on 2026-05-21 13:51 import common.storages import django.contrib.gis.db.models.fields import django.db.models.deletion import django.utils.timezone import stock.models import uuid from django.conf import settings from django.db import migrations, models class Migration(migrations.Migration): initial = True dependencies = [ ('contracts', '0001_initial'), ('interventions', '0001_initial'), ('sign', '0001_initial'), migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( name='Product', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('code', models.CharField(max_length=100, unique=True)), ('name', models.CharField(max_length=200)), ('sku', models.CharField(max_length=100, unique=True)), ('description', models.TextField(blank=True, null=True)), ('price', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True)), ('unit', models.CharField(choices=[('pc', 'Pièce(s)'), ('kg', 'Kilogramme(s)'), ('g', 'Gramme(s)'), ('t', 'Tonne(s)'), ('L', 'Litre(s)'), ('m', 'Mètre(s)'), ('m2', 'Mètre(s) carré(s)'), ('m3', 'Mètre(s) cube(s)')], default='pc', max_length=10, verbose_name='Unité')), ('threshold', models.IntegerField(default=10)), ('total_stock', models.IntegerField(default=0)), ('reserved_quantity', models.IntegerField(default=0)), ('qr_code', models.ImageField(blank=True, null=True, upload_to='stock/qrcodes/products/', verbose_name='QR Code')), ('is_serialized', models.BooleanField(default=False, help_text='Si activé, chaque article de ce produit devra avoir un numéro de série unique.', verbose_name='Articles tracés (numéro de série)')), ], ), migrations.CreateModel( name='ProductCategory', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('code', models.CharField(max_length=100, unique=True)), ('name_fr', models.CharField(max_length=100, unique=True)), ('name_en', models.CharField(blank=True, max_length=100, null=True, unique=True)), ('name_nl', models.CharField(blank=True, max_length=100, null=True, unique=True)), ('description', models.TextField(blank=True, null=True)), ], ), migrations.CreateModel( name='PurchaseOrder', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('code', models.CharField(blank=True, max_length=50, unique=True)), ('uuid', models.UUIDField(default=uuid.uuid4, editable=False)), ('date_ordered', models.DateField(auto_now_add=True)), ('status', models.CharField(choices=[('pending', 'En attente'), ('ordered', 'Envoyée'), ('partial', 'Partiellement reçue'), ('received', 'Reçue'), ('cancelled', 'Annulée')], default='pending', max_length=50, verbose_name='Statut')), ('received_at', models.DateTimeField(blank=True, null=True)), ], options={ 'ordering': ('-date_ordered', '-id'), }, ), migrations.CreateModel( name='Supplier', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=200)), ('contact_email', models.EmailField(blank=True, max_length=254, null=True)), ('phone_number', models.CharField(blank=True, max_length=20, null=True)), ('address', models.TextField(blank=True, null=True)), ('is_active', models.BooleanField(default=True)), ('enterprise_number', models.CharField(blank=True, max_length=100, null=True)), ], options={ 'verbose_name': 'Fournisseur', 'verbose_name_plural': 'Fournisseurs', 'ordering': ('name',), }, ), migrations.CreateModel( name='Warehouse', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('code', models.CharField(max_length=100, unique=True)), ('name', models.CharField(max_length=100, unique=True)), ('location', models.TextField(blank=True, null=True)), ('description', models.TextField(blank=True, null=True)), ('manager', models.CharField(max_length=200)), ('lon', models.FloatField(blank=True, null=True)), ('lat', models.FloatField(blank=True, null=True)), ('geom', django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=3812)), ], options={ 'verbose_name': 'Entrepôt', 'verbose_name_plural': 'Entrepôts', 'ordering': ('name',), }, ), migrations.CreateModel( name='PreparationOrder', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('order_number', models.CharField(max_length=100, unique=True)), ('date', models.DateTimeField(auto_now_add=True)), ('status', models.CharField(choices=[('to_process', 'A traiter'), ('pending', 'En attente'), ('processed', 'Traité'), ('cancelled', 'Annulé')], default='to_process', max_length=50)), ('requester', models.CharField(blank=True, help_text="Personne ou service à l'origine de la demande", max_length=255, null=True, verbose_name='Demandeur')), ('qr_code', models.ImageField(blank=True, null=True, upload_to='stock/qrcodes/preparation_orders/', verbose_name='QR Code')), ('intervention', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='preparation_orders', to='interventions.intervention', verbose_name='Intervention')), ], ), migrations.CreateModel( name='PreparationOrderDocument', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('file', models.FileField(storage=common.storages.PrivateMediaStorage(), upload_to=stock.models.preparation_order_document_upload_path, verbose_name='Fichier')), ('name', models.CharField(blank=True, max_length=255, verbose_name='Nom')), ('uploaded_at', models.DateTimeField(auto_now_add=True)), ('preparation_order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='documents', to='stock.preparationorder', verbose_name='Bon de préparation')), ], ), migrations.CreateModel( name='PreparationOrderItem', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('quantity', models.IntegerField()), ('is_prepared', models.BooleanField(default=False)), ('quantity_modified', models.BooleanField(default=False, help_text="Indique que la quantité a été modifiée après que l'article ait été marqué comme préparé.", verbose_name='Quantité modifiée')), ('previous_quantity', models.IntegerField(blank=True, help_text='Ancienne quantité avant modification (pour information du magasinier).', null=True, verbose_name='Quantité précédente')), ('preparation_order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='stock.preparationorder')), ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='stock.product')), ], ), migrations.AddField( model_name='preparationorder', name='items', field=models.ManyToManyField(through='stock.PreparationOrderItem', to='stock.product'), ), migrations.AddField( model_name='product', name='category', field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='products', to='stock.productcategory'), ), migrations.CreateModel( name='PreparationOrderOtherItem', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('description', models.TextField(verbose_name='Description')), ('quantity', models.IntegerField(default=1, verbose_name='Quantité')), ('is_prepared', models.BooleanField(default=False, verbose_name='Préparé')), ('preparation_order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='other_items', to='stock.preparationorder')), ('sign_panel_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='sign.signpaneltype', verbose_name='Type de panneau')), ('category', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='stock.productcategory', verbose_name='Catégorie')), ], ), migrations.CreateModel( name='ProductionOrder', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('code', models.CharField(blank=True, max_length=100, unique=True)), ('quantity', models.IntegerField(default=1, help_text="Nombre d'unités à concevoir")), ('status', models.CharField(choices=[('draft', 'Brouillon'), ('to_process', 'À traiter'), ('in_production', 'En confection'), ('completed', 'Terminé'), ('cancelled', 'Annulé')], default='to_process', max_length=20)), ('destination', models.CharField(choices=[('internal', 'Interne'), ('external', 'Externe')], default='internal', help_text="Indiquer si la confection est destinée à l'usage interne ou externe.", max_length=20, verbose_name='Destination')), ('notes', models.TextField(blank=True, null=True)), ('created_at', models.DateTimeField(auto_now_add=True)), ('updated_at', models.DateTimeField(auto_now=True)), ('completed_at', models.DateTimeField(blank=True, null=True)), ('qr_code', models.ImageField(blank=True, null=True, upload_to='stock/qrcodes/conception_orders/', verbose_name='QR Code')), ('output_product_name', models.CharField(blank=True, help_text="Nom du nouveau produit à créer si 'Produit fini à stocker' n'est pas sélectionné.", max_length=300, null=True, verbose_name='Nom du produit fini (nouveau)')), ('output_product', models.ForeignKey(blank=True, help_text="Produit existant dont la quantité sera augmentée à la fin de la confection. Si vide et qu'un nom est fourni, un nouveau produit sera créé.", null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='conception_orders_output', to='stock.product', verbose_name='Produit fini à stocker')), ('preparation_order', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='production_orders', to='stock.preparationorder')), ('preparation_order_item', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='production_orders', to='stock.preparationorderitem', verbose_name='Article du bon de préparation')), ('preparation_order_other_item', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='production_orders', to='stock.preparationorderotheritem', verbose_name='Autre produit du bon de préparation')), ('warehouse', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='production_orders', to='stock.warehouse')), ], options={ 'ordering': ('-created_at',), }, ), migrations.CreateModel( name='ProductionOrderDocument', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('file', models.FileField(storage=common.storages.PrivateMediaStorage(), upload_to=stock.models.production_order_document_upload_path, verbose_name='Fichier')), ('name', models.CharField(blank=True, max_length=255, verbose_name='Nom')), ('uploaded_at', models.DateTimeField(auto_now_add=True)), ('production_order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='documents', to='stock.productionorder', verbose_name='Bon de confection')), ], ), migrations.CreateModel( name='PurchaseOrderDocument', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('file', models.FileField(storage=common.storages.PrivateMediaStorage(), upload_to=stock.models.purchase_order_document_upload_path, verbose_name='Fichier')), ('name', models.CharField(blank=True, max_length=255, verbose_name='Nom')), ('uploaded_at', models.DateTimeField(auto_now_add=True)), ('purchase_order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='documents', to='stock.purchaseorder', verbose_name='Commande fournisseur')), ], ), migrations.CreateModel( name='SerializedItem', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('serial_number', models.CharField(max_length=200, unique=True, verbose_name='Numéro de série')), ('status', models.CharField(choices=[('available', 'Disponible'), ('assigned', 'Attribué'), ('lost', 'Perdu'), ('retired', 'Retiré du service')], default='available', max_length=20, verbose_name='Statut')), ('notes', models.TextField(blank=True, default='', verbose_name='Notes')), ('qr_code', models.ImageField(blank=True, null=True, upload_to='stock/qrcodes/serialized_items/', verbose_name='QR Code')), ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Créé le')), ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='created_serialized_items', to=settings.AUTH_USER_MODEL, verbose_name='Créé par')), ('current_holder', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='held_serialized_items', to='contracts.companymember', verbose_name='Détenteur actuel')), ('product', models.ForeignKey(limit_choices_to={'is_serialized': True}, on_delete=django.db.models.deletion.CASCADE, related_name='serialized_items', to='stock.product', verbose_name='Produit')), ], options={ 'verbose_name': 'Article tracé', 'verbose_name_plural': 'Articles tracés', 'ordering': ('product__name', 'serial_number'), }, ), migrations.CreateModel( name='StockMovementBatch', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('movement_type', models.CharField(choices=[('in', 'Entrée'), ('out', 'Sortie'), ('transfer', 'Transfert')], max_length=20, verbose_name='Type')), ('movement_subtype', models.CharField(blank=True, choices=[('purchase', 'Achat'), ('return', 'Retour'), ('inventory', 'Inventaire'), ('consumption', 'Consommation'), ('loss', 'Perte'), ('donation', 'Don'), ('internal', 'Interne'), ('external', 'Externe'), ('correction', 'Correction'), ('confection', 'Confection'), ('preparation_order', 'Bon de préparation'), ('epi', 'EPI'), ('loan', 'Emprunt'), ('worksite', 'Chantier'), ('other', 'Autre')], max_length=30, null=True, verbose_name='Sous-type')), ('date', models.DateTimeField(auto_now_add=True, verbose_name='Date')), ('reason', models.TextField(blank=True, null=True, verbose_name='Raison')), ('requester', models.CharField(blank=True, help_text="Personne ou service à l'origine de la demande", max_length=255, null=True, verbose_name='Demandeur')), ('signature', models.ImageField(blank=True, help_text='Signature du réceptionnaire (image depuis tablette)', null=True, upload_to='stock_movements/signatures/', verbose_name='Signature')), ('company', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='stock_batches', to='contracts.company', verbose_name='Entreprise')), ('contract', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='stock_batches', to='contracts.contract', verbose_name='Contrat')), ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='created_stock_batches', to=settings.AUTH_USER_MODEL, verbose_name='Créé par')), ('person', models.ForeignKey(blank=True, help_text='Personne à qui le matériel est attribué ou qui le restitue', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='stock_batches', to='contracts.companymember', verbose_name='Personne')), ('preparation_order', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='stock_batches', to='stock.preparationorder', verbose_name='Bon de préparation')), ('purchase_order', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='stock_batches', to='stock.purchaseorder', verbose_name="Commande d'achat")), ], options={ 'verbose_name': 'Lot de mouvements de stock', 'verbose_name_plural': 'Lots de mouvements de stock', 'ordering': ('-date',), }, ), migrations.CreateModel( name='StockBatchSignature', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('image', models.ImageField(upload_to=stock.models.stock_batch_signature_upload_path, verbose_name='Image de signature')), ('signed_at', models.DateTimeField(auto_now_add=True, verbose_name='Signé le')), ('signed_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='batch_signatures', to=settings.AUTH_USER_MODEL, verbose_name='Signé par')), ('batch', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='signatures', to='stock.stockmovementbatch', verbose_name='Lot')), ], options={ 'verbose_name': 'Signature de lot', 'verbose_name_plural': 'Signatures de lot', 'ordering': ('signed_at',), }, ), migrations.CreateModel( name='StockMovementDocument', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('file', models.FileField(storage=common.storages.PrivateMediaStorage(), upload_to=stock.models.stock_movement_document_upload_path, verbose_name='Fichier')), ('name', models.CharField(blank=True, max_length=255, verbose_name='Nom')), ('uploaded_at', models.DateTimeField(auto_now_add=True)), ('batch', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='documents', to='stock.stockmovementbatch', verbose_name='Lot')), ], ), migrations.AddField( model_name='purchaseorder', name='supplier', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='purchase_orders', to='stock.supplier', verbose_name='Fournisseur'), ), migrations.AddField( model_name='purchaseorder', name='warehouse', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='purchase_orders', to='stock.warehouse', verbose_name='Entrepôt'), ), migrations.CreateModel( name='WarehouseLocation', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('code', models.CharField(max_length=100, unique=True)), ('name', models.CharField(max_length=100)), ('description', models.TextField(blank=True, null=True)), ('is_default', models.BooleanField(default=False, help_text='Si activé, cet emplacement sera proposé par défaut dans les formulaires pour cet entrepôt.', verbose_name='Emplacement par défaut')), ('qr_code', models.ImageField(blank=True, null=True, upload_to='stock/qrcodes/locations/', verbose_name='QR Code')), ('warehouse', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='locations', to='stock.warehouse')), ], options={ 'unique_together': {('warehouse', 'name')}, }, ), migrations.CreateModel( name='StockMovement', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('quantity', models.IntegerField()), ('date', models.DateTimeField(auto_now_add=True)), ('reason', models.TextField(blank=True, null=True)), ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='stock_movements', to='stock.product')), ('serialized_items', models.ManyToManyField(blank=True, related_name='stock_movements', to='stock.serializeditem', verbose_name='Articles tracés')), ('batch', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='movements', to='stock.stockmovementbatch', verbose_name='Lot')), ('destination_location', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='incoming_movements', to='stock.warehouselocation')), ('source_location', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='outgoing_movements', to='stock.warehouselocation')), ], ), migrations.CreateModel( name='SerializedItemEvent', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('event_type', models.CharField(choices=[('entry', 'Entrée en stock'), ('assigned', 'Attribué'), ('returned', 'Rendu'), ('transferred', 'Transféré'), ('lost', 'Perdu'), ('retired', 'Retiré du service'), ('note', 'Note')], max_length=20, verbose_name="Type d'événement")), ('date', models.DateTimeField(default=django.utils.timezone.now, verbose_name='Date')), ('notes', models.TextField(blank=True, default='', verbose_name='Remarques')), ('created_at', models.DateTimeField(auto_now_add=True)), ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='serialized_item_events', to=settings.AUTH_USER_MODEL, verbose_name='Enregistré par')), ('item', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='events', to='stock.serializeditem', verbose_name='Article')), ('person', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='serialized_item_events', to='contracts.companymember', verbose_name='Personne')), ('from_location', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='serialized_events_from', to='stock.warehouselocation', verbose_name='Depuis')), ('to_location', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='serialized_events_to', to='stock.warehouselocation', verbose_name='Vers')), ], options={ 'verbose_name': 'Événement article tracé', 'verbose_name_plural': 'Événements articles tracés', 'ordering': ('-date', '-created_at'), }, ), migrations.AddField( model_name='serializeditem', name='current_location', field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='serialized_items', to='stock.warehouselocation', verbose_name='Emplacement actuel'), ), migrations.CreateModel( name='PurchaseOrderItem', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('quantity', models.IntegerField(help_text="Quantité totale dans l'unité du produit à ajouter au stock", verbose_name='Quantité totale')), ('num_articles', models.PositiveIntegerField(blank=True, help_text="Nombre d'articles commandés (ex: nombre de sacs)", null=True, verbose_name="Nombre d'articles")), ('quantity_per_article', models.DecimalField(blank=True, decimal_places=3, help_text="Quantité dans l'unité du produit par article (ex: 10 kg par sac)", max_digits=10, null=True, verbose_name='Quantité par article')), ('received_quantity', models.IntegerField(default=0, help_text='Quantité déjà réceptionnée pour cet article', verbose_name='Quantité reçue')), ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='stock.product')), ('purchase_order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='items', to='stock.purchaseorder')), ('location', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='stock.warehouselocation')), ], ), migrations.AddField( model_name='productionorder', name='output_location', field=models.ForeignKey(blank=True, help_text="Emplacement où le produit fini sera ajouté au stock. Si vide, utilise l'emplacement par défaut de la conception.", null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='conception_orders_output', to='stock.warehouselocation', verbose_name='Emplacement de stockage du produit fini'), ), migrations.CreateModel( name='Inventory', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('performed_by', models.CharField(blank=True, max_length=255)), ('status', models.CharField(choices=[('draft', 'Brouillon'), ('in_progress', 'En cours'), ('done', 'Terminé'), ('validated', 'Validé')], default='draft', max_length=20)), ('created_at', models.DateTimeField(auto_now_add=True)), ('updated_at', models.DateTimeField(auto_now=True)), ('validated_at', models.DateTimeField(blank=True, null=True)), ('qr_code', models.ImageField(blank=True, null=True, upload_to='stock/qrcodes/inventories/', verbose_name='QR Code')), ('validated_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='validated_inventories', to=settings.AUTH_USER_MODEL, verbose_name='Validé par')), ('warehouse_location', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='inventories', to='stock.warehouselocation')), ], options={ 'ordering': ('-created_at', '-id'), }, ), migrations.CreateModel( name='InventoryItem', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('expected_quantity', models.IntegerField(blank=True, null=True)), ('counted_quantity', models.IntegerField()), ('is_validated', models.BooleanField(default=False, verbose_name='Validé')), ('validated_at', models.DateTimeField(blank=True, null=True, verbose_name='Validé le')), ('comment', models.TextField(blank=True, default='', verbose_name='Commentaire')), ('inventory', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='items', to='stock.inventory')), ('validated_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='validated_inventory_items', to=settings.AUTH_USER_MODEL, verbose_name='Validé par')), ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='stock.product')), ], options={ 'unique_together': {('inventory', 'product')}, }, ), migrations.CreateModel( name='ProductionOrderComponent', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('quantity', models.IntegerField(default=1)), ('notes', models.CharField(blank=True, max_length=500, null=True)), ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='production_order_usages', to='stock.product')), ('production_order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='order_components', to='stock.productionorder')), ], options={ 'ordering': ('product__name',), 'unique_together': {('production_order', 'product')}, }, ), migrations.CreateModel( name='StockAlert', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('current_quantity', models.IntegerField(default=0)), ('triggered_at', models.DateTimeField(auto_now_add=True)), ('resolved_at', models.DateTimeField(blank=True, null=True)), ('is_active', models.BooleanField(default=True)), ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='alerts', to='stock.product')), ('warehouse', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='alerts', to='stock.warehouse')), ], options={ 'unique_together': {('product', 'warehouse', 'is_active')}, }, ), migrations.CreateModel( name='Stock', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('quantity', models.IntegerField(default=0)), ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='stocks', to='stock.product')), ('location', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='stocks', to='stock.warehouselocation')), ], options={ 'unique_together': {('product', 'location')}, }, ), ]