Ninad077 commited on
Commit
6ed6c8e
·
verified ·
1 Parent(s): 9893727

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +1168 -623
app.py CHANGED
@@ -14,14 +14,14 @@ from pyngrok import conf, ngrok
14
  import requests
15
 
16
  # Manually set ngrok path
17
- # ngrok_path = "/Users/ninadmandavkar/Desktop/ngrok/ngrok 3"
18
 
19
  # Set the ngrok path in the configuration
20
- # config = conf.get_default()
21
- # config.ngrok_path = ngrok_path
22
 
23
  # Set your ngrok auth token
24
- # ngrok.set_auth_token('2jQ6LRMBFqe25TP7o2ugti9EH6Y_3mBzBYbsjZmhh69eGq2Q1')
25
 
26
  # logging.basicConfig(level=logging.INFO)
27
 
@@ -35,6 +35,8 @@ global_user_data = [] # For appending user_data
35
  global_data_rows = [] # For appending data rows
36
 
37
 
 
 
38
  # Function to initialize session state
39
  def initialize_session_state():
40
  if 'data' not in st.session_state:
@@ -111,6 +113,9 @@ def generate_plan_id(user_data):
111
 
112
  company_id = user_data.get('Company ID', '') # Get company_id from user_data
113
 
 
 
 
114
  # Increment serial counter and reset if it reaches 999999
115
  serial_counter += 1
116
  if serial_counter > 999999:
