Coverage for simulate_transactions.py: 0%

226 statements  

« prev     ^ index     » next       coverage.py v7.16.0, created at 2026-10-17 16:50 +0800

1""" 

2FUDO ERP - Comprehensive Transaction Simulation 

3Simulates the full accounting cycle: chart of accounts, products, invoices, payments, shipments, etc. 

4Run from: d:\FUDO\erp\apps\backend 

5Usage: python manage.py shell < simulate_transactions.py 

6""" 

7import os 

8import sys 

9from decimal import Decimal 

10from datetime import date, timedelta 

11 

12# Setup 

13sys.path.insert(0, 'd:/FUDO/erp/apps/backend') 

14os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') 

15 

16import django 

17django.setup() 

18 

19from django.utils import timezone 

20from modules.authentication.models import User 

21from modules.erp.models import ( 

22 Account, JournalEntry, JournalItem, Product, Warehouse, 

23 StockMove, Invoice, InvoiceLine, Shipment 

24) 

25from modules.erp.services import ERPService 

26from modules.crm.models import Company, Contact, Deal, Pipeline, Stage 

27from modules.logistics.models import WarehouseReceipt, ShippingQuote, FreightQuote 

28from modules.hr.models import Employee, Leave, PayrollRun, Payslip 

29from modules.trucking.models import Vehicle, Driver, FuelLog, Trip 

30from modules.customs.models import CustomsEntry, DutyRate 

31 

32# ── Get current user & tenant ───────────────────────────────────────────────── 

33user = User.objects.filter(email__iexact='jusmedina@gmail.com').first() or \ 

34 User.objects.filter(email__iexact='admin@fudo.local').first() or \ 

35 User.objects.filter(is_superuser=True).first() 

36 

37if not user: 

38 print("❌ No user found. Run Django first and create a user.") 

39 sys.exit(1) 

40 

41tenant_id = user.tenant_id 

42print(f"✅ User: {user.email} | Tenant: {tenant_id}") 

43 

44# ── 1. Chart of Accounts ──────────────────────────────────────────────────── 

45print("\n" + "="*70) 

46print("1. CHART OF ACCOUNTS") 

47print("="*70) 

48ERPService.get_or_create_chart_of_accounts(tenant_id) 

49accounts = Account.objects.filter(tenant_id=tenant_id).order_by('code') 

50for a in accounts: 

51 print(f" [{a.code}] {a.name:<35} {a.type}") 

52print(f" Total accounts: {accounts.count()}") 

53 

54# ── 2. Products ────────────────────────────────────────────────────────────── 

55print("\n" + "="*70) 

56print("2. PRODUCTS / INVENTORY") 

57print("="*70) 

58product_data = [ 

59 ("SKU001", "International Freight Service", "Service", Decimal("1000.00"), Decimal("1500.00"), Decimal("0.00")), 

60 ("SKU002", "Customs Brokerage Service", "Service", Decimal("500.00"), Decimal("800.00"), Decimal("0.00")), 

61 ("SKU003", "Warehousing (per pallet/month)", "Service", Decimal("50.00"), Decimal("100.00"), Decimal("0.00")), 

62 ("SKU004", "Trucking - Local Delivery", "Service", Decimal("200.00"), Decimal("350.00"), Decimal("0.00")), 

63 ("SKU005", "Cargo Insurance", "Service", Decimal("100.00"), Decimal("150.00"), Decimal("12.00")), 

64 ("SKU006", "Pharmaceutical Freight (Air)", "Service", Decimal("2000.00"), Decimal("3500.00"), Decimal("0.00")), 

65 ("SKU007", "Hazardous Materials Handling", "Service", Decimal("500.00"), Decimal("900.00"), Decimal("0.00")), 

66 ("SKU008", "Cold Chain Logistics", "Service", Decimal("800.00"), Decimal("1200.00"), Decimal("0.00")), 

67] 

68for sku, name, cat, cost, sell, tax in product_data: 

69 p, created = Product.objects.get_or_create( 

70 tenant_id=tenant_id, sku=sku, 

71 defaults=dict(name=name, category=cat, cost_price=cost, selling_price=sell, tax_rate=tax) 

72 ) 

73 status = "✅ Created" if created else "🔄 Exists" 

74 print(f" {status}: {sku} - {name} | Sell: {sell} | Tax: {tax}%") 

75print(f" Total products: {Product.objects.filter(tenant_id=tenant_id).count()}") 

