finished pricebook2 & pricebookentry
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@ -14,4 +14,6 @@ Asset.csv
|
|||||||
.env
|
.env
|
||||||
venv/
|
venv/
|
||||||
*Location.csv
|
*Location.csv
|
||||||
Product2.csv
|
Product2.csv
|
||||||
|
Pricebook2.csv
|
||||||
|
PricebookEntry.csv
|
@ -1,15 +1,16 @@
|
|||||||
# FSL Migration from Legacy with SFDMU & Python (Pandas)
|
# FSL Migration from Legacy with SFDMU & Python
|
||||||
|
|
||||||
This git is representing a migration from Legacy GMS solution to FSL Standard
|
This git is representing a migration from Legacy GMS solution to FSL Standard
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Install Python [python](https://www.python.org/) to install python 3.13+.
|
Install Python [python](https://www.python.org/) to install python 3.13+.
|
||||||
After installation open a terminal/powershell to install pandas globally
|
After installation open a terminal/powershell to install the packages globally
|
||||||
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python -m pip install pandas
|
cd ./migration_via_sfdmu-main
|
||||||
|
python -m pip install -r ./requirements.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
Type,ActiveFrom,ActiveTo,ParentRecordId,PKey__c,LocationId
|
||||||
|
Installer (installation),2018-03-27,,0019Z00000fmCAYQA2,"Mr. P.J.M. Aalberselaan 19, 1181 XJ AMSTELVEEN, NL;;;",1319Z000000ij1RQAQ
|
||||||
|
Owner,2018-04-06,,0019Z00000fmCAYQA2,"Mr. P.J.M. Aalberselaan 19, 1181 XJ AMSTELVEEN, NL;;;",1319Z000000ij1RQAQ
|
|
@ -0,0 +1 @@
|
|||||||
|
sf sfdmu run --sourceusername csvfile --targetusername rene.kasseboehmer@vaillant.de.devrene
|
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"allOrNone": true,
|
||||||
|
"excludeIdsFromCSVFiles": true,
|
||||||
|
"objects": [
|
||||||
|
{
|
||||||
|
"query": "SELECT Id, ProductCode FROM Product2",
|
||||||
|
"operation": "Readonly",
|
||||||
|
"master": false,
|
||||||
|
"externalId": "ProductCode"
|
||||||
|
},{
|
||||||
|
"query": "SELECT Business_Type__c, IsStandard, IsActive, Name, Brand__c, Country__c FROM Pricebook2",
|
||||||
|
"operation": "Insert",
|
||||||
|
"externalId": "Name",
|
||||||
|
"master": true,
|
||||||
|
"useSourceCSVFile": true
|
||||||
|
},{
|
||||||
|
"query": "SELECT IsActive, Product2Id, UnitPrice, Pricebook2Id FROM PricebookEntry",
|
||||||
|
"operation": "Insert",
|
||||||
|
"master": true,
|
||||||
|
"useSourceCSVFile": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
1
prepared_steps/12_insert_/command.txt
Normal file
1
prepared_steps/12_insert_/command.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
sf sfdmu run --sourceusername csvfile --targetusername rene.kasseboehmer@vaillant.de.devrene
|
10
prepared_steps/12_insert_/export.json
Normal file
10
prepared_steps/12_insert_/export.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"allOrNone": true,
|
||||||
|
"excludeIdsFromCSVFiles": true,
|
||||||
|
"objects": [
|
||||||
|
{
|
||||||
|
"query": "SELECT Business_Type__c, IsStandard, IsActive, Name, Brand__c, Country__c FROM Pricebook2",
|
||||||
|
"operation": "Insert"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -147,11 +147,13 @@ def extract_data(object_id, query, output_path='output', context='qa2'):
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
# Parse command-line arguments
|
# Parse command-line arguments
|
||||||
parser = argparse.ArgumentParser(description='Extract Salesforce data via Bulk API')
|
parser = argparse.ArgumentParser(description='Extract Salesforce data via Bulk API')
|
||||||
parser.add_argument('--context', type=str, required=True,
|
parser.add_argument('--context', type=str, required=True,
|
||||||
help='Context name (e.g., "qa2", "prod")')
|
help='Context name (e.g., "qa2", "prod")')
|
||||||
|
parser.add_argument('--country', type=str, required=True,
|
||||||
|
help='CountryCode (e.g., "NL", "UK")')
|
||||||
parser.add_argument('--output_path', type=str, required=False,
|
parser.add_argument('--output_path', type=str, required=False,
|
||||||
help='./')
|
help='./')
|
||||||
parser.add_argument('--sobjects', type=str, required=False,
|
parser.add_argument('--sobjects', type=str, required=False,
|
||||||
@ -170,7 +172,7 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
for query_def in queries:
|
for query_def in queries:
|
||||||
sobject = query_def['sobject']
|
sobject = query_def['sobject']
|
||||||
query_str = query_def['query']
|
query_str = query_def['query'].replace('{country}', args.country)
|
||||||
|
|
||||||
# Skip if --sobjects is provided and current sobject isn't in the list
|
# Skip if --sobjects is provided and current sobject isn't in the list
|
||||||
if selected_sobjects and sobject not in selected_sobjects:
|
if selected_sobjects and sobject not in selected_sobjects:
|
||||||
|
@ -2,28 +2,34 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"sobject": "SCInstalledBaseLocation__c",
|
"sobject": "SCInstalledBaseLocation__c",
|
||||||
"query": "SELECT Id, City__c, Country__c, GeoY__c, GeoX__c, PostalCode__c, Street__c, Extension__c, HouseNo__c, FlatNo__c, Floor__c FROM SCInstalledBaseLocation__c WHERE Country__c = 'NL' AND Id = 'a1B1r0000099EsfEAE' limit 1"
|
"query": "SELECT Id, City__c, Country__c, GeoY__c, GeoX__c, PostalCode__c, Street__c, Extension__c, HouseNo__c, FlatNo__c, Floor__c FROM SCInstalledBaseLocation__c WHERE Country__c = '{country}' AND Id = 'a1B1r0000099EsfEAE' limit 1"
|
||||||
},{
|
},{
|
||||||
"sobject": "SCInstalledBase__c",
|
"sobject": "SCInstalledBase__c",
|
||||||
"query": "SELECT Id, Name, CommissioningDate__c,InstallationDate__c,ProductEnergy__c, ProductUnitClass__c,ArticleNo__c,SerialNo__c, SerialNoException__c, ProductUnitType__c, InstalledBaseLocation__c FROM SCInstalledBase__c WHERE Country__c = 'NL' AND InstalledBaseLocation__c = 'a1B1r0000099EsfEAE'"
|
"query": "SELECT Id, Name, CommissioningDate__c,InstallationDate__c,ProductEnergy__c, ProductUnitClass__c,ArticleNo__c,SerialNo__c, SerialNoException__c, ProductUnitType__c, InstalledBaseLocation__c FROM SCInstalledBase__c WHERE Country__c = '{country}' AND InstalledBaseLocation__c = 'a1B1r0000099EsfEAE'"
|
||||||
},{
|
},{
|
||||||
"sobject": "Asset",
|
"sobject": "Asset",
|
||||||
"query": "SELECT Id, Serialnumber FROM Asset WHERE Location.ParentLocation.Name LIKE '%NL'"
|
"query": "SELECT Id, Serialnumber FROM Asset WHERE Location.ParentLocation.Name LIKE '%{country}'"
|
||||||
},{
|
},{
|
||||||
"sobject": "Address",
|
"sobject": "Address",
|
||||||
"query": "SELECT Id, Country, CountryCode, Street, City, ParentId, PostalCode FROM Address WHERE CountryCode = 'NL'"
|
"query": "SELECT Id, Country, CountryCode, Street, City, ParentId, PostalCode FROM Address WHERE CountryCode = '{country}'"
|
||||||
},{
|
},{
|
||||||
"sobject": "ParentLocation",
|
"sobject": "ParentLocation",
|
||||||
"query": "SELECT Id, Name FROM Location WHERE Name LIKE '%NL'"
|
"query": "SELECT Id, Name FROM Location WHERE Name LIKE '%{country}'"
|
||||||
},{
|
},{
|
||||||
"sobject": "ChildLocation",
|
"sobject": "ChildLocation",
|
||||||
"query": "SELECT Id, ParentLocationId, Name FROM Location WHERE ParentLocation.Name LIKE '%NL'"
|
"query": "SELECT Id, ParentLocationId, Name FROM Location WHERE ParentLocation.Name LIKE '%{country}'"
|
||||||
},{
|
},{
|
||||||
"sobject": "Product2",
|
"sobject": "Product2",
|
||||||
"query": "SELECT Id, Main_Product_Group__c, Family, MaterialType__c, Name, Product_Code__c, ProductCode, EAN_Product_Code__c FROM Product2"
|
"query": "SELECT Id, Main_Product_Group__c, Family, MaterialType__c, Name, Product_Code__c, ProductCode, EAN_Product_Code__c FROM Product2"
|
||||||
},{
|
},{
|
||||||
"sobject": "SCInstalledBaseRole__c",
|
"sobject": "SCInstalledBaseRole__c",
|
||||||
"query": "SELECT Id, InstalledBaseLocation__c, Role__c, ValidFrom__c, ValidTo__c, Account__c FROM SCInstalledBaseRole__c WHERE InstalledBaseLocation__r.Country__c = 'NL' AND InstalledBaseLocation__c = 'a1B1r0000099EsfEAE'"
|
"query": "SELECT Id, InstalledBaseLocation__c, Role__c, ValidFrom__c, ValidTo__c, Account__c FROM SCInstalledBaseRole__c WHERE InstalledBaseLocation__r.Country__c = '{country}' AND InstalledBaseLocation__c = 'a1B1r0000099EsfEAE'"
|
||||||
|
},{
|
||||||
|
"sobject": "SCPriceList__c",
|
||||||
|
"query": "SELECT Id, Name, Brand__r.Name, Country__c from SCPriceList__c WHERE Country__c = '{country}' AND PriceList__c != null"
|
||||||
|
},{
|
||||||
|
"sobject": "SCPriceListItem__c",
|
||||||
|
"query": "SELECT Id, Article__r.Name, Price__c, PriceUnit__c, Pricelist__c, ValidFrom__c, ValidTo__c, Article__r.EANCode__c, Pricelist__r.Brand__r.Name, Pricelist__r.Country__c FROM SCPriceListItem__c WHERE Country__c = '{country}' AND PriceList__c != null AND (ValidTo__c >= TODAY OR ValidFrom__c >= TODAY) AND Article__c = 'a0Gw000001R9slpEAB'"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
"Id","Article__r.Name","Article__r.EANCode__c","Price__c","PriceUnit__c","Pricelist__c","ValidFrom__c","ValidTo__c","Pricelist__r.Brand__r.Name","Pricelist__r.Country__c"
|
||||||
|
"a0p6900000eZ3nbAAC","0010021907","4024074807507","2011.85","1.0","a0q20000000PO8OAAW","2021-01-01","2099-12-31","Vaillant","NL"
|
|
3
prepared_steps/1_extract_data/results/SCPriceList__c.csv
Normal file
3
prepared_steps/1_extract_data/results/SCPriceList__c.csv
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
"Id","Name","Brand__r.Name","Country__c"
|
||||||
|
"a0q20000000PO8OAAW","NL Vaillant","Vaillant","NL"
|
||||||
|
"a0q20000000PO8TAAW","NL AWB","AWB","NL"
|
|
@ -10,6 +10,8 @@ read_df = pd.read_csv('../1_extract_data/results/SCInstalledBaseLocation__c.csv'
|
|||||||
read_df_ib = pd.read_csv('../1_extract_data/results/SCInstalledBase__c.csv', header=0, keep_default_na=False, dtype=str)
|
read_df_ib = pd.read_csv('../1_extract_data/results/SCInstalledBase__c.csv', header=0, keep_default_na=False, dtype=str)
|
||||||
read_df_product2 = pd.read_csv('../1_extract_data/results/Product2.csv', header=0, keep_default_na=False, dtype=str)
|
read_df_product2 = pd.read_csv('../1_extract_data/results/Product2.csv', header=0, keep_default_na=False, dtype=str)
|
||||||
read_df_ibr = pd.read_csv('../1_extract_data/results/SCInstalledBaseRole__c.csv', header=0, keep_default_na=False, dtype=str)
|
read_df_ibr = pd.read_csv('../1_extract_data/results/SCInstalledBaseRole__c.csv', header=0, keep_default_na=False, dtype=str)
|
||||||
|
read_df_pricelist = pd.read_csv('../1_extract_data/results/SCPriceList__c.csv', header=0, keep_default_na=False, dtype=str)
|
||||||
|
read_df_pricelistitem = pd.read_csv('../1_extract_data/results/SCPriceListItem__c.csv', header=0, keep_default_na=False, dtype=str)
|
||||||
|
|
||||||
for row in read_df.to_dict('records'):
|
for row in read_df.to_dict('records'):
|
||||||
try:
|
try:
|
||||||
@ -31,13 +33,19 @@ reindex_columns_product2 = ['Id','Main_Product_Group__c','Family','MaterialType_
|
|||||||
#reindex_columns_product2 = ['EAN_Product_Code__c','Family','Id','Main_Product_Group__c','MaterialType__c','Name','Product_Code__c','ProductCode']
|
#reindex_columns_product2 = ['EAN_Product_Code__c','Family','Id','Main_Product_Group__c','MaterialType__c','Name','Product_Code__c','ProductCode']
|
||||||
#"Id","InstalledBaseLocation__c","Role__c","ValidFrom__c","ValidTo__c","Account__c"
|
#"Id","InstalledBaseLocation__c","Role__c","ValidFrom__c","ValidTo__c","Account__c"
|
||||||
reindex_columns_ibr = ['Id', 'InstalledBaseLocation__c', 'Role__c', 'ValidFrom__c', 'ValidTo__c', 'Account__c']
|
reindex_columns_ibr = ['Id', 'InstalledBaseLocation__c', 'Role__c', 'ValidFrom__c', 'ValidTo__c', 'Account__c']
|
||||||
|
reindex_columns_pricelist = ['Id', 'Name', 'Brand__r.Name', 'Country__c']
|
||||||
|
reindex_columns_pricelistitem = ['Id', 'Article__r.Name', 'Article__r.EANCode__c', 'Price__c', 'PriceUnit__c', 'Pricelist__c', 'ValidFrom__c', 'ValidTo__c', 'Pricelist__r.Brand__r.Name', 'Pricelist__r.Country__c']
|
||||||
|
|
||||||
# Reindex the columns to match the desired format
|
# Reindex the columns to match the desired format
|
||||||
df = read_df.reindex(reindex_columns, axis=1)
|
df = read_df.reindex(reindex_columns, axis=1)
|
||||||
df_ib = read_df_ib.reindex(reindex_columns_ib, axis=1)
|
df_ib = read_df_ib.reindex(reindex_columns_ib, axis=1)
|
||||||
df_product2 = read_df_product2.reindex(reindex_columns_product2, axis=1)
|
df_product2 = read_df_product2.reindex(reindex_columns_product2, axis=1)
|
||||||
df_ibr = read_df_ibr.reindex(reindex_columns_ibr, axis=1)
|
df_ibr = read_df_ibr.reindex(reindex_columns_ibr, axis=1)
|
||||||
|
df_pricelist = read_df_pricelist.reindex(reindex_columns_pricelist, axis=1)
|
||||||
|
df_pricelistitem = read_df_pricelistitem.reindex(reindex_columns_pricelistitem, axis=1)
|
||||||
|
|
||||||
|
#creating street column
|
||||||
|
# Concatenate 'Street__c' and 'HouseNo__c' to create the 'Street' column
|
||||||
df['Street'] = (
|
df['Street'] = (
|
||||||
df['Street__c'].astype(str) + ' ' +
|
df['Street__c'].astype(str) + ' ' +
|
||||||
df['HouseNo__c'].astype(str)
|
df['HouseNo__c'].astype(str)
|
||||||
@ -246,14 +254,55 @@ for index, row in tqdm(merged_df_ib.iterrows(), total=len(merged_df_ib)):
|
|||||||
if product_group not in valid_groups:
|
if product_group not in valid_groups:
|
||||||
merged_df_ib.loc[index, 'Kind_of_Energy__c'] = None # or set to empty string
|
merged_df_ib.loc[index, 'Kind_of_Energy__c'] = None # or set to empty string
|
||||||
|
|
||||||
print(merged_df_ib)
|
|
||||||
|
|
||||||
|
# Pricelist to Pricebook2
|
||||||
|
columns_pricebook2 = ['Id', 'Name', 'Brand__c', 'Country__c']
|
||||||
|
|
||||||
|
df_pricelist.columns = columns_pricebook2
|
||||||
|
|
||||||
|
df_pricelist.insert(0, 'IsActive', 'true')
|
||||||
|
df_pricelist.insert(0, 'IsStandard', 'false')
|
||||||
|
df_pricelist.insert(0, 'Business_Type__c', 'Service')
|
||||||
|
|
||||||
|
df_pricelist['Name'] = (
|
||||||
|
df_pricelist['Country__c'].astype(str).fillna('').str.upper() + ' ' +
|
||||||
|
df_pricelist['Brand__c'].astype(str).fillna('').str.upper() + ' ' +
|
||||||
|
df_pricelist['Business_Type__c'].astype(str).fillna('').str.upper()
|
||||||
|
)
|
||||||
|
|
||||||
|
df_pricelist = df_pricelist.drop('Id', axis=1)
|
||||||
|
|
||||||
|
df_pricelistitem['Pricebook2.Name'] = (
|
||||||
|
df_pricelistitem['Pricelist__r.Country__c'].astype(str).fillna('').str.upper() + ' ' +
|
||||||
|
df_pricelistitem['Pricelist__r.Brand__r.Name'].astype(str).fillna('').str.upper() + ' ' +
|
||||||
|
'SERVICE'
|
||||||
|
)
|
||||||
|
|
||||||
|
df_pricelistitem = df_pricelistitem.drop('Id', axis=1)
|
||||||
|
df_pricelistitem = df_pricelistitem.drop('PriceUnit__c', axis=1)
|
||||||
|
df_pricelistitem = df_pricelistitem.drop('Pricelist__c', axis=1)
|
||||||
|
df_pricelistitem = df_pricelistitem.drop('ValidFrom__c', axis=1)
|
||||||
|
df_pricelistitem = df_pricelistitem.drop('ValidTo__c', axis=1)
|
||||||
|
df_pricelistitem = df_pricelistitem.drop('Pricelist__r.Country__c', axis=1)
|
||||||
|
df_pricelistitem = df_pricelistitem.drop('Pricelist__r.Brand__r.Name', axis=1)
|
||||||
|
|
||||||
|
df_pricelistitem.insert(0, 'IsActive', 'true')
|
||||||
|
|
||||||
|
print(df_pricelistitem)
|
||||||
|
|
||||||
|
columns_pricebookentry = ['IsActive', 'Product2.Product_Code__c', 'Product2.EAN_Product_Code__c', 'UnitPrice', 'Pricebook2.Name']
|
||||||
|
|
||||||
|
df_pricelistitem.columns = columns_pricebookentry
|
||||||
|
|
||||||
# Write each DataFrame to a separate CSV file
|
# Write each DataFrame to a separate CSV file
|
||||||
address_df.to_csv('../3_upsert_address_and_parent_location/Address.csv', index=False)
|
address_df.to_csv('../3_upsert_address_and_parent_location/Address.csv', index=False)
|
||||||
parent_df.to_csv('../3_upsert_address_and_parent_location/Location.csv', index=False)
|
parent_df.to_csv('../3_upsert_address_and_parent_location/Location.csv', index=False)
|
||||||
child_df.to_csv('../5_upsert_child_location/Location.csv', index=False)
|
child_df.to_csv('../5_upsert_child_location/Location.csv', index=False)
|
||||||
merged_df_ib.to_csv('../7_upsert_assets/Asset.csv', index=False)
|
merged_df_ib.to_csv('../7_upsert_assets/Asset.csv', index=False)
|
||||||
df_ibr.to_csv('../9_upsert_associated_location/AssociatedLocation.csv', index=False)
|
df_ibr.to_csv('../10_upsert_associated_location/AssociatedLocation.csv', index=False)
|
||||||
|
df_pricelist.to_csv('../11_insert_pricebook2/Pricebook2.csv', index=False)
|
||||||
|
df_pricelistitem.to_csv('../11_insert_pricebook2/PricebookEntry.csv', index=False)
|
||||||
|
|
||||||
## end mapping
|
## end mapping
|
||||||
|
|
@ -1 +1 @@
|
|||||||
python .\LocationScript.py
|
python .\TransformScript.py
|
Reference in New Issue
Block a user