class GOD_CustomerCreateService
{
private GOD_CustomerCreateResponse buildResponse(boolean _success, str _message, str _accountNum = '', RecId _custRecId = 0, RecId _partyRecId = 0)
{
GOD_CustomerCreateResponse resp = new GOD_CustomerCreateResponse();
DirPartyTable party;
resp.parmSuccess(_success);
resp.parmMessage(_message);
resp.parmAccountNum(_accountNum);
resp.parmCustRecId(_custRecId);
resp.parmPartyRecId(_partyRecId);
if (_partyRecId)
{
party = DirPartyTable::findRec(_partyRecId);
resp.parmPartyNumber(party.PartyNumber);
}
return resp;
}
/// <summary>
/// Creates a customer with party, and optionally a postal address.
/// </summary>
/// <param name="_cust">Data contract with customer details.</param>
/// <returns>Response contract with result info.</returns>
[SysEntryPointAttribute(true)]
public GOD_CustomerCreateResponse createCustomer(GOD_CustomerCreateContract _cust)
{
GOD_CustomerCreateResponse response;
str targetCompany = _cust.parmCompany();
// Simple validation
if (!_cust.parmName())
{
return this.buildResponse(false, "Name is required.");
}
if (!_cust.parmCustGroup())
{
return this.buildResponse(false, "CustGroup is required.");
}
// Validate customer group
if (!CustGroup::exist(_cust.parmCustGroup()))
{
return this.buildResponse(false, strFmt("CustGroup %1 does not exist.", _cust.parmCustGroup()));
}
// Run in the specified company, if any
if (targetCompany)
{
changecompany(targetCompany)
{
response = this.createCustomerInCurrentCompany(_cust);
}
}
else
{
response = this.createCustomerInCurrentCompany(_cust);
}
return response;
}
private GOD_CustomerCreateResponse createCustomerInCurrentCompany(GOD_CustomerCreateContract _cust)
{
CustTable custTable;
NumberSeq numSeq;
boolean generatedAccount = false;
str accountNum = _cust.parmAccountNum();
RecId partyRecId;
GOD_CustomerCreateResponse resp;
DirParty dirParty;
DirPartyPostalAddressView dirPartyPostalAddressView;
DirPartyContactInfoView dirPartyContactInfo;
try
{
ttsbegin;
// If caller supplied AccountNum and it already exists, return success (idempotent)
if (accountNum && CustTable::exist(accountNum))
{
custTable = CustTable::find(accountNum, true);
ttscommit;
return this.buildResponse(true, "Customer already exists; no action taken.", accountNum, custTable.RecId, custTable.Party);
}
// Generate account from number sequence if not provided
if (!accountNum)
{
NumberSequenceReference nsRef = CustParameters::numRefCustAccount();
if (!nsRef)
{
throw error("Customer account number sequence reference is not configured.");
}
numSeq = NumberSeq::newGetNum(nsRef);
accountNum = numSeq.num();
generatedAccount = true;
}
// Create Party (Organization or Person)
DirPartyType partyType = _cust.parmIsPerson() ? DirPartyType::Person : DirPartyType::Organization;
//partyRecId = DirParty::createParty(partyType, _cust.parmName());
// Create the customer
custTable.clear();
custTable.initValue(); // defaults
custTable.AccountNum = accountNum;
custTable.CustGroup = _cust.parmCustGroup();
custTable.PaymTermId = CustGroup::find(custTable.CustGroup).PaymTermId;
//custTable.Party = partyRecId;
if (_cust.parmCurrency())
{
custTable.Currency = _cust.parmCurrency();
}
custTable.insert(partyType,_cust.parmName());
// Mark number sequence as used if we generated it
if (generatedAccount && numSeq)
{
numSeq.used();
}
// Optional: create postal address if provided
dirParty = DirParty::constructFromCommon(custTable);
dirPartyPostalAddressView.city = _cust.parmCity();
dirPartyPostalAddressView.Street = _cust.parmStreet();
dirPartyPostalAddressView.State = _cust.parmState();
dirPartyPostalAddressView.County = _cust.parmCountry();
dirPartyPostalAddressView.IsPrimary = NoYes::Yes;
dirParty.createOrUpdatePostalAddress(dirPartyPostalAddressView);
//
//if (_cust.parmStreet() || _cust.parmCity() || _cust.parmZipCode() || _cust.parmCountry())
//{
// this.createPrimaryPostalAddress(partyRecId,
// _cust.parmStreet(),
// _cust.parmCity(),
// _cust.parmState(),
// _cust.parmZipCode(),
// _cust.parmCountry());
//}
dirPartyContactInfo.LocationName = "Email address";
dirPartyContactInfo.Locator = "abc@gmail.com";
dirPartyContactInfo.Type = LogisticsElectronicAddressMethodType::Email;
dirPartyContactInfo.IsPrimary = NoYes::Yes;
dirParty.createOrUpdateContactInfo(dirPartyContactInfo);
// Optional: add electronic addresses (email/phone)
// NOTE: There are multiple helper APIs; uncomment and adapt as per your standard.
/*
if (_cust.parmEmail())
{
DirPartyContactInfo::addElectronicAddress(partyRecId,
LogisticsElectronicAddressMethodType::Email,
_cust.parmEmail(),
true, // isPrimary
"Primary email");
}
if (_cust.parmPhone())
{
DirPartyContactInfo::addElectronicAddress(partyRecId,
LogisticsElectronicAddressMethodType::Phone,
_cust.parmPhone(),
false, // isPrimary
"Main phone");
}
*/
ttscommit;
resp = this.buildResponse(true, "Customer created successfully.", accountNum, custTable.RecId, partyRecId);
}
catch (Exception::Error)
{
// Rollback handled automatically by the runtime on exception
resp = this.buildResponse(false, infolog.text(), accountNum);
}
catch
{
resp = this.buildResponse(false, "Unknown error creating customer.", accountNum);
}
return resp;
}
/// <summary>
/// Creates a primary postal address for the specified party.
/// </summary>
/*
private void createPrimaryPostalAddress(RecId _partyRecId, str _street, str _city, str _state, str _zip, str _country)
{
// Use logistics location framework
LogisticsLocation loc = LogisticsLocation::construct();
RecId locationRecId;
LogisticsPostalAddress postal = LogisticsPostalAddress::construct();
DirPartyLocation partyLocation = DirPartyLocation::construct();
// Create a location
locationRecId = loc.createLocation();
// Create postal address record
postal.parmLocation(locationRecId);
postal.parmIsPrimary(true);
postal.parmStreet(_street);
postal.parmCity(_city);
postal.parmState(_state);
postal.parmZipCode(_zip);
postal.parmCountryRegionId(_country);
postal.create();
// Link the location to the party
partyLocation.parmParty(_partyRecId);
partyLocation.parmLocation(locationRecId);
partyLocation.parmIsPostalAddress(true);
partyLocation.parmIsPrimary(true);
partyLocation.create();
}
*/
}

internal final class GOD_CustomerCreateTestingJob
{
/// <summary>
/// Class entry point. The system will call this method when a designated menu
/// is selected or when execution starts and this class is set as the startup class.
/// </summary>
/// <param name = "_args">The specified arguments.</param>
public static void main(Args _args)
{
GOD_CustomerCreateContract contract = new GOD_CustomerCreateContract();
GOD_CustomerCreateService customerCreateService = new GOD_CustomerCreateService();
contract.parmAccountNum('US-104');
contract.parmCompany('USMF');
contract.parmName('TestCust');
contract.parmCustGroup('90');
contract.parmStreet('KPHB');
contract.parmCity('Chennai');
contract.parmStreet('Adayar');
contract.parmCountry('India');
contract.parmState('TamilNadu');
customerCreateService.createCustomer(contract);
}
}
{
"_cust": {
"Company": "USMF",
"Name": "Contoso Retail Pvt Ltd",
"CustGroup": "10",
"Currency": "USD",
"Street": "1 Microsoft Way",
"City": "Redmond",
"State": "WA",
"ZipCode": "98052",
"Country": "US",
"IsPerson": false
}
}