76 

77# ── 3. Warehouse ───────────────────────────────────────────────────────────── 

78print("\n" + "="*70) 

79print("3. WAREHOUSES") 

80print("="*70) 

81warehouses_data = [ 

82 ("WH-MNL-01", "Manila Main Warehouse", "Metro Manila, Philippines"), 

83 ("WH-宿雾-01", "Cebu Logistics Hub", "Cebu, Philippines"), 

84 ("WH-DVO-01", "Davao Distribution Center", "Davao, Philippines"), 

85] 

86for code, name, addr in warehouses_data: 

87 w, created = Warehouse.objects.get_or_create( 

88 tenant_id=tenant_id, code=code, 

89 defaults=dict(name=name, address=addr, is_active=True) 

90 ) 

91 status = "✅ Created" if created else "🔄 Exists" 

92 print(f" {status}: [{code}] {name} - {addr}") 

93print(f" Total warehouses: {Warehouse.objects.filter(tenant_id=tenant_id).count()}") 

94 

95# ── 4. Stock Moves ─────────────────────────────────────────────────────────── 

96print("\n" + "="*70) 

97print("4. STOCK MOVES (Inventory)") 

98print("="*70) 

99wh_main = Warehouse.objects.filter(tenant_id=tenant_id, code='WH-MNL-01').first() 

100products = list(Product.objects.filter(tenant_id=tenant_id)[:3]) 

101if wh_main and products: 

102 for i, prod in enumerate(products): 

103 sm, created = StockMove.objects.get_or_create( 

104 tenant_id=tenant_id, 

105 product=prod, 

106 source_warehouse=None, 

107 dest_warehouse=wh_main, 

108 move_type='INCOMING', 

109 reference_doc=f"INIT-STOCK-{prod.sku}", 

110 defaults=dict( 

111 quantity=Decimal(f"{100 + i * 50}"), 

112 unit_cost=prod.cost_price, 

113 ) 

114 ) 

115 status = "✅ Created" if created else "🔄 Exists" 

116 print(f" {status}: {prod.sku} → {wh_main.code} | Qty: {sm.quantity} × {sm.unit_cost}") 

117print(f" Total stock moves: {StockMove.objects.filter(tenant_id=tenant_id).count()}") 

118 

119# ── 5. Shipping & Freight Quotes ───────────────────────────────────────────── 

120print("\n" + "="*70) 

121print("5. SHIPPING & FREIGHT QUOTES") 

122print("="*70) 

123sq_data = [ 

124 dict(quote_number="SQ-2024-001", carrier="2GO", service_type="Sea Freight", 

125 origin="Manila", destination="Cebu", weight_kg=Decimal("500.00"), 

126 volume_m3=Decimal("2.00"), estimated_cost=Decimal("2500.00"), 

127 currency="PHP", valid_until=date.today() + timedelta(days=14), status="PENDING"), 

128 dict(quote_number="SQ-2024-002", carrier="LBC", service_type="Air Freight", 

129 origin="Manila", destination="Davao", weight_kg=Decimal("50.00"), 

130 volume_m3=Decimal("0.50"), estimated_cost=Decimal("4500.00"), 

131 currency="PHP", valid_until=date.today() + timedelta(days=7), status="PENDING"), 

132] 

133for data in sq_data: 

134 sq, created = ShippingQuote.objects.get_or_create( 

135 tenant_id=tenant_id, quote_number=data['quote_number'], 

136 defaults=dict(**data, is_active=True) 

137 ) 

138 status = "✅ Created" if created else "🔄 Exists" 

139 print(f" {status}: {sq.quote_number} | {sq.carrier} {sq.service_type} | {sq.origin} → {sq.destination} | ₱{sq.estimated_cost}") 

140 

141fq_data = [ 

142 dict(quote_number="FQ-2024-001", carrier="Philex", route="Manila-Cebu", 

143 container_type="20ft", estimated_cost=Decimal("15000.00"), 

144 currency="PHP", valid_until=date.today() + timedelta(days=10), status="PENDING"), 

145 dict(quote_number="FQ-2024-002", carrier="G nucleotide", route="Manila-Davao", 

146 container_type="40ft", estimated_cost=Decimal("28000.00"), 

147 currency="PHP", valid_until=date.today() + timedelta(days=10), status="PENDING"), 

148] 

149for data in fq_data: 

