main #7
@@ -68,126 +68,202 @@ class AutomationCron(ModelSQL, ModelView):
|
|||||||
t.FintradeBookingKey,
|
t.FintradeBookingKey,
|
||||||
))
|
))
|
||||||
|
|
||||||
# Préparer les listes pour la sauvegarde et les données du shipment
|
# ---- PREMIÈRE TRANSACTION : Création des objets de référence ----
|
||||||
parties_to_save = []
|
with Transaction().new_transaction() as trans1:
|
||||||
vessels_to_save = []
|
try:
|
||||||
locations_to_save = []
|
parties_to_save = []
|
||||||
shipments_data = [] # <-- nouvelle liste
|
vessels_to_save = []
|
||||||
|
locations_to_save = []
|
||||||
|
|
||||||
|
parties_cache = {}
|
||||||
|
vessels_cache = {}
|
||||||
|
locations_cache = {}
|
||||||
|
|
||||||
|
# Collecter les données des objets de référence
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
for row in rows:
|
||||||
|
(
|
||||||
|
si_number, si_date, si_quantity, si_unit,
|
||||||
|
container_number, container_type,
|
||||||
|
loading_name, destination_name,
|
||||||
|
agent_name, carrier_name,
|
||||||
|
vessel_name, bl_number,
|
||||||
|
etd_date, bl_date, controller,
|
||||||
|
comments, fintrade_booking_key
|
||||||
|
) = row
|
||||||
|
|
||||||
parties_cache = {}
|
# Fonction pour obtenir ou créer un Party
|
||||||
vessels_cache = {}
|
def get_or_create_party(name):
|
||||||
locations_cache = {}
|
if not name:
|
||||||
|
return None
|
||||||
|
name_upper = name.upper()
|
||||||
|
if name_upper in parties_cache:
|
||||||
|
return parties_cache[name_upper]
|
||||||
|
|
||||||
|
# Chercher d'abord dans la base
|
||||||
|
existing = Party.search([('name', '=', name_upper)], limit=1)
|
||||||
|
if existing:
|
||||||
|
parties_cache[name_upper] = existing[0]
|
||||||
|
return existing[0]
|
||||||
|
|
||||||
|
# Créer un nouveau
|
||||||
|
new_p = Party()
|
||||||
|
new_p.name = name_upper
|
||||||
|
parties_cache[name_upper] = new_p
|
||||||
|
parties_to_save.append(new_p)
|
||||||
|
return new_p
|
||||||
|
|
||||||
rows = cursor.fetchall()
|
# Fonction pour obtenir ou créer un Vessel
|
||||||
for row in rows:
|
def get_or_create_vessel(name):
|
||||||
(
|
if not name:
|
||||||
si_number, si_date, si_quantity, si_unit,
|
return None
|
||||||
container_number, container_type,
|
name_upper = name.upper()
|
||||||
loading_name, destination_name,
|
if name_upper in vessels_cache:
|
||||||
agent_name, carrier_name,
|
return vessels_cache[name_upper]
|
||||||
vessel_name, bl_number,
|
|
||||||
etd_date, bl_date, controller,
|
existing = Vessel.search([('vessel_name', '=', name_upper)], limit=1)
|
||||||
comments, fintrade_booking_key
|
if existing:
|
||||||
) = row
|
vessels_cache[name_upper] = existing[0]
|
||||||
|
return existing[0]
|
||||||
|
|
||||||
|
new_v = Vessel()
|
||||||
|
new_v.vessel_name = name_upper
|
||||||
|
vessels_cache[name_upper] = new_v
|
||||||
|
vessels_to_save.append(new_v)
|
||||||
|
return new_v
|
||||||
|
|
||||||
logger.info("ROW_FROM_CRON: %s", row)
|
# Fonction pour obtenir ou créer une Location
|
||||||
|
def get_or_create_location(name, type_):
|
||||||
|
if not name:
|
||||||
|
return None
|
||||||
|
key = f"{name.upper()}_{type_}"
|
||||||
|
if key in locations_cache:
|
||||||
|
return locations_cache[key]
|
||||||
|
|
||||||
|
existing = Location.search([
|
||||||
|
('name', '=', name.upper()),
|
||||||
|
('type', '=', type_)
|
||||||
|
], limit=1)
|
||||||
|
|
||||||
|
if existing:
|
||||||
|
locations_cache[key] = existing[0]
|
||||||
|
return existing[0]
|
||||||
|
|
||||||
|
new_loc = Location()
|
||||||
|
new_loc.name = name.upper()
|
||||||
|
new_loc.type = type_
|
||||||
|
locations_cache[key] = new_loc
|
||||||
|
locations_to_save.append(new_loc)
|
||||||
|
return new_loc
|
||||||
|
|
||||||
# ----- Fonctions pour créer ou récupérer les objets -----
|
# Collecter les objets à créer
|
||||||
def get_or_create_party(name):
|
_ = get_or_create_party(carrier_name)
|
||||||
name_upper = name.upper()
|
_ = get_or_create_party(agent_name)
|
||||||
if name_upper in parties_cache:
|
_ = get_or_create_vessel(vessel_name)
|
||||||
return parties_cache[name_upper]
|
_ = get_or_create_location(loading_name, 'supplier')
|
||||||
existing = Party.search([('name', '=', name_upper)], limit=1)
|
_ = get_or_create_location(destination_name, 'customer')
|
||||||
if existing:
|
|
||||||
parties_cache[name_upper] = existing[0]
|
|
||||||
return existing[0]
|
|
||||||
if name:
|
|
||||||
new_p = Party()
|
|
||||||
new_p.name = name_upper
|
|
||||||
parties_cache[name_upper] = new_p
|
|
||||||
parties_to_save.append(new_p)
|
|
||||||
return new_p
|
|
||||||
|
|
||||||
def get_or_create_vessel(name, imo=None):
|
# Sauvegarder tous les objets de référence
|
||||||
name_upper = name.upper()
|
if parties_to_save:
|
||||||
if name_upper in vessels_cache:
|
Party.save(parties_to_save)
|
||||||
return vessels_cache[name_upper]
|
if vessels_to_save:
|
||||||
existing = Vessel.search([('vessel_name', '=', name_upper)], limit=1)
|
Vessel.save(vessels_to_save)
|
||||||
if existing:
|
if locations_to_save:
|
||||||
vessels_cache[name_upper] = existing[0]
|
Location.save(locations_to_save)
|
||||||
return existing[0]
|
|
||||||
if name:
|
trans1.commit()
|
||||||
new_v = Vessel()
|
logger.info("Première transaction commitée : objets de référence créés")
|
||||||
new_v.vessel_name = name_upper
|
|
||||||
new_v.vessel_imo = imo
|
except Exception as e:
|
||||||
vessels_cache[name_upper] = new_v
|
trans1.rollback()
|
||||||
vessels_to_save.append(new_v)
|
logger.error(f"Erreur dans la première transaction : {e}")
|
||||||
return new_v
|
raise
|
||||||
|
|
||||||
def get_or_create_location(name, type_):
|
# ---- DEUXIÈME TRANSACTION : Création des shipments ----
|
||||||
key = f"{name.upper()}_{type_}"
|
with Transaction().new_transaction() as trans2:
|
||||||
if key in locations_cache:
|
try:
|
||||||
return locations_cache[key]
|
# Recréer les curseurs après la nouvelle transaction
|
||||||
existing = Location.search([('name', '=', name.upper()), ('type', '=', type_)], limit=1)
|
cursor2 = Transaction().connection.cursor()
|
||||||
if existing:
|
cursor2.execute(*t.select(
|
||||||
locations_cache[key] = existing[0]
|
t.ShippingInstructionNumber,
|
||||||
return existing[0]
|
t.ShippingInstructionDate,
|
||||||
if name:
|
t.ShippingInstructionQuantity,
|
||||||
new_loc = Location()
|
t.ShippingInstructionQuantityUnit,
|
||||||
new_loc.name = name.upper()
|
t.NumberOfContainers,
|
||||||
new_loc.type = type_
|
t.ContainerType,
|
||||||
locations_cache[key] = new_loc
|
t.Loading,
|
||||||
locations_to_save.append(new_loc)
|
t.Destination,
|
||||||
return new_loc
|
t.BookingAgent,
|
||||||
|
t.Carrier,
|
||||||
|
t.Vessel,
|
||||||
|
t.BL_Number,
|
||||||
|
t.ETD_Date,
|
||||||
|
t.BL_Date,
|
||||||
|
t.ExpectedController,
|
||||||
|
t.Comments,
|
||||||
|
t.FintradeBookingKey,
|
||||||
|
))
|
||||||
|
|
||||||
# ----- Récupération ou création des objets -----
|
rows2 = cursor2.fetchall()
|
||||||
carrier = get_or_create_party(carrier_name)
|
shipments_to_save = []
|
||||||
agent = get_or_create_party(agent_name)
|
|
||||||
vessel = get_or_create_vessel(vessel_name)
|
for row in rows2:
|
||||||
loc_from = get_or_create_location(loading_name, 'supplier')
|
(
|
||||||
loc_to = get_or_create_location(destination_name, 'customer')
|
si_number, si_date, si_quantity, si_unit,
|
||||||
|
container_number, container_type,
|
||||||
|
loading_name, destination_name,
|
||||||
|
agent_name, carrier_name,
|
||||||
|
vessel_name, bl_number,
|
||||||
|
etd_date, bl_date, controller,
|
||||||
|
comments, fintrade_booking_key
|
||||||
|
) = row
|
||||||
|
|
||||||
# Stocker les données pour la deuxième étape
|
# Vérifier si le shipment existe déjà
|
||||||
shipments_data.append({
|
existing_shipment = ShipmentIn.search([
|
||||||
'si_number': si_number,
|
('reference', '=', si_number)
|
||||||
'bl_number': bl_number,
|
], limit=1)
|
||||||
'bl_date': bl_date,
|
|
||||||
'etd_date': etd_date,
|
if existing_shipment:
|
||||||
'carrier': carrier,
|
logger.info(f"Shipment existe déjà : {si_number}")
|
||||||
'agent': agent,
|
continue
|
||||||
'vessel': vessel,
|
|
||||||
'from_location': loc_from,
|
|
||||||
'to_location': loc_to,
|
|
||||||
})
|
|
||||||
|
|
||||||
# ----- Étape 1 : sauvegarde des objets de référence -----
|
# Récupérer les objets (maintenant ils existent dans la base)
|
||||||
if parties_to_save:
|
carrier = Party.search([('name', '=', carrier_name.upper())], limit=1) if carrier_name else None
|
||||||
Party.save(parties_to_save)
|
agent = Party.search([('name', '=', agent_name.upper())], limit=1) if agent_name else None
|
||||||
if vessels_to_save:
|
vessel = Vessel.search([('vessel_name', '=', vessel_name.upper())], limit=1) if vessel_name else None
|
||||||
Vessel.save(vessels_to_save)
|
loc_from = Location.search([
|
||||||
if locations_to_save:
|
('name', '=', loading_name.upper()),
|
||||||
Location.save(locations_to_save)
|
('type', '=', 'supplier')
|
||||||
|
], limit=1) if loading_name else None
|
||||||
|
loc_to = Location.search([
|
||||||
|
('name', '=', destination_name.upper()),
|
||||||
|
('type', '=', 'customer')
|
||||||
|
], limit=1) if destination_name else None
|
||||||
|
|
||||||
# Commit pour garantir que tous les IDs sont corrects
|
# Créer le shipment
|
||||||
Transaction().commit()
|
shipment = ShipmentIn()
|
||||||
|
shipment.reference = si_number
|
||||||
|
shipment.from_location = loc_from[0] if loc_from else None
|
||||||
|
shipment.to_location = loc_to[0] if loc_to else None
|
||||||
|
shipment.carrier = carrier[0] if carrier else None
|
||||||
|
shipment.supplier = agent[0] if agent else None
|
||||||
|
shipment.vessel = vessel[0] if vessel else None
|
||||||
|
shipment.cargo_mode = 'bulk'
|
||||||
|
shipment.bl_number = bl_number
|
||||||
|
shipment.bl_date = bl_date
|
||||||
|
shipment.etd = etd_date
|
||||||
|
|
||||||
|
shipments_to_save.append(shipment)
|
||||||
|
logger.info(f"Shipment préparé : {si_number}")
|
||||||
|
|
||||||
# ----- Étape 2 : création des shipments -----
|
# Sauvegarder tous les shipments
|
||||||
for data in shipments_data:
|
if shipments_to_save:
|
||||||
si_number = data['si_number']
|
ShipmentIn.save(shipments_to_save)
|
||||||
shipment = ShipmentIn.search([('reference', '=', si_number)], limit=1)
|
logger.info(f"{len(shipments_to_save)} shipments créés")
|
||||||
if shipment:
|
|
||||||
sh = shipment[0]
|
trans2.commit()
|
||||||
else:
|
|
||||||
sh = ShipmentIn()
|
except Exception as e:
|
||||||
sh.reference = si_number
|
trans2.rollback()
|
||||||
sh.from_location = data['from_location']
|
logger.error(f"Erreur dans la deuxième transaction : {e}")
|
||||||
sh.to_location = data['to_location']
|
raise
|
||||||
sh.carrier = data['carrier']
|
|
||||||
sh.supplier = data['agent']
|
|
||||||
sh.vessel = data['vessel']
|
|
||||||
sh.cargo_mode = 'bulk'
|
|
||||||
sh.bl_number = data['bl_number']
|
|
||||||
sh.bl_date = data['bl_date']
|
|
||||||
sh.etd = data['etd_date']
|
|
||||||
ShipmentIn.save([sh])
|
|
||||||
logger.info("SHIPMENT_CREATED: %s", sh)
|
|
||||||
Reference in New Issue
Block a user