@@ -292,39 +297,48 @@ html_content_1 = """
292
 
293
  st.sidebar.markdown(html_content_1, unsafe_allow_html=True)
294
 
295
-
 
296
 
297
  v1 = ["Commerce India", "Reliance", "Commerce Global", "Government Projects", "Individual BH"]
298
  business_head = st.sidebar.selectbox("Business Head", [""] + v1, help="Business Head is used for cost centre allocation")
 
 
 
 
 
 
299
  company_id = st.sidebar.text_input("Company ID", help="Enter the company ID")
300
- if company_id:
 
 
301
  try:
302
- # Construct the API URL with the provided cmpid
303
- api_url = f"https://api.boltic.io/service/platform/bolt/share/v1/data?api_token=eyJpZCI6IjU4OTdmZjZlLTMwMTYtNDZjMC1hMzdlLTJmNjBkMjhjYjc5YyIsInRlbmFudCI6ImdvZnluZGNvbSJ9&batch_size=10000&display_meta=true&cmpid={company_id}"
 
 
304
 
305
- # Fetch data from the API
 
 
 
306
  response = requests.get(api_url)
307
 
308
- # Check if the request was successful
309
  if response.status_code == 200:
310
  data = response.json()
311
-
312
- # Extract company name from the data
313
  if "results" in data and len(data["results"]) > 0:
314
- company_name = data["results"][0].get("company_name", "Company name not found")
315
  else:
316
- company_name = "Company name not found"
317
  else:
318
- company_name = f"Error: Unable to fetch data (Status code: {response.status_code})"
319
  except Exception as e:
320
- company_name = f"An error occurred: {e}"
321
-
322
-
323
- # Display the company name
324
- st.sidebar.text_input("Company Name", value=company_name)
325
  else:
326
- st.sidebar.text_input("Company Name", value="")
327
 
 
 
328
 
329
  currency = st.sidebar.radio("Currency", options= ["INR", "USD"], help= "Select the type of currency", index =None)
330
  bundle_by = st.sidebar.radio(options=["Single value", "Feature specific"], label="Bundle by", help = "Select the bundle", index=None)
@@ -348,313 +362,529 @@ if bundle_by == "Feature specific":
348
  chargeable_on_options = ["Active", "Build", "Cancelled", "Delivered", "DTO", "Invoiced", "Packed", "Picked", "Placed", "Return Window", "RTO", "Setup", "SiteOps-hr", "Subscribed", "TechOps-hr"]
349
  plan_validity_options = ["One time", "Monthly", "Quarterly", "Bi-Annually", "Annually"]
350
  payment_method_options = ["Prepaid", "Postpaid"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
351
 
352
- # Given new_mapping dictionary
353
- new_mapping = {
354
- "GoFynd": {
355
- "Marketing": {
356
- "Order": ["Placed"]
357
- },
358
- "Transaction": {
359
- "Bag": ["Return Window"],
360
- "Shipment": ["Cancelled", "RTO", "DTO"]
361
- },
362
- "Logistics": {
363
- "Shipment": ["Picked", "RTO", "DTO"]
364
- },
365
- "Packaging": {
366
- "Shipment": ["Packed"]
367
- }
368
- },
369
- "Uniket": {
370
- "Marketing": {
371
- "Order": ["Placed"]
372
- },
373
- "Transaction": {
374
- "Bag": ["Return Window"],
375
- "Shipment": ["Cancelled", "RTO", "DTO"]
376
- },
377
- "Logistics": {
378
- "Shipment": ["Picked", "RTO", "DTO"]
379
- },
380
- "Packaging": {
381
- "Shipment": ["Packed"]
382
- }
383
- },
384
- "ONDC": {
385
- "Transaction": {
386
- "Bag": ["Return Window"],
387
- "Shipment": ["Cancelled", "RTO", "DTO"]
388
- },
389
- "Logistics": {
390
- "Shipment": ["Picked", "RTO", "DTO"]
391
- },
392
- "Packaging": {
393
- "Shipment": ["Packed"]
394
- }
395
- },
396
- "StoreOS": {
397
- "Licensing": {
398
- "Application": ["Setup"]
399
- },
400
- "Subscription": {
401
- "Application": ["Subscribed"],
402
- "User": ["Active"],
403
- "Resource": ["TechOps-hr", "SiteOps-hr"]
404
- },
405
- "Marketing": {
406
- "Order": ["Placed"]
407
- },
408
- "Transaction": {
409
- "Order": ["Placed"],
410
- "Bag": ["Invoiced", "Delivered"]
411
- },
412
- "Logistics": {
413
- "Shipment": ["Picked", "RTO", "DTO"]
414
- },
415
- "Packaging": {
416
- "Shipment": ["Packed"]
417
- }
418
- },
419
- "Website": {
420
- "Licensing": {
421
- "Application": ["Setup"]
422
- },
423
- "Subscription": {
424
- "Application": ["Subscribed"],
425
- "User": ["Active"],
426
- "Resource": ["TechOps-hr", "SiteOps-hr"]
427
- },
428
- "Transaction": {
429
- "Order": ["Placed"],
430
- "Bag": ["Invoiced", "Delivered"]
431
- },
432
- "Logistics": {
433
- "Shipment": ["Picked", "RTO", "DTO"]
434
- },
435
- "Packaging": {
436
- "Shipment": ["Packed"]
437
- },
438
- "Development": {
439
- "Application": ["Build"]
440
- }
441
- },
442
- "OMS": {
443
- "Development": {
444
- "Integration": ["Build"]
445
- },
446
- "Licensing": {
447
- "Integration": ["Setup"]
448
- },
449
- "Subscription": {
450
- "Integration": ["Subscribed"],
451
- "User": ["Active"],
452
- "Resource": ["TechOps-hr", "SiteOps-hr"]
453
- },
454
- "Transaction": {
455
- "Order": ["Placed"],
456
- "Bag": ["Invoiced", "Delivered"]
457
- }
458
- },
459
- "WMS": {
460
- "Development": {
461
- "Integration": ["Build"]
462
- },
463
- "Licensing": {
464
- "Integration": ["Setup"]
465
- },
466
- "Subscription": {
467
- "Integration": ["Subscribed"],
468
- "User": ["Active"],
469
- "Resource": ["TechOps-hr", "SiteOps-hr"]
470
- },
471
- "Transaction": {
472
- "Order": ["Placed"],
473
- "Bag": ["Invoiced", "Delivered"],
474
- "B2B": ["Invoiced"],
475
- "B2C": ["Invoiced"]
476
- }
477
- },
478
- "TMS": {
479
- "Development": {
480
- "Integration": ["Build"]
481
- },
482
- "Licensing": {
483
- "Integration": ["Setup"]
484
- },
485
- "Subscription": {
486
- "Integration": ["Subscribed"],
487
- "User": ["Active"],
488
- "Resource": ["TechOps-hr", "SiteOps-hr"]
489
- },
490
- "Logistics": {
491
- "Shipment": ["Picked", "RTO", "DTO"]
492
- }
493
- },
494
- "GMC": {
495
- "Development": {
496
- "Extension": ["Build"],
497
- "Integration": ["Build"]
498
- },
499
- "Licensing": {
500
- "Extension": ["Setup"]
501
- },
502
- "Subscription": {
503
- "Extension": ["Subscribed"],
504
- "User": ["Active"],
505
- "Resource": ["TechOps-hr", "SiteOps-hr"]
506
- }
507
- },
508
- "Partner": {
509
- "Development": {
510
- "Extension": ["Build"]
511
- },
512
- "Licensing": {
513
- "Extension": ["Setup"]
514
- },
515
- "Subscription": {
516
- "Extension": ["Subscribed"],
517
- "User": ["Active"],
518
- "Resource": ["TechOps-hr", "SiteOps-hr"]
519
- }
520
- },
521
- "Catalog Cloud": {
522
- "Development": {
523
- "Extension": ["Build"]
524
- },
525
- "Licensing": {
526
- "Extension": ["Setup"]
527
- },
528
- "Subscription": {
529
- "Extension": ["Subscribed"],
530
- "User": ["Active"],
531
- "Resource": ["TechOps-hr", "SiteOps-hr"]
532
- }
533
- },
534
- "FCP": {
535
- "Subscription": {
536
- "Platform": ["Subscribed"],
537
- "User": ["Active"],
538
- "Resource": ["TechOps-hr", "SiteOps-hr"]
539
- }
540
- },
541
- "PixelBin": {
542
- "Subscription": {
543
- "Platform": ["Subscribed"],
544
- "User": ["Active"],
545
- "Resource": ["TechOps-hr", "SiteOps-hr"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
546
  }
547
- },
548
- "Boltic": {
549
- "Subscription": {
550
- "Platform": ["Subscribed"],
551
- "User": ["Active"],
552
- "Resource": ["TechOps-hr", "SiteOps-hr"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
553
  }
554
- },
555
- "CoPilot": {
556
- "Subscription": {
557
- "Platform": ["Subscribed"],
558
- "User": ["Active"],
559
- "Resource": ["TechOps-hr", "SiteOps-hr"]
560
  }
561
- }
562
- }
563
 
564
- # Initialize mappings
565
- fee_type_mapping = {}
566
- variable_type_mapping = {}
567
- chargeable_on_mapping = {}
568
-
569
- # Populate mappings from new_mapping
570
- for ordering_channel, details in new_mapping.items():
571
- for fee_type, variables in details.items():
572
- if fee_type not in fee_type_mapping:
573
- fee_type_mapping[fee_type] = []
574
- if fee_type not in variable_type_mapping:
575
- variable_type_mapping[fee_type] = []
576
- variable_types = list(variables.keys())
577
- variable_type_mapping[fee_type].extend(variable_types)
578
- for variable_type, chargeable_on_list in variables.items():
579
- if variable_type not in chargeable_on_mapping:
580
- chargeable_on_mapping[variable_type] = []
581
- chargeable_on_mapping[variable_type].extend(chargeable_on_list)
582
-
583
- # Remove duplicates in mappings
584
- fee_type_mapping = {k: list(set(v)) for k, v in fee_type_mapping.items()}
585
- variable_type_mapping = {k: list(set(v)) for k, v in variable_type_mapping.items()}
586
- chargeable_on_mapping = {k: list(set(v)) for k, v in chargeable_on_mapping.items()}
587
-
588
-
589
- # Section 2: Company Info
590
-
591
- html_content_3 = """
592
- <h1 style='
593
- color: #a689f6;
594
- font-size: 22px;
595
- background-image: -webkit-linear-gradient(0deg, #a689f6 3%, #272191 33%, #413bb9 61%);
596
- background-clip: text;
597
- -webkit-background-clip: text;
598
- text-fill-color: transparent;
599
- -webkit-text-fill-color: transparent;
600
- '>Section 2: Rule Info</h1>
601
- """
602
 
603
- st.sidebar.markdown(html_content_3, unsafe_allow_html=True)
 
 
 
604
 
605
- # 1st layer: Select ordering channel
606
- selected_ordering_channel = st.sidebar.selectbox(
607
- "Product Lines",
608
- [""] + list(new_mapping.keys()),
609
- help="Select a product line"
610
- )
611
 
612
- # Layer 1: Mapping of Ordering channels with Fulfilling location
613
- if "TMS" in selected_ordering_channel or "GMC" in selected_ordering_channel or "Catalog Cloud" in selected_ordering_channel:
614
- fulfilling_location = None
615
- application_id = None
616
- else:
617
- abc = ["Store", "Warehouse"]
618
- fulfilling_location = st.sidebar.selectbox("Fulfilling Location", [""] + abc, help="Select the fulfilling location")
619
- application_id = st.sidebar.text_input("Application ID", key="application_id_input", help="Enter the application ID")
620
-
621
- # 2nd layer: Select fee type based on the selected ordering channel
622
- fee_types_for_channel = []
623
- if selected_ordering_channel:
624
- details = new_mapping.get(selected_ordering_channel, {})
625
- fee_types_for_channel = list(details.keys())
626
-
627
- selected_fee_type = st.selectbox(
628
- "Fee Type",
629
- [""] + fee_types_for_channel,
630
- help="Fee type is a revenue head for grouping the revenue"
631
- )
632
 
633
- # 3rd layer: Select variable type based on the selected fee type
634
- variable_type_options = []
635
- if selected_fee_type and selected_ordering_channel:
636
- details = new_mapping.get(selected_ordering_channel, {})
637
- variables = details.get(selected_fee_type, {})
638
- variable_type_options = list(variables.keys())
639
-
640
- selected_variable_type = st.selectbox(
641
- "Variable Type",
642
- [""] + variable_type_options,
643
- help="Variable type is an attribute on which revenue calculation will be done"
644
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
645
 
646
- # 4th layer: Select chargeable on based on the selected variable type
647
- chargeable_on_options = []
648
- if selected_variable_type and selected_fee_type and selected_ordering_channel:
649
- details = new_mapping.get(selected_ordering_channel, {})
650
- variables = details.get(selected_fee_type, {})
651
- chargeable_on_options = variables.get(selected_variable_type, [])
652
-
653
- selected_chargeable_on = st.selectbox(
654
- "Chargeable on",
655
- [""] + chargeable_on_options,
656
- help="Chargeable on is a service status on which the above fee will be applicable"
657
- )
658
 
659
  # Create an empty DataFrame with the desired column names
660
  slabs_df = pd.DataFrame(columns=["Slab", "Max_value", "Commercial_value", "Usage", "Capping/Min_Guarantee_value", "Threshold"])
@@ -743,6 +973,10 @@ if bundle_by == "Feature specific":
743
 
744
 
745
  # 6th layer: Expected Billing
 
 
 
 
746
  fee_reversal_options = ["RTO", "DTO", "Cancel"]
747
  fee_reversal = st.multiselect("Fee Reversal", fee_reversal_options, help = "Fee reversal is an option of reversing to be given to any fee on a particular service status") if selected_fee_type == "Transaction" and selected_variable_type == "Bag" else None
748
  reversal_per = st.number_input("Reversal %", min_value= 0.0, help = "Enter the reversal percentage") if selected_fee_type == "Transaction" and selected_variable_type == "Bag" else None
@@ -777,6 +1011,7 @@ if bundle_by == "Feature specific":
777
  else:
778
  expected_billing = initial_expected_billing # Default to initial Product value if no threshold selected
779
 
 
780
  selected_plan_validity = st.selectbox("Plan Validity", [""] + plan_validity_options, help="Plan validity defines the periodicity of calculation for the above billing", key="plan_vd_2")
781
 
782
  html_content_7 = f"""
@@ -825,7 +1060,7 @@ if bundle_by == "Feature specific":
825
  st.markdown(html_content_8, unsafe_allow_html=True)
826
 
827
 
828
-
829
  selected_payment_method = st.selectbox("Payment Method", [""] + payment_method_options, help="Payment method defines the mode of payment of the plan", key="py_vd_2")
830
 
831
 
@@ -857,12 +1092,35 @@ if bundle_by == "Feature specific":
857
 
858
  rule_id = None
859
  plan_id = None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
860
 
861
  if st.button("Submit", key ='submit_button'):
862
  # Save user data
863
  user_data = {
864
  "Business_Head": business_head,
865
- "Company_ID": company_id,
866
  "Company_Name": company_name,
867
  "Currency": currency,
868
  "Bundle_by": bundle_by,
@@ -935,6 +1193,12 @@ if bundle_by == "Feature specific":
935
  project_id = "fynd-db"
936
  dataset_id = "finance_dwh"
937
  table_id = "plan_v2"
 
 
 
 
 
 
938
  user_data = {
939
  "Business_Head": business_head,
940
  "Company_ID": company_id,
@@ -949,7 +1213,7 @@ if bundle_by == "Feature specific":
949
  "Fee_Type": selected_fee_type,
950
  "Variable_Type": selected_variable_type,
951
  "Chargeable_on": selected_chargeable_on,
952
- "Fee_Nature": "Flat currency",
953
  "Commercial_value": user_input_3,
954
  "Fee_reversal": 0,
955
  "Reversal_%": 0,
@@ -961,9 +1225,22 @@ if bundle_by == "Feature specific":
961
  "Plan_Validity": selected_plan_validity,
962
  "rule_id": rule_id,
963
  "plan_id": plan_id,
 
964
  "Net_total_billing":int(final_billing)
965
  }
966
 
 
 
 
 
 
 
 
 
 
 
 
 
967
  service_account_info = {
968
  "type": "service_account",
969
  "project_id": "fynd-db",
@@ -1007,311 +1284,533 @@ elif bundle_by == "Single value":
1007
  payment_method_options = ["Prepaid", "Postpaid"]
1008
 
1009
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1010
  # Given new_mapping dictionary
1011
- new_mapping = {
1012
- "GoFynd": {
1013
- "Marketing": {
1014
- "Order": ["Placed"]
1015
- },
1016
- "Transaction": {
1017
- "Bag": ["Return Window"],
1018
- "Shipment": ["Cancelled", "RTO", "DTO"]
1019
- },
1020
- "Logistics": {
1021
- "Shipment": ["Picked", "RTO", "DTO"]
1022
- },
1023
- "Packaging": {
1024
- "Shipment": ["Packed"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1025
  }
1026
- },
1027
- "Uniket": {
1028
- "Marketing": {
1029
- "Order": ["Placed"]
1030
- },
1031
- "Transaction": {
1032
- "Bag": ["Return Window"],
1033
- "Shipment": ["Cancelled", "RTO", "DTO"]
1034
- },
1035
- "Logistics": {
1036
- "Shipment": ["Picked", "RTO", "DTO"]
1037
- },
1038
- "Packaging": {
1039
- "Shipment": ["Packed"]
1040
- }
1041
- },
1042
- "ONDC": {
1043
- "Transaction": {
1044
- "Bag": ["Return Window"],
1045
- "Shipment": ["Cancelled", "RTO", "DTO"]
1046
- },
1047
- "Logistics": {
1048
- "Shipment": ["Picked", "RTO", "DTO"]
1049
- },
1050
- "Packaging": {
1051
- "Shipment": ["Packed"]
1052
- }
1053
- },
1054
- "StoreOS": {
1055
- "Licensing": {
1056
- "Application": ["Setup"]
1057
- },
1058
- "Subscription": {
1059
- "Application": ["Subscribed"],
1060
- "User": ["Active"],
1061
- "Resource": ["TechOps-hr", "SiteOps-hr"]
1062
- },
1063
- "Marketing": {
1064
- "Order": ["Placed"]
1065
- },
1066
- "Transaction": {
1067
- "Order": ["Placed"],
1068
- "Bag": ["Invoiced", "Delivered"]
1069
- },
1070
- "Logistics": {
1071
- "Shipment": ["Picked", "RTO", "DTO"]
1072
- },
1073
- "Packaging": {
1074
- "Shipment": ["Packed"]
1075
- }
1076
- },
1077
- "Website": {
1078
- "Licensing": {
1079
- "Application": ["Setup"]
1080
- },
1081
- "Subscription": {
1082
- "Application": ["Subscribed"],
1083
- "User": ["Active"],
1084
- "Resource": ["TechOps-hr", "SiteOps-hr"]
1085
- },
1086
- "Transaction": {
1087
- "Order": ["Placed"],
1088
- "Bag": ["Invoiced", "Delivered"]
1089
- },
1090
- "Logistics": {
1091
- "Shipment": ["Picked", "RTO", "DTO"]
1092
- },
1093
- "Packaging": {
1094
- "Shipment": ["Packed"]
1095
- },
1096
- "Development": {
1097
- "Application": ["Build"]
1098
- }
1099
- },
1100
- "OMS": {
1101
- "Development": {
1102
- "Integration": ["Build"]
1103
- },
1104
- "Licensing": {
1105
- "Integration": ["Setup"]
1106
- },
1107
- "Subscription": {
1108
- "Integration": ["Subscribed"],
1109
- "User": ["Active"],
1110
- "Resource": ["TechOps-hr", "SiteOps-hr"]
1111
- },
1112
- "Transaction": {
1113
- "Order": ["Placed"],
1114
- "Bag": ["Invoiced", "Delivered"]
1115
- }
1116
- },
1117
- "WMS": {
1118
- "Development": {
1119
- "Integration": ["Build"]
1120
- },
1121
- "Licensing": {
1122
- "Integration": ["Setup"]
1123
- },
1124
- "Subscription": {
1125
- "Integration": ["Subscribed"],
1126
- "User": ["Active"],
1127
- "Resource": ["TechOps-hr", "SiteOps-hr"]
1128
- },
1129
- "Transaction": {
1130
- "Order": ["Placed"],
1131
- "Bag": ["Invoiced", "Delivered"],
1132
- "B2B": ["Invoiced"],
1133
- "B2C": ["Invoiced"]
1134
- }
1135
- },
1136
- "TMS": {
1137
- "Development": {
1138
- "Integration": ["Build"]
1139
- },
1140
- "Licensing": {
1141
- "Integration": ["Setup"]
1142
- },
1143
- "Subscription": {
1144
- "Integration": ["Subscribed"],
1145
- "User": ["Active"],
1146
- "Resource": ["TechOps-hr", "SiteOps-hr"]
1147
- },
1148
- "Logistics": {
1149
- "Shipment": ["Picked", "RTO", "DTO"]
1150
- }
1151
- },
1152
- "GMC": {
1153
- "Development": {
1154
- "Extension": ["Build"],
1155
- "Integration": ["Build"]
1156
- },
1157
- "Licensing": {
1158
- "Extension": ["Setup"]
1159
- },
1160
- "Subscription": {
1161
- "Extension": ["Subscribed"],
1162
- "User": ["Active"],
1163
- "Resource": ["TechOps-hr", "SiteOps-hr"]
1164
- }
1165
- },
1166
- "Partner": {
1167
- "Development": {
1168
- "Extension": ["Build"]
1169
- },
1170
- "Licensing": {
1171
- "Extension": ["Setup"]
1172
- },
1173
- "Subscription": {
1174
- "Extension": ["Subscribed"],
1175
- "User": ["Active"],
1176
- "Resource": ["TechOps-hr", "SiteOps-hr"]
1177
- }
1178
- },
1179
- "Catalog Cloud": {
1180
- "Development": {
1181
- "Extension": ["Build"]
1182
- },
1183
- "Licensing": {
1184
- "Extension": ["Setup"]
1185
- },
1186
- "Subscription": {
1187
- "Extension": ["Subscribed"],
1188
- "User": ["Active"],
1189
- "Resource": ["TechOps-hr", "SiteOps-hr"]
1190
- }
1191
- },
1192
- "FCP": {
1193
- "Subscription": {
1194
- "Platform": ["Subscribed"],
1195
- "User": ["Active"],
1196
- "Resource": ["TechOps-hr", "SiteOps-hr"]
1197
- }
1198
- },
1199
- "PixelBin": {
1200
- "Subscription": {
1201
- "Platform": ["Subscribed"],
1202
- "User": ["Active"],
1203
- "Resource": ["TechOps-hr", "SiteOps-hr"]
1204
- }
1205
- },
1206
- "Boltic": {
1207
- "Subscription": {
1208
- "Platform": ["Subscribed"],
1209
- "User": ["Active"],
1210
- "Resource": ["TechOps-hr", "SiteOps-hr"]
1211
  }
1212
- },
1213
- "CoPilot": {
1214
- "Subscription": {
1215
- "Platform": ["Subscribed"],
1216
- "User": ["Active"],
1217
- "Resource": ["TechOps-hr", "SiteOps-hr"]
1218
  }
1219
- }
1220
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1221
 
1222
- # Initialize mappings
1223
- fee_type_mapping = {}
1224
- variable_type_mapping = {}
1225
- chargeable_on_mapping = {}
1226
-
1227
- # Populate mappings from new_mapping
1228
- for ordering_channel, details in new_mapping.items():
1229
- for fee_type, variables in details.items():
1230
- if fee_type not in fee_type_mapping:
1231
- fee_type_mapping[fee_type] = []
1232
- if fee_type not in variable_type_mapping:
1233
- variable_type_mapping[fee_type] = []
1234
- variable_types = list(variables.keys())
1235
- variable_type_mapping[fee_type].extend(variable_types)
1236
- for variable_type, chargeable_on_list in variables.items():
1237
- if variable_type not in chargeable_on_mapping:
1238
- chargeable_on_mapping[variable_type] = []
1239
- chargeable_on_mapping[variable_type].extend(chargeable_on_list)
1240
-
1241
- # Remove duplicates in mappings
1242
- fee_type_mapping = {k: list(set(v)) for k, v in fee_type_mapping.items()}
1243
- variable_type_mapping = {k: list(set(v)) for k, v in variable_type_mapping.items()}
1244
- chargeable_on_mapping = {k: list(set(v)) for k, v in chargeable_on_mapping.items()}
1245
 
 
 
 
 
 
1246
  # Section 2: Company Info
1247
 
1248
- html_content_3 = """
1249
- <h1 style='
1250
- color: #a689f6;
1251
- font-size: 22px;
1252
- background-image: -webkit-linear-gradient(0deg, #a689f6 3%, #272191 33%, #413bb9 61%);
1253
- background-clip: text;
1254
- -webkit-background-clip: text;
1255
- text-fill-color: transparent;
1256
- -webkit-text-fill-color: transparent;
1257
- '>Section 2: Rule Info</h1>
1258
- """
1259
 
1260
- st.sidebar.markdown(html_content_3, unsafe_allow_html=True)
1261
 
1262
- # 1st layer: Select ordering channel
1263
- selected_ordering_channel = st.sidebar.selectbox(
1264
- "Product lines",
1265
- [""] + list(new_mapping.keys()),
1266
- help="Select a Product line"
1267
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1268
 
1269
- # Layer 1: Mapping of Ordering channels with Fulfilling location
1270
- if "TMS" in selected_ordering_channel or "GMC" in selected_ordering_channel or "Catalog Cloud" in selected_ordering_channel:
1271
- fulfilling_location = None
1272
- application_id = None
1273
- else:
1274
- abc = ["Store", "Warehouse"]
1275
- fulfilling_location = st.sidebar.selectbox("Fulfilling Location", [""] + abc, help="Select the fulfilling location")
1276
- application_id = st.sidebar.text_input("Application ID", key="application_id_input", help="Enter the application ID")
1277
-
1278
- # 2nd layer: Select fee type based on the selected ordering channel
1279
- fee_types_for_channel = []
1280
- if selected_ordering_channel:
1281
- details = new_mapping.get(selected_ordering_channel, {})
1282
- fee_types_for_channel = list(details.keys())
1283
-
1284
- selected_fee_type = st.selectbox(
1285
- "Fee Type",
1286
- [""] + fee_types_for_channel,
1287
- help="Fee type is a revenue head for grouping the revenue"
1288
- )
1289
 
1290
- # 3rd layer: Select variable type based on the selected fee type
1291
- variable_type_options = []
1292
- if selected_fee_type and selected_ordering_channel:
1293
- details = new_mapping.get(selected_ordering_channel, {})
1294
- variables = details.get(selected_fee_type, {})
1295
- variable_type_options = list(variables.keys())
1296
-
1297
- selected_variable_type = st.selectbox(
1298
- "Variable Type",
1299
- [""] + variable_type_options,
1300
- help="Variable type is an attribute on which revenue calculation will be done"
1301
- )
1302
 
1303
- # 4th layer: Select chargeable on based on the selected variable type
1304
- chargeable_on_options = []
1305
- if selected_variable_type and selected_fee_type and selected_ordering_channel:
1306
- details = new_mapping.get(selected_ordering_channel, {})
1307
- variables = details.get(selected_fee_type, {})
1308
- chargeable_on_options = variables.get(selected_variable_type, [])
1309
-
1310
- selected_chargeable_on = st.selectbox(
1311
- "Chargeable on",
1312
- [""] + chargeable_on_options,
1313
- help="Chargeable on is a service status on which the above fee will be applicable"
1314
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1315
 
1316
  usage_1 = st.number_input(f"Usage limit for {selected_variable_type}", min_value=0.0, help="Enter the usage limit")
1317
  usage_2 = float(usage_1)
@@ -1393,13 +1892,38 @@ elif bundle_by == "Single value":
1393
 
1394
  rule_id = None
1395
  plan_id = None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1396
 
1397
  # Submit button
1398
  if st.button("Submit"):
1399
  # Save user data
1400
  user_data = {
1401
  "Business Head": business_head,
1402
- "Company ID": company_id,
1403
  "Company Name": company_name,
1404
  "Currency": currency,
1405
  "Bundle by": bundle_by,
@@ -1411,7 +1935,7 @@ elif bundle_by == "Single value":
1411
  "Fee Type": selected_fee_type,
1412
  "Variable Type": selected_variable_type,
1413
  "Chargeable on": selected_chargeable_on,
1414
- "Fee Nature": "Flat currency",
1415
  "Commercial value": user_input_3,
1416
  "Fee reversal": 0,
1417
  "Reversal %": 0,
@@ -1479,13 +2003,20 @@ elif bundle_by == "Single value":
1479
 
1480
 
1481
 
1482
- # Your data and service account info here
1483
  project_id = "fynd-db"
1484
  dataset_id = "finance_dwh"
1485
  table_id = "plan_v2"
 
 
 
 
 
 
 
 
1486
  user_data = {
1487
  "Business_Head": business_head,
1488
- "Company_ID": company_id,
1489
  "Company_Name": company_name,
1490
  "Currency": currency,
1491
  "Bundle_by": bundle_by,
@@ -1497,7 +2028,7 @@ elif bundle_by == "Single value":
1497
  "Fee_Type": selected_fee_type,
1498
  "Variable_Type": selected_variable_type,
1499
  "Chargeable_on": selected_chargeable_on,
1500
- "Fee_Nature": "Flat currency",
1501
  "Commercial_value": user_input_3,
1502
  "Fee_reversal": 0,
1503
  "Reversal_%": 0,
@@ -1509,9 +2040,23 @@ elif bundle_by == "Single value":
1509
  "Plan_Validity": selected_plan_validity,
1510
  "rule_id": rule_id,
1511
  "plan_id": plan_id,
 
1512
  "Net_total_billing":int(final_billing)
1513
  }
1514
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1515
  service_account_info = {
1516
  "type": "service_account",
1517
  "project_id": "fynd-db",
@@ -1562,8 +2107,8 @@ st.write(" ")
1562
  # Start a tunnel to the correct port
1563
 
1564
  # Connect to a port (e.g., 8501) without a custom subdomain
1565
- # try:
1566
- # ngrok_tunnel = ngrok.connect(8501) # Replace 8501 with your port number
1567
- # print(f"ngrok tunnel URL: {ngrok_tunnel.public_url}")
1568
- # except Exception as e:
1569
- # print(f"Failed to start ngrok tunnel: {e}")
 
14
  import requests
15
 
16
  # Manually set ngrok path
17
+ ngrok_path = "/Users/ninadmandavkar/Desktop/ngrok/ngrok 3"
18
 
19
  # Set the ngrok path in the configuration
20
+ config = conf.get_default()
21
+ config.ngrok_path = ngrok_path
22
 
23
  # Set your ngrok auth token
24
+ ngrok.set_auth_token('2jQ6LRMBFqe25TP7o2ugti9EH6Y_3mBzBYbsjZmhh69eGq2Q1')
25
 
26
  # logging.basicConfig(level=logging.INFO)
27
 
 
35
  global_data_rows = [] # For appending data rows
36
 
37
 
38
+
39
+
40
  # Function to initialize session state
41
  def initialize_session_state():
42
  if 'data' not in st.session_state:
 
113
 
114
  company_id = user_data.get('Company ID', '') # Get company_id from user_data
115
 
116
+ if company_id is None or not company_id.strip():
117
+ company_id = ''
118
+
119
  # Increment serial counter and reset if it reaches 999999
120
  serial_counter += 1
121
  if serial_counter > 999999:
 
297
 
298
  st.sidebar.markdown(html_content_1, unsafe_allow_html=True)
299
 
300
+ if 'company_name' not in st.session_state:
301
+ st.session_state['company_name'] = "Company name not available"
302
 
303
  v1 = ["Commerce India", "Reliance", "Commerce Global", "Government Projects", "Individual BH"]
304
  business_head = st.sidebar.selectbox("Business Head", [""] + v1, help="Business Head is used for cost centre allocation")
305
+
306
+ # Initialize company_name in session state
307
+ if 'company_name' not in st.session_state:
308
+ st.session_state['company_name'] = ""
309
+
310
+ # User inputs Company ID
311
  company_id = st.sidebar.text_input("Company ID", help="Enter the company ID")
312
+ company_id_int = None
313
+
314
+ if company_id.strip():
315
  try:
316
+ company_id_int = int(company_id.strip())
317
+ except ValueError:
318
+ st.error("Invalid Company ID. Please enter a valid integer.")
319
+ company_id_int = None
320
 
321
+ # Construct the API URL and fetch data only if company_id_int is valid
322
+ if company_id_int is not None:
323
+ try:
324
+ api_url = f"https://api.boltic.io/service/platform/bolt/share/v1/data?api_token=eyJpZCI6IjU4OTdmZjZlLTMwMTYtNDZjMC1hMzdlLTJmNjBkMjhjYjc5YyIsInRlbmFudCI6ImdvZnluZGNvbSJ9&batch_size=10000&display_meta=true&cmpid={company_id_int}"
325
  response = requests.get(api_url)
326
 
 
327
  if response.status_code == 200:
328
  data = response.json()
 
 
329
  if "results" in data and len(data["results"]) > 0:
330
+ st.session_state['company_name'] = data["results"][0].get("company_name", "Company name not found")
331
  else:
332
+ st.session_state['company_name'] = "Company name not found"
333
  else:
334
+ st.session_state['company_name'] = f"Error: Unable to fetch data (Status code: {response.status_code})"
335
  except Exception as e:
336
+ st.session_state['company_name'] = f"An error occurred: {e}"
 
 
 
 
337
  else:
338
+ st.session_state['company_name'] = "" # Set to an empty string if Company ID is not provided or invalid
339
 
340
+ # Display the company name
341
+ st.sidebar.text_input("Company Name", value=st.session_state['company_name'], disabled=False)
342
 
343
  currency = st.sidebar.radio("Currency", options= ["INR", "USD"], help= "Select the type of currency", index =None)
344
  bundle_by = st.sidebar.radio(options=["Single value", "Feature specific"], label="Bundle by", help = "Select the bundle", index=None)
 
362
  chargeable_on_options = ["Active", "Build", "Cancelled", "Delivered", "DTO", "Invoiced", "Packed", "Picked", "Placed", "Return Window", "RTO", "Setup", "SiteOps-hr", "Subscribed", "TechOps-hr"]
363
  plan_validity_options = ["One time", "Monthly", "Quarterly", "Bi-Annually", "Annually"]
364
  payment_method_options = ["Prepaid", "Postpaid"]
365
+
366
+
367
+ # Initialize session state variables if they don't exist
368
+ if 'new_mapping' not in st.session_state:
369
+ st.session_state['new_mapping'] = {}
370
+ if 'file_data' not in st.session_state:
371
+ st.session_state['file_data'] = None
372
+ if 'mapping_mode' not in st.session_state:
373
+ st.session_state['mapping_mode'] = None # None, 'default', 'custom'
374
+ if 'button_clicked' not in st.session_state:
375
+ st.session_state['button_clicked'] = None
376
+
377
+ # Function to handle custom button click
378
+ def custom_button_click():
379
+ st.session_state.button_clicked = 'custom'
380
+
381
+ # Function to handle default button click
382
+ def default_button_click():
383
+ st.session_state.button_clicked = 'default'
384
 
385
+
386
+ # Display buttons without immediate execution on click
387
+ col1, col2 = st.sidebar.columns([0.25, 0.45])
388
+ with col1:
389
+ default_clicked = st.button("Default mapping")
390
+ with col2:
391
+ custom_clicked = st.button("Custom mapping")
392
+
393
+ # Determine action based on button clicked
394
+ if default_clicked:
395
+ default_button_click()
396
+ elif custom_clicked:
397
+ custom_button_click()
398
+
399
+ # Define CSS styles for the button
400
+ button_styles = """
401
+ <style>
402
+ div.stButton > button {
403
+ color: #ffffff; /* Text color */
404
+ font-size: 50px;
405
+ background-image: linear-gradient(0deg, #a689f6 3%, #413bb9 61%);
406
+ border: none;
407
+ padding: 10px 20px;
408
+ cursor: pointer;
409
+ border-radius: 15px;
410
+ display: inline-block;
411
+ }
412
+ div.stButton > button:hover {
413
+ background-color: #00ff00; /* Hover background color */
414
+ color: #ff0000; /* Hover text color */
415
+ }
416
+ </style>
417
+ """
418
+
419
+ # Render the button with the specified styles
420
+ st.markdown(button_styles, unsafe_allow_html=True)
421
+
422
+
423
+ # Handle Default Mapping
424
+ if st.session_state.button_clicked == 'default':
425
+ # Default mapping data
426
+ new_mapping = {
427
+ "GoFynd": {
428
+ "Marketing": {
429
+ "Order": ["Placed"]
430
+ },
431
+ "Transaction": {
432
+ "Bag": ["Return Window"],
433
+ "Shipment": ["Cancelled", "RTO", "DTO"]
434
+ },
435
+ "Logistics": {
436
+ "Shipment": ["Picked", "RTO", "DTO"]
437
+ },
438
+ "Packaging": {
439
+ "Shipment": ["Packed"]
440
+ }
441
+ },
442
+ "Uniket": {
443
+ "Marketing": {
444
+ "Order": ["Placed"]
445
+ },
446
+ "Transaction": {
447
+ "Bag": ["Return Window"],
448
+ "Shipment": ["Cancelled", "RTO", "DTO"]
449
+ },
450
+ "Logistics": {
451
+ "Shipment": ["Picked", "RTO", "DTO"]
452
+ },
453
+ "Packaging": {
454
+ "Shipment": ["Packed"]
455
+ }
456
+ },
457
+ "ONDC": {
458
+ "Transaction": {
459
+ "Bag": ["Return Window"],
460
+ "Shipment": ["Cancelled", "RTO", "DTO"]
461
+ },
462
+ "Logistics": {
463
+ "Shipment": ["Picked", "RTO", "DTO"]
464
+ },
465
+ "Packaging": {
466
+ "Shipment": ["Packed"]
467
+ }
468
+ },
469
+ "StoreOS": {
470
+ "Licensing": {
471
+ "Application": ["Setup"]
472
+ },
473
+ "Subscription": {
474
+ "Application": ["Subscribed"],
475
+ "User": ["Active"],
476
+ "Resource": ["TechOps-hr", "SiteOps-hr"]
477
+ },
478
+ "Marketing": {
479
+ "Order": ["Placed"]
480
+ },
481
+ "Transaction": {
482
+ "Order": ["Placed"],
483
+ "Bag": ["Invoiced", "Delivered"]
484
+ },
485
+ "Logistics": {
486
+ "Shipment": ["Picked", "RTO", "DTO"]
487
+ },
488
+ "Packaging": {
489
+ "Shipment": ["Packed"]
490
+ }
491
+ },
492
+ "Website": {
493
+ "Licensing": {
494
+ "Application": ["Setup"]
495
+ },
496
+ "Subscription": {
497
+ "Application": ["Subscribed"],
498
+ "User": ["Active"],
499
+ "Resource": ["TechOps-hr", "SiteOps-hr"]
500
+ },
501
+ "Transaction": {
502
+ "Order": ["Placed"],
503
+ "Bag": ["Invoiced", "Delivered"]
504
+ },
505
+ "Logistics": {
506
+ "Shipment": ["Picked", "RTO", "DTO"]
507
+ },
508
+ "Packaging": {
509
+ "Shipment": ["Packed"]
510
+ },
511
+ "Development": {
512
+ "Application": ["Build"]
513
+ }
514
+ },
515
+ "OMS": {
516
+ "Development": {
517
+ "Integration": ["Build"]
518
+ },
519
+ "Licensing": {
520
+ "Integration": ["Setup"]
521
+ },
522
+ "Subscription": {
523
+ "Integration": ["Subscribed"],
524
+ "User": ["Active"],
525
+ "Resource": ["TechOps-hr", "SiteOps-hr"]
526
+ },
527
+ "Transaction": {
528
+ "Order": ["Placed"],
529
+ "Bag": ["Invoiced", "Delivered"]
530
+ }
531
+ },
532
+ "WMS": {
533
+ "Development": {
534
+ "Integration": ["Build"]
535
+ },
536
+ "Licensing": {
537
+ "Integration": ["Setup"]
538
+ },
539
+ "Subscription": {
540
+ "Integration": ["Subscribed"],
541
+ "User": ["Active"],
542
+ "Resource": ["TechOps-hr", "SiteOps-hr"]
543
+ },
544
+ "Transaction": {
545
+ "Order": ["Placed"],
546
+ "Bag": ["Invoiced", "Delivered"],
547
+ "B2B": ["Invoiced"],
548
+ "B2C": ["Invoiced"]
549
+ }
550
+ },
551
+ "TMS": {
552
+ "Development": {
553
+ "Integration": ["Build"]
554
+ },
555
+ "Licensing": {
556
+ "Integration": ["Setup"]
557
+ },
558
+ "Subscription": {
559
+ "Integration": ["Subscribed"],
560
+ "User": ["Active"],
561
+ "Resource": ["TechOps-hr", "SiteOps-hr"]
562
+ },
563
+ "Logistics": {
564
+ "Shipment": ["Picked", "RTO", "DTO"]
565
+ }
566
+ },
567
+ "GMC": {
568
+ "Development": {
569
+ "Extension": ["Build"],
570
+ "Integration": ["Build"]
571
+ },
572
+ "Licensing": {
573
+ "Extension": ["Setup"]
574
+ },
575
+ "Subscription": {
576
+ "Extension": ["Subscribed"],
577
+ "User": ["Active"],
578
+ "Resource": ["TechOps-hr", "SiteOps-hr"]
579
+ }
580
+ },
581
+ "Partner": {
582
+ "Development": {
583
+ "Extension": ["Build"]
584
+ },
585
+ "Licensing": {
586
+ "Extension": ["Setup"]
587
+ },
588
+ "Subscription": {
589
+ "Extension": ["Subscribed"],
590
+ "User": ["Active"],
591
+ "Resource": ["TechOps-hr", "SiteOps-hr"]
592
+ }
593
+ },
594
+ "Catalog Cloud": {
595
+ "Development": {
596
+ "Extension": ["Build"]
597
+ },
598
+ "Licensing": {
599
+ "Extension": ["Setup"]
600
+ },
601
+ "Subscription": {
602
+ "Extension": ["Subscribed"],
603
+ "User": ["Active"],
604
+ "Resource": ["TechOps-hr", "SiteOps-hr"]
605
+ }
606
+ },
607
+ "FCP": {
608
+ "Subscription": {
609
+ "Platform": ["Subscribed"],
610
+ "User": ["Active"],
611
+ "Resource": ["TechOps-hr", "SiteOps-hr"]
612
+ }
613
+ },
614
+ "PixelBin": {
615
+ "Subscription": {
616
+ "Platform": ["Subscribed"],
617
+ "User": ["Active"],
618
+ "Resource": ["TechOps-hr", "SiteOps-hr"]
619
+ }
620
+ },
621
+ "Boltic": {
622
+ "Subscription": {
623
+ "Platform": ["Subscribed"],
624
+ "User": ["Active"],
625
+ "Resource": ["TechOps-hr", "SiteOps-hr"]
626
+ }
627
+ },
628
+ "CoPilot": {
629
+ "Subscription": {
630
+ "Platform": ["Subscribed"],
631
+ "User": ["Active"],
632
+ "Resource": ["TechOps-hr", "SiteOps-hr"]
633
+ }
634
  }
635
+ }
636
+
637
+ st.session_state['new_mapping'] = new_mapping
638
+ st.session_state['mapping_mode'] = 'default'
639
+
640
+ html_content_1 = """
641
+ <h1 style='
642
+ color: #a689f6;
643
+ font-size: 22px;
644
+ background-image: -webkit-linear-gradient(0deg, #a689f6 3%, #272191 33%, #413bb9 61%);
645
+ background-clip: text;
646
+ -webkit-background-clip: text;
647
+ text-fill-color: transparent;
648
+ -webkit-text-fill-color: transparent;
649
+ '>Section 2: Rule Info</h1>
650
+ """
651
+
652
+ st.sidebar.markdown(html_content_1, unsafe_allow_html=True)
653
+
654
+ # Handle Custom Mapping
655
+ elif st.session_state.button_clicked == 'custom':
656
+
657
+ # Define CSS styles for the button
658
+ button_styles = """
659
+ <style>
660
+ div.stButton > button {
661
+ color: #ffffff; /* Text color */
662
+ font-size: 50px;
663
+ background-image: linear-gradient(0deg, #a689f6 3%, #413bb9 61%);
664
+ border: none;
665
+ padding: 10px 20px;
666
+ cursor: pointer;
667
+ border-radius: 15px;
668
+ display: inline-block;
669
  }
670
+ div.stButton > button:hover {
671
+ background-color: #00ff00; /* Hover background color */
672
+ color: #ff0000; /* Hover text color */
 
 
 
673
  }
674
+ </style>
675
+ """
676
 
677
+ # Render the button with the specified styles
678
+ st.markdown(button_styles, unsafe_allow_html=True)
679
+
680
+ # File upload
681
+ uploaded_file = st.sidebar.file_uploader("Upload a file:", type=['csv', 'xlsx'], key='file_uploader')
682
+
683
+ html_content_1 = """
684
+ <h1 style='
685
+ color: #a689f6;
686
+ font-size: 22px;
687
+ background-image: -webkit-linear-gradient(0deg, #a689f6 3%, #272191 33%, #413bb9 61%);
688
+ background-clip: text;
689
+ -webkit-background-clip: text;
690
+ text-fill-color: transparent;
691
+ -webkit-text-fill-color: transparent;
692
+ '>Section 2: Rule Info</h1>
693
+ """
694
+
695
+ st.sidebar.markdown(html_content_1, unsafe_allow_html=True)
696
+
697
+ if uploaded_file is not None:
698
+ try:
699
+ # Read the file, treating the first row as the header
700
+ if uploaded_file.name.endswith('.csv'):
701
+ data = pd.read_csv(uploaded_file, header=0)
702
+ elif uploaded_file.name.endswith('.xlsx'):
703
+ data = pd.read_excel(uploaded_file, header=0)
 
 
 
 
 
 
 
 
 
 
 
704
 
705
+ if st.sidebar.button("Overwrite headers"):
706
+ # Rename the headers
707
+ new_headers = ['ordering_channel', 'fee_type', 'variable_type', 'chargeable_on']
708
+ data.columns = new_headers
709
 
710
+ # Save the data to session state
711
+ st.session_state['file_data'] = data
 
 
 
 
712
 
713
+ # Initialize the mapping
714
+ new_mapping = {}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
715
 
716
+
717
+
718
+ # Build the mapping
719
+ for _, row in data.iterrows():
720
+
721
+
722
+ ordering_channel = row['ordering_channel']
723
+ fee_type = row['fee_type']
724
+ variable_type = row['variable_type']
725
+ chargeable_on = row['chargeable_on']
726
+
727
+ if ordering_channel not in new_mapping:
728
+ new_mapping[ordering_channel] = {}
729
+
730
+ if fee_type not in new_mapping[ordering_channel]:
731
+ new_mapping[ordering_channel][fee_type] = {}
732
+
733
+ if variable_type not in new_mapping[ordering_channel][fee_type]:
734
+ new_mapping[ordering_channel][fee_type][variable_type] = []
735
+
736
+ if chargeable_on not in new_mapping[ordering_channel][fee_type][variable_type]:
737
+ new_mapping[ordering_channel][fee_type][variable_type].append(chargeable_on)
738
+
739
+ st.session_state['new_mapping'] = new_mapping
740
+ st.session_state['mapping_mode'] = 'custom'
741
+
742
+ except Exception as e:
743
+ st.error(f"Error reading the file: {e}")
744
+
745
+ # Handle mapping display
746
+ # Initialize session state variables if they don't exist
747
+ # Initialize session state variables with default values if not already set
748
+ if 'business_head' not in st.session_state:
749
+ st.session_state['business_head'] = None
750
+ if 'company_id' not in st.session_state:
751
+ st.session_state['company_id'] = None
752
+ if 'company_name' not in st.session_state:
753
+ st.session_state['company_name'] = None
754
+ if 'currency' not in st.session_state:
755
+ st.session_state['currency'] = None
756
+ if 'bundle_by' not in st.session_state:
757
+ st.session_state['bundle_by'] = None
758
+ if 'plan_name' not in st.session_state:
759
+ st.session_state['plan_name'] = None
760
+ if 'plan_description' not in st.session_state:
761
+ st.session_state['plan_description'] = None
762
+ if 'selected_ordering_channel' not in st.session_state:
763
+ st.session_state['selected_ordering_channel'] = None
764
+ if 'fulfilling_location' not in st.session_state:
765
+ st.session_state['fulfilling_location'] = None
766
+ if 'application_id' not in st.session_state:
767
+ st.session_state['application_id'] = None
768
+ if 'selected_fee_type' not in st.session_state:
769
+ st.session_state['selected_fee_type'] = None
770
+ if 'selected_variable_type' not in st.session_state:
771
+ st.session_state['selected_variable_type'] = None
772
+ if 'selected_chargeable_on' not in st.session_state:
773
+ st.session_state['selected_chargeable_on'] = None
774
+ if 'selected_fee_nature' not in st.session_state:
775
+ st.session_state['selected_fee_nature'] = None
776
+ if 'user_input_3' not in st.session_state:
777
+ st.session_state['user_input_3'] = None
778
+ if 'usage_3' not in st.session_state:
779
+ st.session_state['usage_3'] = None
780
+ if 'Capping_or_Minimum_Guarantee_3' not in st.session_state:
781
+ st.session_state['Capping_or_Minimum_Guarantee_3'] = None
782
+ if 'threshold' not in st.session_state:
783
+ st.session_state['threshold'] = None
784
+ if 'expected_billing' not in st.session_state:
785
+ st.session_state['expected_billing'] = None
786
+ if 'selected_payment_method' not in st.session_state:
787
+ st.session_state['selected_payment_method'] = None
788
+ if 'selected_plan_validity' not in st.session_state:
789
+ st.session_state['selected_plan_validity'] = None
790
+ if 'final_billing' not in st.session_state:
791
+ st.session_state['final_billing'] = None
792
+ if 'fee_reversal' not in st.session_state:
793
+ st.session_state['fee_reversal'] = None
794
+ if 'reversal_per' not in st.session_state:
795
+ st.session_state['reversal_per'] = None
796
+
797
+ # Check if 'mapping_mode' exists in session state before using it
798
+ if 'mapping_mode' in st.session_state and st.session_state['mapping_mode']:
799
+ # 1st layer: Select ordering channel
800
+ selected_ordering_channel = st.sidebar.selectbox(
801
+ "Product lines",
802
+ [""] + list(st.session_state['new_mapping'].keys()),
803
+ help="Select a Product line",
804
+ key='ordering_channel'
805
+ )
806
+
807
+ if selected_ordering_channel:
808
+ selected_ordering_channel = str(selected_ordering_channel) or int(selected_ordering_channel)
809
+
810
+ # Determine fulfilling_location and application_id based on selected_ordering_channel
811
+ if any(channel in selected_ordering_channel for channel in ["TMS", "GMC", "Catalog Cloud"]):
812
+ st.session_state['fulfilling_location'] = None
813
+ st.session_state['application_id'] = None
814
+ else:
815
+ abc = ["Store", "Warehouse"]
816
+ st.session_state['fulfilling_location'] = st.sidebar.selectbox(
817
+ "Fulfilling Location", [""] + abc, help="Select the fulfilling location"
818
+ )
819
+ st.session_state['application_id'] = st.sidebar.text_input(
820
+ "Application ID", key="application_id_input", help="Enter the application ID"
821
+ )
822
+
823
+ # Use the session state variables in your app
824
+ fulfilling_location = st.session_state['fulfilling_location']
825
+ application_id = st.session_state['application_id']
826
+
827
+
828
+
829
+ # 2nd layer: Select fee type based on the selected ordering channel
830
+
831
+ if 'selected_fee_type' not in st.session_state:
832
+ st.session_state['selected_fee_type'] = None
833
+
834
+ fee_types_for_channel = st.session_state['new_mapping'].get(selected_ordering_channel, {}).keys()
835
+ fee_types_for_channel = list(fee_types_for_channel)
836
+
837
+ if fee_types_for_channel:
838
+
839
+
840
+ # Define selected_fee_type based on user input
841
+
842
+ st.session_state['selected_fee_type'] = st.selectbox(
843
+ "Fee Type",
844
+ [""] + fee_types_for_channel,
845
+ help="Fee type is a revenue head for grouping the revenue",
846
+ key='fee_type'
847
+ )
848
+
849
+ # Access selected_fee_type for any session state operations
850
+ selected_fee_type = st.session_state['selected_fee_type']
851
+
852
+ # 3rd layer: Select variable type based on the selected fee type
853
+ variable_type_options = []
854
+ if selected_fee_type:
855
+ details = st.session_state['new_mapping'].get(selected_ordering_channel, {})
856
+ variables = details.get(selected_fee_type, {})
857
+ variable_type_options = list(variables.keys())
858
+
859
+ st.session_state['selected_variable_type'] = st.selectbox(
860
+ "Variable Type",
861
+ [""] + variable_type_options,
862
+ help="Variable type is an attribute on which revenue calculation will be done",
863
+ key='variable_type'
864
+ )
865
+
866
+ selected_variable_type = st.session_state['selected_variable_type']
867
+
868
+
869
+ # 4th layer: Select chargeable on based on the selected variable type
870
+ chargeable_on_options = []
871
+ if selected_variable_type:
872
+ chargeable_on_options = variables.get(selected_variable_type, [])
873
+
874
+ st.session_state['selected_chargeable_on'] = st.selectbox(
875
+ "Chargeable on",
876
+ [""] + chargeable_on_options,
877
+ help="Chargeable on is a service status on which the above fee will be applicable",
878
+ key='chargeable_on'
879
+ )
880
+
881
+ selected_chargeable_on = st.session_state['selected_chargeable_on']
882
+
883
+ else:
884
+ st.write("No fee types available for the selected ordering channel.")
885
+ else:
886
+ st.write("")
887
 
 
 
 
 
 
 
 
 
 
 
 
 
888
 
889
  # Create an empty DataFrame with the desired column names
890
  slabs_df = pd.DataFrame(columns=["Slab", "Max_value", "Commercial_value", "Usage", "Capping/Min_Guarantee_value", "Threshold"])
 
973
 
974
 
975
  # 6th layer: Expected Billing
976
+
977
+ selected_fee_type = st.session_state['selected_fee_type']
978
+ selected_variable_type = st.session_state['selected_variable_type']
979
+
980
  fee_reversal_options = ["RTO", "DTO", "Cancel"]
981
  fee_reversal = st.multiselect("Fee Reversal", fee_reversal_options, help = "Fee reversal is an option of reversing to be given to any fee on a particular service status") if selected_fee_type == "Transaction" and selected_variable_type == "Bag" else None
982
  reversal_per = st.number_input("Reversal %", min_value= 0.0, help = "Enter the reversal percentage") if selected_fee_type == "Transaction" and selected_variable_type == "Bag" else None
 
1011
  else:
1012
  expected_billing = initial_expected_billing # Default to initial Product value if no threshold selected
1013
 
1014
+ plan_validity_options = ["One time", "Monthly", "Quarterly", "Bi-Annually", "Annually"]
1015
  selected_plan_validity = st.selectbox("Plan Validity", [""] + plan_validity_options, help="Plan validity defines the periodicity of calculation for the above billing", key="plan_vd_2")
1016
 
1017
  html_content_7 = f"""
 
1060
  st.markdown(html_content_8, unsafe_allow_html=True)
1061
 
1062
 
1063
+ payment_method_options = ["Prepaid", "Postpaid"]
1064
  selected_payment_method = st.selectbox("Payment Method", [""] + payment_method_options, help="Payment method defines the mode of payment of the plan", key="py_vd_2")
1065
 
1066
 
 
1092
 
1093
  rule_id = None
1094
  plan_id = None
1095
+ business_head = st.session_state['business_head']
1096
+ company_name = st.session_state['company_name']
1097
+ company_id = st.session_state['company_id']
1098
+ currency = st.session_state['currency']
1099
+ # bundle_by = st.session_state['bundle_by']
1100
+ plan_name = st.session_state['plan_name']
1101
+ plan_description = st.session_state['plan_description']
1102
+ selected_ordering_channel = st.session_state['selected_ordering_channel']
1103
+ fulfilling_location = st.session_state['fulfilling_location']
1104
+ application_id = st.session_state['application_id']
1105
+ selected_fee_type = st.session_state['selected_fee_type']
1106
+ selected_variable_type = st.session_state['selected_variable_type']
1107
+ selected_chargeable_on = st.session_state['selected_chargeable_on']
1108
+ user_input_3 = st.session_state['user_input_3']
1109
+ usage_3 = st.session_state['usage_3']
1110
+ Capping_or_Minimum_Guarantee_3 = st.session_state['Capping_or_Minimum_Guarantee_3']
1111
+ fee_reversal = st.session_state['fee_reversal']
1112
+ reversal_per = st.session_state['reversal_per']
1113
+ threshold = st.session_state['threshold']
1114
+ expected_billing = st.session_state['expected_billing']
1115
+ selected_payment_method = st.session_state['selected_payment_method']
1116
+ selected_plan_validity = st.session_state['selected_plan_validity']
1117
+ final_billing = int(st.session_state['final_billing']) if st.session_state['final_billing'] is not None else 0
1118
 
1119
  if st.button("Submit", key ='submit_button'):
1120
  # Save user data
1121
  user_data = {
1122
  "Business_Head": business_head,
1123
+ "Company_ID": company_id.strip() if company_id else None,
1124
  "Company_Name": company_name,
1125
  "Currency": currency,
1126
  "Bundle_by": bundle_by,
 
1193
  project_id = "fynd-db"
1194
  dataset_id = "finance_dwh"
1195
  table_id = "plan_v2"
1196
+ fulfilling_location = st.session_state['fulfilling_location']
1197
+ application_id = st.session_state['application_id']
1198
+ # bundle_by = st.session_state['bundle_by']
1199
+
1200
+ created_at = datetime.now().isoformat()
1201
+
1202
  user_data = {
1203
  "Business_Head": business_head,
1204
  "Company_ID": company_id,
 
1213
  "Fee_Type": selected_fee_type,
1214
  "Variable_Type": selected_variable_type,
1215
  "Chargeable_on": selected_chargeable_on,
1216
+ "Fee_Nature": selected_fee_nature,
1217
  "Commercial_value": user_input_3,
1218
  "Fee_reversal": 0,
1219
  "Reversal_%": 0,
 
1225
  "Plan_Validity": selected_plan_validity,
1226
  "rule_id": rule_id,
1227
  "plan_id": plan_id,
1228
+ "created_at": created_at,
1229
  "Net_total_billing":int(final_billing)
1230
  }
1231
 
1232
+ global_user_data.append((user_name, user_data))
1233
+
1234
+ # Generate PM_id and add it to user_data
1235
+ rule_id = generate_rule_id(user_data)
1236
+ user_data['rule_id'] = rule_id
1237
+
1238
+ # Generate Plan ID and add it to user_data
1239
+ plan_id = generate_plan_id(user_data)
1240
+ user_data['plan_id'] = plan_id
1241
+
1242
+ save_user_data(user_data) # Save user data after submission
1243
+
1244
  service_account_info = {
1245
  "type": "service_account",
1246
  "project_id": "fynd-db",
 
1284
  payment_method_options = ["Prepaid", "Postpaid"]
1285
 
1286
 
1287
+ # Initialize session state variables if they don't exist
1288
+ if 'new_mapping' not in st.session_state:
1289
+ st.session_state['new_mapping'] = {}
1290
+ if 'file_data' not in st.session_state:
1291
+ st.session_state['file_data'] = None
1292
+ if 'mapping_mode' not in st.session_state:
1293
+ st.session_state['mapping_mode'] = None # None, 'default', 'custom'
1294
+ if 'button_clicked' not in st.session_state:
1295
+ st.session_state['button_clicked'] = None
1296
+
1297
+ # Function to handle custom button click
1298
+ def custom_button_click():
1299
+ st.session_state.button_clicked = 'custom'
1300
+
1301
+ # Function to handle default button click
1302
+ def default_button_click():
1303
+ st.session_state.button_clicked = 'default'
1304
+
1305
+
1306
+ # Display buttons without immediate execution on click
1307
+ col1, col2 = st.sidebar.columns([0.25, 0.45])
1308
+ with col1:
1309
+ default_clicked = st.button("Default mapping")
1310
+ with col2:
1311
+ custom_clicked = st.button("Custom mapping")
1312
+
1313
+ # Determine action based on button clicked
1314
+ if default_clicked:
1315
+ default_button_click()
1316
+ elif custom_clicked:
1317
+ custom_button_click()
1318
+
1319
+ # Define CSS styles for the button
1320
+ button_styles = """
1321
+ <style>
1322
+ div.stButton > button {
1323
+ color: #ffffff; /* Text color */
1324
+ font-size: 50px;
1325
+ background-image: linear-gradient(0deg, #a689f6 3%, #413bb9 61%);
1326
+ border: none;
1327
+ padding: 10px 20px;
1328
+ cursor: pointer;
1329
+ border-radius: 15px;
1330
+ display: inline-block;
1331
+ }
1332
+ div.stButton > button:hover {
1333
+ background-color: #00ff00; /* Hover background color */
1334
+ color: #ff0000; /* Hover text color */
1335
+ }
1336
+ </style>
1337
+ """
1338
+
1339
+ # Render the button with the specified styles
1340
+ st.markdown(button_styles, unsafe_allow_html=True)
1341
+
1342
  # Given new_mapping dictionary
1343
+ # Handle Default Mapping
1344
+ if st.session_state.button_clicked == 'default':
1345
+ new_mapping = {
1346
+ "GoFynd": {
1347
+ "Marketing": {
1348
+ "Order": ["Placed"]
1349
+ },
1350
+ "Transaction": {
1351
+ "Bag": ["Return Window"],
1352
+ "Shipment": ["Cancelled", "RTO", "DTO"]
1353
+ },
1354
+ "Logistics": {
1355
+ "Shipment": ["Picked", "RTO", "DTO"]
1356
+ },
1357
+ "Packaging": {
1358
+ "Shipment": ["Packed"]
1359
+ }
1360
+ },
1361
+ "Uniket": {
1362
+ "Marketing": {
1363
+ "Order": ["Placed"]
1364
+ },
1365
+ "Transaction": {
1366
+ "Bag": ["Return Window"],
1367
+ "Shipment": ["Cancelled", "RTO", "DTO"]
1368
+ },
1369
+ "Logistics": {
1370
+ "Shipment": ["Picked", "RTO", "DTO"]
1371
+ },
1372
+ "Packaging": {
1373
+ "Shipment": ["Packed"]
1374
+ }
1375
+ },
1376
+ "ONDC": {
1377
+ "Transaction": {
1378
+ "Bag": ["Return Window"],
1379
+ "Shipment": ["Cancelled", "RTO", "DTO"]
1380
+ },
1381
+ "Logistics": {
1382
+ "Shipment": ["Picked", "RTO", "DTO"]
1383
+ },
1384
+ "Packaging": {
1385
+ "Shipment": ["Packed"]
1386
+ }
1387
+ },
1388
+ "StoreOS": {
1389
+ "Licensing": {
1390
+ "Application": ["Setup"]
1391
+ },
1392
+ "Subscription": {
1393
+ "Application": ["Subscribed"],
1394
+ "User": ["Active"],
1395
+ "Resource": ["TechOps-hr", "SiteOps-hr"]
1396
+ },
1397
+ "Marketing": {
1398
+ "Order": ["Placed"]
1399
+ },
1400
+ "Transaction": {
1401
+ "Order": ["Placed"],
1402
+ "Bag": ["Invoiced", "Delivered"]
1403
+ },
1404
+ "Logistics": {
1405
+ "Shipment": ["Picked", "RTO", "DTO"]
1406
+ },
1407
+ "Packaging": {
1408
+ "Shipment": ["Packed"]
1409
+ }
1410
+ },
1411
+ "Website": {
1412
+ "Licensing": {
1413
+ "Application": ["Setup"]
1414
+ },
1415
+ "Subscription": {
1416
+ "Application": ["Subscribed"],
1417
+ "User": ["Active"],
1418
+ "Resource": ["TechOps-hr", "SiteOps-hr"]
1419
+ },
1420
+ "Transaction": {
1421
+ "Order": ["Placed"],
1422
+ "Bag": ["Invoiced", "Delivered"]
1423
+ },
1424
+ "Logistics": {
1425
+ "Shipment": ["Picked", "RTO", "DTO"]
1426
+ },
1427
+ "Packaging": {
1428
+ "Shipment": ["Packed"]
1429
+ },
1430
+ "Development": {
1431
+ "Application": ["Build"]
1432
+ }
1433
+ },
1434
+ "OMS": {
1435
+ "Development": {
1436
+ "Integration": ["Build"]
1437
+ },
1438
+ "Licensing": {
1439
+ "Integration": ["Setup"]
1440
+ },
1441
+ "Subscription": {
1442
+ "Integration": ["Subscribed"],
1443
+ "User": ["Active"],
1444
+ "Resource": ["TechOps-hr", "SiteOps-hr"]
1445
+ },
1446
+ "Transaction": {
1447
+ "Order": ["Placed"],
1448
+ "Bag": ["Invoiced", "Delivered"]
1449
+ }
1450
+ },
1451
+ "WMS": {
1452
+ "Development": {
1453
+ "Integration": ["Build"]
1454
+ },
1455
+ "Licensing": {
1456
+ "Integration": ["Setup"]
1457
+ },
1458
+ "Subscription": {
1459
+ "Integration": ["Subscribed"],
1460
+ "User": ["Active"],
1461
+ "Resource": ["TechOps-hr", "SiteOps-hr"]
1462
+ },
1463
+ "Transaction": {
1464
+ "Order": ["Placed"],
1465
+ "Bag": ["Invoiced", "Delivered"],
1466
+ "B2B": ["Invoiced"],
1467
+ "B2C": ["Invoiced"]
1468
+ }
1469
+ },
1470
+ "TMS": {
1471
+ "Development": {
1472
+ "Integration": ["Build"]
1473
+ },
1474
+ "Licensing": {
1475
+ "Integration": ["Setup"]
1476
+ },
1477
+ "Subscription": {
1478
+ "Integration": ["Subscribed"],
1479
+ "User": ["Active"],
1480
+ "Resource": ["TechOps-hr", "SiteOps-hr"]
1481
+ },
1482
+ "Logistics": {
1483
+ "Shipment": ["Picked", "RTO", "DTO"]
1484
+ }
1485
+ },
1486
+ "GMC": {
1487
+ "Development": {
1488
+ "Extension": ["Build"],
1489
+ "Integration": ["Build"]
1490
+ },
1491
+ "Licensing": {
1492
+ "Extension": ["Setup"]
1493
+ },
1494
+ "Subscription": {
1495
+ "Extension": ["Subscribed"],
1496
+ "User": ["Active"],
1497
+ "Resource": ["TechOps-hr", "SiteOps-hr"]
1498
+ }
1499
+ },
1500
+ "Partner": {
1501
+ "Development": {
1502
+ "Extension": ["Build"]
1503
+ },
1504
+ "Licensing": {
1505
+ "Extension": ["Setup"]
1506
+ },
1507
+ "Subscription": {
1508
+ "Extension": ["Subscribed"],
1509
+ "User": ["Active"],
1510
+ "Resource": ["TechOps-hr", "SiteOps-hr"]
1511
+ }
1512
+ },
1513
+ "Catalog Cloud": {
1514
+ "Development": {
1515
+ "Extension": ["Build"]
1516
+ },
1517
+ "Licensing": {
1518
+ "Extension": ["Setup"]
1519
+ },
1520
+ "Subscription": {
1521
+ "Extension": ["Subscribed"],
1522
+ "User": ["Active"],
1523
+ "Resource": ["TechOps-hr", "SiteOps-hr"]
1524
+ }
1525
+ },
1526
+ "FCP": {
1527
+ "Subscription": {
1528
+ "Platform": ["Subscribed"],
1529
+ "User": ["Active"],
1530
+ "Resource": ["TechOps-hr", "SiteOps-hr"]
1531
+ }
1532
+ },
1533
+ "PixelBin": {
1534
+ "Subscription": {
1535
+ "Platform": ["Subscribed"],
1536
+ "User": ["Active"],
1537
+ "Resource": ["TechOps-hr", "SiteOps-hr"]
1538
+ }
1539
+ },
1540
+ "Boltic": {
1541
+ "Subscription": {
1542
+ "Platform": ["Subscribed"],
1543
+ "User": ["Active"],
1544
+ "Resource": ["TechOps-hr", "SiteOps-hr"]
1545
+ }
1546
+ },
1547
+ "CoPilot": {
1548
+ "Subscription": {
1549
+ "Platform": ["Subscribed"],
1550
+ "User": ["Active"],
1551
+ "Resource": ["TechOps-hr", "SiteOps-hr"]
1552
+ }
1553
  }
1554
+ }
1555
+
1556
+ st.session_state['new_mapping'] = new_mapping
1557
+ st.session_state['mapping_mode'] = 'default'
1558
+
1559
+ html_content_1 = """
1560
+ <h1 style='
1561
+ color: #a689f6;
1562
+ font-size: 22px;
1563
+ background-image: -webkit-linear-gradient(0deg, #a689f6 3%, #272191 33%, #413bb9 61%);
1564
+ background-clip: text;
1565
+ -webkit-background-clip: text;
1566
+ text-fill-color: transparent;
1567
+ -webkit-text-fill-color: transparent;
1568
+ '>Section 2: Rule Info</h1>
1569
+ """
1570
+
1571
+ st.sidebar.markdown(html_content_1, unsafe_allow_html=True)
1572
+
1573
+ # Handle Custom Mapping
1574
+ elif st.session_state.button_clicked == 'custom':
1575
+
1576
+ # Define CSS styles for the button
1577
+ button_styles = """
1578
+ <style>
1579
+ div.stButton > button {
1580
+ color: #ffffff; /* Text color */
1581
+ font-size: 50px;
1582
+ background-image: linear-gradient(0deg, #a689f6 3%, #413bb9 61%);
1583
+ border: none;
1584
+ padding: 10px 20px;
1585
+ cursor: pointer;
1586
+ border-radius: 15px;
1587
+ display: inline-block;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1588
  }
1589
+ div.stButton > button:hover {
1590
+ background-color: #00ff00; /* Hover background color */
1591
+ color: #ff0000; /* Hover text color */
 
 
 
1592
  }
1593
+ </style>
1594
+ """
1595
+
1596
+ # Render the button with the specified styles
1597
+ st.markdown(button_styles, unsafe_allow_html=True)
1598
+
1599
+ # File upload
1600
+ uploaded_file = st.sidebar.file_uploader("Upload a file:", type=['csv', 'xlsx'], key='file_uploader')
1601
+
1602
+ html_content_1 = """
1603
+ <h1 style='
1604
+ color: #a689f6;
1605
+ font-size: 22px;
1606
+ background-image: -webkit-linear-gradient(0deg, #a689f6 3%, #272191 33%, #413bb9 61%);
1607
+ background-clip: text;
1608
+ -webkit-background-clip: text;
1609
+ text-fill-color: transparent;
1610
+ -webkit-text-fill-color: transparent;
1611
+ '>Section 2: Rule Info</h1>
1612
+ """
1613
+
1614
+ st.sidebar.markdown(html_content_1, unsafe_allow_html=True)
1615
+
1616
+ if uploaded_file is not None:
1617
+ try:
1618
+ # Read the file, treating the first row as the header
1619
+ if uploaded_file.name.endswith('.csv'):
1620
+ data = pd.read_csv(uploaded_file, header=0)
1621
+ elif uploaded_file.name.endswith('.xlsx'):
1622
+ data = pd.read_excel(uploaded_file, header=0)
1623
+
1624
+ if st.sidebar.button("Overwrite headers"):
1625
+ # Rename the headers
1626
+ new_headers = ['ordering_channel', 'fee_type', 'variable_type', 'chargeable_on']
1627
+ data.columns = new_headers
1628
+
1629
+ # Save the data to session state
1630
+ st.session_state['file_data'] = data
1631
+
1632
+ # Initialize the mapping
1633
+ new_mapping = {}
1634
+
1635
+
1636
+
1637
+ # Build the mapping
1638
+ for _, row in data.iterrows():
1639
+
1640
+
1641
+ ordering_channel = row['ordering_channel']
1642
+ fee_type = row['fee_type']
1643
+ variable_type = row['variable_type']
1644
+ chargeable_on = row['chargeable_on']
1645
+
1646
+ if ordering_channel not in new_mapping:
1647
+ new_mapping[ordering_channel] = {}
1648
+
1649
+ if fee_type not in new_mapping[ordering_channel]:
1650
+ new_mapping[ordering_channel][fee_type] = {}
1651
+
1652
+ if variable_type not in new_mapping[ordering_channel][fee_type]:
1653
+ new_mapping[ordering_channel][fee_type][variable_type] = []
1654
 
1655
+ if chargeable_on not in new_mapping[ordering_channel][fee_type][variable_type]:
1656
+ new_mapping[ordering_channel][fee_type][variable_type].append(chargeable_on)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1657
 
1658
+ st.session_state['new_mapping'] = new_mapping
1659
+ st.session_state['mapping_mode'] = 'custom'
1660
+
1661
+ except Exception as e:
1662
+ st.error(f"Error reading the file: {e}")
1663
  # Section 2: Company Info
1664
 
1665
+
 
 
 
 
 
 
 
 
 
 
1666
 
 
1667
 
1668
+ # Handle mapping display
1669
+ # Initialize session state variables if they don't exist
1670
+ # Initialize session state variables with default values if not already set
1671
+ if 'business_head' not in st.session_state:
1672
+ st.session_state['business_head'] = None
1673
+ if 'company_id' not in st.session_state:
1674
+ st.session_state['company_id'] = None
1675
+ if 'company_name' not in st.session_state:
1676
+ st.session_state['company_name'] = None
1677
+ if 'currency' not in st.session_state:
1678
+ st.session_state['currency'] = None
1679
+ if 'bundle_by' not in st.session_state:
1680
+ st.session_state['bundle_by'] = None
1681
+ if 'plan_name' not in st.session_state:
1682
+ st.session_state['plan_name'] = None
1683
+ if 'plan_description' not in st.session_state:
1684
+ st.session_state['plan_description'] = None
1685
+ if 'selected_ordering_channel' not in st.session_state:
1686
+ st.session_state['selected_ordering_channel'] = None
1687
+ if 'fulfilling_location' not in st.session_state:
1688
+ st.session_state['fulfilling_location'] = None
1689
+ if 'application_id' not in st.session_state:
1690
+ st.session_state['application_id'] = None
1691
+ if 'selected_fee_type' not in st.session_state:
1692
+ st.session_state['selected_fee_type'] = None
1693
+ if 'selected_variable_type' not in st.session_state:
1694
+ st.session_state['selected_variable_type'] = None
1695
+ if 'selected_chargeable_on' not in st.session_state:
1696
+ st.session_state['selected_chargeable_on'] = None
1697
+ if 'selected_fee_nature' not in st.session_state:
1698
+ st.session_state['selected_fee_nature'] = None
1699
+ if 'user_input_3' not in st.session_state:
1700
+ st.session_state['user_input_3'] = None
1701
+ if 'usage_3' not in st.session_state:
1702
+ st.session_state['usage_3'] = None
1703
+ if 'Capping_or_Minimum_Guarantee_3' not in st.session_state:
1704
+ st.session_state['Capping_or_Minimum_Guarantee_3'] = None
1705
+ if 'threshold' not in st.session_state:
1706
+ st.session_state['threshold'] = None
1707
+ if 'expected_billing' not in st.session_state:
1708
+ st.session_state['expected_billing'] = None
1709
+ if 'selected_payment_method' not in st.session_state:
1710
+ st.session_state['selected_payment_method'] = None
1711
+ if 'selected_plan_validity' not in st.session_state:
1712
+ st.session_state['selected_plan_validity'] = None
1713
+ if 'final_billing' not in st.session_state:
1714
+ st.session_state['final_billing'] = None
1715
+ if 'fee_reversal' not in st.session_state:
1716
+ st.session_state['fee_reversal'] = None
1717
+ if 'reversal_per' not in st.session_state:
1718
+ st.session_state['reversal_per'] = None
1719
+
1720
+
1721
+ # Check if 'mapping_mode' exists in session state before using it
1722
+ if 'mapping_mode' in st.session_state and st.session_state['mapping_mode']:
1723
+ # 1st layer: Select ordering channel
1724
+ selected_ordering_channel = st.sidebar.selectbox(
1725
+ "Product lines",
1726
+ [""] + list(st.session_state['new_mapping'].keys()),
1727
+ help="Select a Product line",
1728
+ key='ordering_channel'
1729
+ )
1730
+
1731
+ if selected_ordering_channel:
1732
+ selected_ordering_channel = str(selected_ordering_channel) or int(selected_ordering_channel)
1733
+
1734
+ # Determine fulfilling_location and application_id based on selected_ordering_channel
1735
+ if any(channel in selected_ordering_channel for channel in ["TMS", "GMC", "Catalog Cloud"]):
1736
+ st.session_state['fulfilling_location'] = None
1737
+ st.session_state['application_id'] = None
1738
+ else:
1739
+ abc = ["Store", "Warehouse"]
1740
+ st.session_state['fulfilling_location'] = st.sidebar.selectbox(
1741
+ "Fulfilling Location", [""] + abc, help="Select the fulfilling location"
1742
+ )
1743
+ st.session_state['application_id'] = st.sidebar.text_input(
1744
+ "Application ID", key="application_id_input", help="Enter the application ID"
1745
+ )
1746
 
1747
+ # Use the session state variables in your app
1748
+ fulfilling_location = st.session_state['fulfilling_location']
1749
+ application_id = st.session_state['application_id']
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1750
 
 
 
 
 
 
 
 
 
 
 
 
 
1751
 
1752
+
1753
+ # 2nd layer: Select fee type based on the selected ordering channel
1754
+
1755
+ if 'selected_fee_type' not in st.session_state:
1756
+ st.session_state['selected_fee_type'] = None
1757
+
1758
+ fee_types_for_channel = st.session_state['new_mapping'].get(selected_ordering_channel, {}).keys()
1759
+ fee_types_for_channel = list(fee_types_for_channel)
1760
+
1761
+ if fee_types_for_channel:
1762
+
1763
+
1764
+ # Define selected_fee_type based on user input
1765
+
1766
+ st.session_state['selected_fee_type'] = st.selectbox(
1767
+ "Fee Type",
1768
+ [""] + fee_types_for_channel,
1769
+ help="Fee type is a revenue head for grouping the revenue",
1770
+ key='fee_type'
1771
+ )
1772
+
1773
+ # Access selected_fee_type for any session state operations
1774
+ selected_fee_type = st.session_state['selected_fee_type']
1775
+
1776
+ # 3rd layer: Select variable type based on the selected fee type
1777
+ variable_type_options = []
1778
+ if selected_fee_type:
1779
+ details = st.session_state['new_mapping'].get(selected_ordering_channel, {})
1780
+ variables = details.get(selected_fee_type, {})
1781
+ variable_type_options = list(variables.keys())
1782
+
1783
+ st.session_state['selected_variable_type'] = st.selectbox(
1784
+ "Variable Type",
1785
+ [""] + variable_type_options,
1786
+ help="Variable type is an attribute on which revenue calculation will be done",
1787
+ key='variable_type'
1788
+ )
1789
+
1790
+ selected_variable_type = st.session_state['selected_variable_type']
1791
+
1792
+
1793
+ # 4th layer: Select chargeable on based on the selected variable type
1794
+ chargeable_on_options = []
1795
+ if selected_variable_type:
1796
+ chargeable_on_options = variables.get(selected_variable_type, [])
1797
+
1798
+ st.session_state['selected_chargeable_on'] = st.selectbox(
1799
+ "Chargeable on",
1800
+ [""] + chargeable_on_options,
1801
+ help="Chargeable on is a service status on which the above fee will be applicable",
1802
+ key='chargeable_on'
1803
+ )
1804
+
1805
+ selected_chargeable_on = st.session_state['selected_chargeable_on']
1806
+
1807
+ else:
1808
+ st.write("No fee types available for the selected ordering channel.")
1809
+ else:
1810
+ st.write("")
1811
+
1812
+
1813
+ selected_variable_type = st.session_state['selected_variable_type']
1814
 
1815
  usage_1 = st.number_input(f"Usage limit for {selected_variable_type}", min_value=0.0, help="Enter the usage limit")
1816
  usage_2 = float(usage_1)
 
1892
 
1893
  rule_id = None
1894
  plan_id = None
1895
+ business_head = st.session_state['business_head']
1896
+ company_name = st.session_state['company_name']
1897
+ company_id = st.session_state['company_id']
1898
+ currency = st.session_state['currency']
1899
+ # bundle_by = st.session_state['bundle_by']
1900
+ plan_name = st.session_state['plan_name']
1901
+ plan_description = st.session_state['plan_description']
1902
+ selected_ordering_channel = st.session_state['selected_ordering_channel']
1903
+ fulfilling_location = st.session_state['fulfilling_location']
1904
+ application_id = st.session_state['application_id']
1905
+ selected_fee_type = st.session_state['selected_fee_type']
1906
+ selected_variable_type = st.session_state['selected_variable_type']
1907
+ selected_chargeable_on = st.session_state['selected_chargeable_on']
1908
+ user_input_3 = st.session_state['user_input_3']
1909
+ usage_3 = st.session_state['usage_3']
1910
+ Capping_or_Minimum_Guarantee_3 = st.session_state['Capping_or_Minimum_Guarantee_3']
1911
+ fee_reversal = st.session_state['fee_reversal']
1912
+ reversal_per = st.session_state['reversal_per']
1913
+ threshold = st.session_state['threshold']
1914
+ expected_billing = st.session_state['expected_billing']
1915
+ selected_payment_method = st.session_state['selected_payment_method']
1916
+ selected_plan_validity = st.session_state['selected_plan_validity']
1917
+ final_billing = int(st.session_state['final_billing']) if st.session_state['final_billing'] is not None else 0
1918
+
1919
+
1920
 
1921
  # Submit button
1922
  if st.button("Submit"):
1923
  # Save user data
1924
  user_data = {
1925
  "Business Head": business_head,
1926
+ "Company ID": company_id.strip() if company_id else None,
1927
  "Company Name": company_name,
1928
  "Currency": currency,
1929
  "Bundle by": bundle_by,
 
1935
  "Fee Type": selected_fee_type,
1936
  "Variable Type": selected_variable_type,
1937
  "Chargeable on": selected_chargeable_on,
1938
+ "Fee Nature": " ",
1939
  "Commercial value": user_input_3,
1940
  "Fee reversal": 0,
1941
  "Reversal %": 0,
 
2003
 
2004
 
2005
 
 
2006
  project_id = "fynd-db"
2007
  dataset_id = "finance_dwh"
2008
  table_id = "plan_v2"
2009
+ fulfilling_location = st.session_state['fulfilling_location']
2010
+ application_id = st.session_state['application_id']
2011
+ # bundle_by = st.session_state['bundle_by']
2012
+
2013
+
2014
+ created_at = datetime.now().isoformat()
2015
+
2016
+
2017
  user_data = {
2018
  "Business_Head": business_head,
2019
+ "Company_ID": company_id if company_id and company_id.strip() else None,
2020
  "Company_Name": company_name,
2021
  "Currency": currency,
2022
  "Bundle_by": bundle_by,
 
2028
  "Fee_Type": selected_fee_type,
2029
  "Variable_Type": selected_variable_type,
2030
  "Chargeable_on": selected_chargeable_on,
2031
+ "Fee_Nature": " ",
2032
  "Commercial_value": user_input_3,
2033
  "Fee_reversal": 0,
2034
  "Reversal_%": 0,
 
2040
  "Plan_Validity": selected_plan_validity,
2041
  "rule_id": rule_id,
2042
  "plan_id": plan_id,
2043
+ "created_at": created_at,
2044
  "Net_total_billing":int(final_billing)
2045
  }
2046
 
2047
+ global_user_data.append((user_name, user_data))
2048
+
2049
+ # Generate PM_id and add it to user_data
2050
+ rule_id = generate_rule_id(user_data)
2051
+ user_data['rule_id'] = rule_id
2052
+
2053
+ # Generate Plan ID and add it to user_data
2054
+ plan_id = generate_plan_id(user_data)
2055
+ user_data['plan_id'] = plan_id
2056
+
2057
+
2058
+ save_user_data(user_data)
2059
+
2060
  service_account_info = {
2061
  "type": "service_account",
2062
  "project_id": "fynd-db",
 
2107
  # Start a tunnel to the correct port
2108
 
2109
  # Connect to a port (e.g., 8501) without a custom subdomain
2110
+ try:
2111
+ ngrok_tunnel = ngrok.connect(8501) # Replace 8501 with your port number
2112
+ print(f"ngrok tunnel URL: {ngrok_tunnel.public_url}")
2113
+ except Exception as e:
2114
+ print(f"Failed to start ngrok tunnel: {e}")