150 fq, created = FreightQuote.objects.get_or_create( 

151 tenant_id=tenant_id, quote_number=data['quote_number'], 

152 defaults=dict(**data, is_active=True) 

153 ) 

154 status = "✅ Created" if created else "🔄 Exists" 

155 print(f" {status}: {fq.quote_number} | {fq.carrier} {fq.container_type} | {fq.route} | ₱{fq.estimated_cost}") 

156 

157# ── 6. Shipments ───────────────────────────────────────────────────────────── 

158print("\n" + "="*70) 

159print("6. SHIPMENTS") 

160print("="*70) 

161shipment_data = [ 

162 dict(reference_number="SHP-INIT-001", shipment_type="IMPORT", 

163 status="IN_TRANSIT", origin="Shanghai, China", destination="Manila, PH", 

164 carrier="COSCO", estimated_arrival=date.today() + timedelta(days=14), 

165 declared_value=Decimal("50000.00"), duty_amount=Decimal("5000.00"), 

166 freight_amount=Decimal("2500.00"), currency="USD"), 

167 dict(reference_number="SHP-INIT-002", shipment_type="EXPORT", 

168 status="DELIVERED", origin="Manila, PH", destination="Los Angeles, USA", 

169 carrier="Maersk", estimated_arrival=date.today() - timedelta(days=2), 

170 declared_value=Decimal("75000.00"), duty_amount=Decimal("0.00"), 

171 freight_amount=Decimal("5000.00"), currency="USD"), 

172 dict(reference_number="SHP-INIT-003", shipment_type="TRANSIT", 

173 status="PENDING", origin="Hong Kong", destination="Manila, PH", 

174 carrier="Yang Ming", estimated_arrival=date.today() + timedelta(days=7), 

175 declared_value=Decimal("30000.00"), duty_amount=Decimal("3000.00"), 

176 freight_amount=Decimal("1800.00"), currency="USD"), 

177] 

178for data in shipment_data: 

179 s, created = Shipment.objects.get_or_create( 

180 tenant_id=tenant_id, reference_number=data['reference_number'], 

181 defaults=dict(**data) 

182 ) 

183 status = "✅ Created" if created else "🔄 Exists" 

184 print(f" {status}: {s.reference_number} | {s.shipment_type} | {s.status} | {s.origin} → {s.destination}") 

185print(f" Total shipments: {Shipment.objects.filter(tenant_id=tenant_id).count()}") 

186 

187# ── 7. CRM - Companies, Contacts, Deals ───────────────────────────────────── 

188print("\n" + "="*70) 

189print("7. CRM - COMPANIES, CONTACTS & DEALS") 

190print("="*70) 

191companies_data = [ 

192 ("JLM Brokerage Corp", "jlm-brokerage.com", "Logistics", "+63-2-8123-4567", "Metro Manila"), 

193 ("Medina Pharma Inc", "medina-pharma.com", "Pharmaceutical", "+63-2-8123-4568", "Makati City"), 

194 ("Global Freight Solutions", "globalfreight.com", "Freight Forwarding", "+1-212-555-0100", "New York, USA"), 

195 ("Pacific Trading Co", "pacifictrading.com", "Trading", "+65-6324-5678", "Singapore"), 

196 ("Kintampo Logistics", "kintampo-logistics.com", "Logistics", "+233-32-123-4567", "Ghana"), 

197] 

198for name, domain, industry, phone, city in companies_data: 

199 c, created = Company.objects.get_or_create( 

200 tenant_id=tenant_id, name=name, 

201 defaults=dict(domain=domain, industry=industry, phone=phone, city=city, country='Philippines') 

202 ) 

203 status = "✅ Created" if created else "🔄 Exists" 

204 print(f" {status}: {c.name} | {c.industry} | {c.city}") 

205 

206# Get or create pipeline 

207pipeline, _ = Pipeline.objects.get_or_create( 

208 tenant_id=tenant_id, name="Sales Pipeline", 

209 defaults=dict(description="Default sales pipeline", is_active=True) 

210) 

211stage_won, _ = Stage.objects.get_or_create( 

212 tenant_id=tenant_id, pipeline=pipeline, name="Won", 

213 defaults=dict(order=1, probability=Decimal("100.00")) 

214) 

215stage_open, _ = Stage.objects.get_or_create( 

216 tenant_id=tenant_id, pipeline=pipeline, name="Qualified", 

217 defaults=dict(order=2, probability=Decimal("50.00")) 

218) 

219 

220companies = list(Company.objects.filter(tenant_id=tenant_id)[:3]) 

221deals_data = [ 

222 ("JLM - Q4 Freight Contract", Decimal("150000.00"), "USD", stage_won, companies[0] if companies else None), 

223 ("Medina Pharma - Cold Chain Setup", Decimal("85000.00"), "USD", stage_open, companies[1] if len(companies) > 1 else None), 

224 ("Global Freight - Customs Brokerage", Decimal("45000.00"), "PHP", stage_won, companies[2] if len(companies) > 2 else None), 

225] 

226for title, value, curr, stage, company in deals_data: 

227 d, created = Deal.objects.get_or_create( 

228 tenant_id=tenant_id, title=title, 

229 defaults=dict(value=value, currency=curr, status=stage.name, 

230 pipeline=pipeline, stage=stage, company=company, 

231 assigned_to=user, expected_close_date=date.today() + timedelta(days=30)) 

232 ) 

233 status = "✅ Created" if created else "🔄 Exists" 

234 print(f" {status}: {d.title} | ₱{d.value} {d.currency} | {d.status}") 

235print(f" Total deals: {Deal.objects.filter(tenant_id=tenant_id).count()}") 

236 

237# ── 8. Invoices ───────────────────────────────────────────────────────────── 

238print("\n" + "="*70) 

239print("8. INVOICES (Double-Entry Journal Entries)") 

240print("="*70) 

241 

242# Build invoice payloads 

243class InvoiceLinePayload: 

244 def __init__(self, product_id, description, quantity, unit_price, tax_rate): 

245 self.product_id = product_id 

246 self.description = description 

247 self.quantity = quantity 

248 self.unit_price = unit_price 

249 self.tax_rate = tax_rate 

250 

251class InvoicePayload: 

252 def __init__(self, customer_name, customer_email, deal_id, due_date, currency, notes, lines): 

253 self.customer_name = customer_name 

254 self.customer_email = customer_email 

255 self.deal_id = deal_id 

256 self.due_date = due_date 

257 self.currency = currency 

258 self.notes = notes 

259 self.terms = "Net 30" 

260 self.lines = lines 

261 

262invoices_to_create = [ 

263 InvoicePayload( 

264 customer_name="JLM Brokerage Corp", 

265 customer_email="billing@jlm-brokerage.com", 

266 deal_id=None, 

267 due_date=date.today() + timedelta(days=30), 

268 currency="PHP", 

269 notes="Q4 International Freight Services", 

270 lines=[ 

271 InvoiceLinePayload(products[0].id, "International Freight Service - Manila Hub", Decimal("2.00"), Decimal("1500.00"), Decimal("12.00")), 

272 InvoiceLinePayload(products[1].id, "Customs Brokerage Service", Decimal("1.00"), Decimal("800.00"), Decimal("12.00")), 

273 ] 

274 ), 

275 InvoicePayload( 

276 customer_name="Medina Pharma Inc", 

277 customer_email="accounts@medina-pharma.com", 

278 deal_id=None, 

279 due_date=date.today() + timedelta(days=30), 

280 currency="PHP", 

281 notes="Cold Chain Logistics - October 2024", 

282 lines=[ 

283 InvoiceLinePayload(products[7].id, "Cold Chain Logistics Service", Decimal("5.00"), Decimal("1200.00"), Decimal("0.00")), 

284 InvoiceLinePayload(products[4].id, "Cargo Insurance", Decimal("1.00"), Decimal("150.00"), Decimal("12.00")), 

285 ] 

286 ), 

287] 

288for inv_payload in invoices_to_create: 

289 inv, created = Invoice.objects.get_or_create( 

290 tenant_id=tenant_id, 

291 invoice_number=f"INV-SIM-{invoices_to_create.index(inv_payload)+1:03d}", 

292 defaults=dict( 

293 customer_name=inv_payload.customer_name, 

294 customer_email=inv_payload.customer_email, 

295 deal_id=inv_payload.deal_id, 

296 issue_date=date.today(), 

297 due_date=inv_payload.due_date, 

298 currency=inv_payload.currency, 

299 subtotal=Decimal("0.00"), # computed in service 

300 tax_total=Decimal("0.00"), 

301 total_amount=Decimal("0.00"), 

302 notes=inv_payload.notes, 

303 terms=inv_payload.terms, 

304 status="SENT", 

305 ) 

306 ) 

307 if created: 

308 # Manually compute lines since we're using get_or_create 

309 for line in inv_payload.lines: 

310 InvoiceLine.objects.create( 

311 tenant_id=tenant_id, 

312 invoice=inv, 

313 product_id=line.product_id, 

314 description=line.description, 

315 quantity=line.quantity, 

316 unit_price=line.unit_price, 

317 tax_rate=line.tax_rate, 

318 subtotal=line.quantity * line.unit_price, 

319 tax_amount=(line.quantity * line.unit_price) * line.tax_rate / Decimal("100.00"), 

320 total=(line.quantity * line.unit_price) * (Decimal("1.00") + line.tax_rate / Decimal("100.00")), 

321 ) 

322 # Recompute totals 

323 lines = InvoiceLine.objects.filter(invoice=inv) 

324 inv.subtotal = sum(l.subtotal for l in lines) 

325 inv.tax_total = sum(l.tax_amount for l in lines) 

326 inv.total_amount = inv.subtotal + inv.tax_total 

327 inv.save() 

328 # Post journal 

329 ERPService.post_invoice_journal(tenant_id, inv) 

330 print(f" ✅ Created: INV-{inv.invoice_number} | {inv.customer_name} | ₱{inv.total_amount} | Status: {inv.status}") 

331 else: 

332 print(f" 🔄 Exists: INV-{inv.invoice_number} | {inv.customer_name} | ₱{inv.total_amount}") 

333 

334print(f" Total invoices: {Invoice.objects.filter(tenant_id=tenant_id).count()}") 

335je_count = JournalEntry.objects.filter(tenant_id=tenant_id, reference_type='INVOICE').count() 

336print(f" Total invoice journal entries: {je_count}") 

337 

338# ── 9. Record Payments ─────────────────────────────────────────────────────── 

339print("\n" + "="*70) 

340print("9. PAYMENTS (Double-Entry Journal Entries)") 

341print("="*70) 

342invoices = Invoice.objects.filter(tenant_id=tenant_id, status__in=['SENT', 'PARTIALLY_PAID']) 

343for inv in invoices: 

344 # Record partial payment (50%) 

345 payment_amount = inv.total_amount * Decimal("0.50") 

346 try: 

347 paid_inv = ERPService.record_payment(tenant_id, inv.id, payment_amount) 

348 print(f" ✅ Payment recorded: INV-{inv.invoice_number} | ₱{payment_amount} paid | Status: {paid_inv.status}") 

349 except Exception as e: 

350 print(f" ⚠️ Payment failed: INV-{inv.invoice_number} | {e}") 

351 

352pay_je_count = JournalEntry.objects.filter(tenant_id=tenant_id, reference_type='PAYMENT').count() 

353print(f" Total payment journal entries: {pay_je_count}") 

354 

355# ── 10. HR - Employees & Payroll ───────────────────────────────────────────── 

356print("\n" + "="*70) 

357print("10. HR - EMPLOYEES & PAYROLL") 

358print("="*70) 

359employees_data = [ 

360 ("Juan", "Dela Cruz", "juan.delacrux@fudo.local", "Logistics Manager", Decimal("75000.00"), "MONTHLY"), 

361 ("Maria", "Santos", "maria.santos@fudo.local", "Operations Supervisor", Decimal("55000.00"), "MONTHLY"), 

362 ("Carlos", "Mendoza", "carlos.mendoza@fudo.local", "Warehouse Lead", Decimal("40000.00"), "MONTHLY"), 

363 ("Ana", "Reyes", "ana.reyes@fudo.local", "HR Coordinator", Decimal("45000.00"), "MONTHLY"), 

364 ("Pedro", "Garcia", "pedro.garcia@fudo.local", "Truck Driver", Decimal("35000.00"), "MONTHLY"), 

365] 

366for first, last, email, title, salary, pay_type in employees_data: 

367 emp, created = Employee.objects.get_or_create( 

368 tenant_id=tenant_id, email=email, 

369 defaults=dict( 

370 first_name=first, last_name=last, job_title=title, 

371 salary=salary, pay_type=pay_type, hire_date=date.today() - timedelta(days=180), 

372 is_active=True 

373 ) 

374 ) 

375 status = "✅ Created" if created else "🔄 Exists" 

376 print(f" {status}: {emp.first_name} {emp.last_name} | {emp.job_title} | ₱{emp.salary}/{emp.pay_type}") 

377 

378print(f" Total employees: {Employee.objects.filter(tenant_id=tenant_id).count()}") 

379 

380# Create a payroll run 

381pr, created = PayrollRun.objects.get_or_create( 

382 tenant_id=tenant_id, 

383 run_date=date.today(), 

384 period_start=date.today() - timedelta(days=30), 

385 period_end=date.today(), 

386 defaults=dict(status="DRAFT", total_amount=Decimal("0.00")) 

387) 

388if created: 

389 employees = Employee.objects.filter(tenant_id=tenant_id, is_active=True) 

390 total = Decimal("0.00") 

391 for emp in employees: 

392 Payslip.objects.create( 

393 tenant_id=tenant_id, 

394 employee=emp, 

395 payroll_run=pr, 

396 basic_salary=emp.salary, 

397 pay_from=pr.period_start, 

398 pay_to=pr.period_end, 

399 net_pay=emp.salary, # simplified 

400 ) 

401 total += emp.salary 

402 pr.total_amount = total 

403 pr.save() 

404print(f" ✅ Payroll Run: PR-{pr.run_date.strftime('%Y%m%d')} | ₱{pr.total_amount} | Status: {pr.status}") 

405print(f" Total payroll runs: {PayrollRun.objects.filter(tenant_id=tenant_id).count()}") 

406 

407# ── 11. Trucking - Vehicles, Drivers, Fuel ──────────────────────────────────── 

408print("\n" + "="*70) 

409print("11. TRUCKING - VEHICLES, DRIVERS & FUEL LOGS") 

410print("="*70) 

411vehicles_data = [ 

412 ("TRK-001", "Mitsubishi Fuso", "ABC-1234", Decimal("10.00"), "ACTIVE"), 

413 ("TRK-002", "Isuzu Elf", "XYZ-5678", Decimal("8.50"), "ACTIVE"), 

414 ("TRK-003", "Hyundai H-100", "DEF-9012", Decimal("6.00"), "MAINTENANCE"), 

415] 

416for code, model, plate, fuel_cap, status_v in vehicles_data: 

417 v, created = Vehicle.objects.get_or_create( 

418 tenant_id=tenant_id, vehicle_number=code, 

419 defaults=dict(model=model, plate_number=plate, fuel_capacity=fuel_cap, status=status_v) 

420 ) 

421 status = "✅ Created" if created else "🔄 Exists" 

422 print(f" {status}: {v.vehicle_number} | {v.model} | {v.plate_number} | {v.status}") 

423 

424drivers_data = [ 

425 ("Roberto", "Aquino", "roberto.aquino@fudo.local", "TRK-001", "VALID"), 

426 ("Luis", "Cruz", "luis.cruz@fudo.local", "TRK-002", "VALID"), 

427] 

428for first, last, email, truck_code, lic_status in drivers_data: 

429 truck = Vehicle.objects.filter(tenant_id=tenant_id, vehicle_number=truck_code).first() 

430 d, created = Driver.objects.get_or_create( 

431 tenant_id=tenant_id, email=email, 

432 defaults=dict( 

433 first_name=first, last_name=last, 

434 license_number=f"DL-{email[-8:-5].upper()}-2024", 

435 license_expiry=date.today() + timedelta(days=365), 

436 license_status=lic_status, status="ACTIVE", assigned_vehicle=truck 

437 ) 

438 ) 

439 status = "✅ Created" if created else "🔄 Exists" 

440 print(f" {status}: {d.first_name} {d.last_name} | {d.license_number} | Truck: {truck_code}") 

441 

442# Fuel logs 

443vehicles = list(Vehicle.objects.filter(tenant_id=tenant_id)[:2]) 

444for v in vehicles: 

445 fl, created = FuelLog.objects.get_or_create( 

446 tenant_id=tenant_id, vehicle=v, log_date=date.today(), 

447 defaults=dict( 

448 odometer_reading=Decimal("50000.00"), 

449 liters_filled=Decimal("50.00"), 

450 price_per_liter=Decimal("65.00"), 

451 total_cost=Decimal("3250.00"), 

452 fuel_type="Diesel", location="Manila Petron Station" 

453 ) 

454 ) 

455 status = "✅ Created" if created else "🔄 Exists" 

456 print(f" {status}: Fuel Log | {v.vehicle_number} | {fl.liters_filled}L @ ₱{fl.price_per_liter}/L") 

457 

458# ── 12. Customs - Entries & Duty Rates ──────────────────────────────────────── 

459print("\n" + "="*70) 

460print("12. CUSTOMS - ENTRIES & DUTY RATES") 

461print("="*70) 

462duty_rates_data = [ 

463 ("8401.40.00", "Fish Meal", Decimal("5.00"), "kg"), 

464 ("9503.00.00", "Toys and Models", Decimal("20.00"), "pc"), 

465 ("3004.90.90", "Pharmaceutical Products", Decimal("1.00"), "kg"), 

466 ("8701.20.00", "Trucks (Commercial)", Decimal("3.00"), "pc"), 

467] 

468for hs, desc, rate, uom in duty_rates_data: 

469 dr, created = DutyRate.objects.get_or_create( 

470 tenant_id=tenant_id, hs_code=hs, 

471 defaults=dict(description=desc, duty_rate=rate, unit_of_measure=uom, is_active=True) 

472 ) 

473 status = "✅ Created" if created else "🔄 Exists" 

474 print(f" {status}: HS {dr.hs_code} | {dr.description} | {dr.duty_rate}% {dr.unit_of_measure}") 

475 

476shipments_for_customs = Shipment.objects.filter(tenant_id=tenant_id, status='IN_TRANSIT')[:1] 

477for sh in shipments_for_customs: 

478 ce, created = CustomsEntry.objects.get_or_create( 

479 tenant_id=tenant_id, shipment=sh, 

480 defaults=dict( 

481 entry_number=f"CE-{sh.reference_number}", 

482 entry_type="IMPORT", 

483 entry_date=date.today(), 

484 customs_value=sh.declared_value, 

485 duty_amount=sh.duty_amount, 

486 vat_amount=(sh.declared_value + sh.duty_amount) * Decimal("0.12"), 

487 status="PENDING", 

488 ) 

489 ) 

490 status = "✅ Created" if created else "🔄 Exists" 

491 print(f" {status}: {ce.entry_number} | Shipment: {sh.reference_number} | ₱{ce.duty_amount} duty") 

492 

493# ── Final Summary ───────────────────────────────────────────────────────────── 

494print("\n" + "="*70) 

495print("📊 FINAL SUMMARY") 

496print("="*70) 

497print(f" Accounts: {Account.objects.filter(tenant_id=tenant_id).count():>6}") 

498print(f" Products: {Product.objects.filter(tenant_id=tenant_id).count():>6}") 

499print(f" Warehouses: {Warehouse.objects.filter(tenant_id=tenant_id).count():>6}") 

500print(f" Stock Moves: {StockMove.objects.filter(tenant_id=tenant_id).count():>6}") 

501print(f" Invoices: {Invoice.objects.filter(tenant_id=tenant_id).count():>6}") 

502print(f" Shipments: {Shipment.objects.filter(tenant_id=tenant_id).count():>6}") 

503print(f" Shipping Quotes: {ShippingQuote.objects.filter(tenant_id=tenant_id).count():>6}") 

504print(f" Freight Quotes: {FreightQuote.objects.filter(tenant_id=tenant_id).count():>6}") 

505print(f" Journal Entries: {JournalEntry.objects.filter(tenant_id=tenant_id).count():>6}") 

506print(f" Journal Items: {JournalItem.objects.filter(tenant_id=tenant_id).count():>6}") 

507print(f" Companies: {Company.objects.filter(tenant_id=tenant_id).count():>6}") 

508print(f" Deals: {Deal.objects.filter(tenant_id=tenant_id).count():>6}") 

509print(f" Employees: {Employee.objects.filter(tenant_id=tenant_id).count():>6}") 

510print(f" Payroll Runs: {PayrollRun.objects.filter(tenant_id=tenant_id).count():>6}") 

511print(f" Vehicles: {Vehicle.objects.filter(tenant_id=tenant_id).count():>6}") 

512print(f" Drivers: {Driver.objects.filter(tenant_id=tenant_id).count():>6}") 

513print(f" Fuel Logs: {FuelLog.objects.filter(tenant_id=tenant_id).count():>6}") 

514print(f" Customs Entries: {CustomsEntry.objects.filter(tenant_id=tenant_id).count():>6}") 

515print(f" Duty Rates: {DutyRate.objects.filter(tenant_id=tenant_id).count():>6}") 

516print("="*70) 

517print("✅ Transaction simulation complete!")