İş arkadaşımın internetten bulduğu kod, kaynağını bilmiyorum ama birçok durumda işe yarıyor:
Dictionary dict;
int idx, lastIdx, totalTables;
TableId tableId;
Application application;
SysOperationProgress progress;
StackBase errorStack;
ErrorTxt errorTxt;
;
application = new Application();
dict = new Dictionary();
totalTables = dict.tableCnt();
progress = new SysOperationProgress();
progress.setTotal(totalTables);
progress.setCaption("@SYS90206");
errorStack = new StackBase(Types::String);
lastIdx = 3000;
try
{
for (idx = lastIdx+1; idx <= totalTables; idx++)
{
tableId = dict.tableCnt2Id(idx);
progress.setText(dict.tableName(tableId));
lastIdx = idx;
application.dbSynchronize(tableId, false, true, false);
progress.incCount();
}
}
catch (Exception::Error)
{
errorTxt = strFmt("'%1' (%2) tablosunda hata var!", tableId, dict.tableName(tableId));
errorStack.push(errorTxt);
retry;
}
setPrefix("@SYS86407");
errorTxt = errorStack.pop();
while (errorTxt)
{
error(errorTxt);
errorTxt = errorStack.pop();
}
Blog Listem
ax etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
ax etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
4 Ocak 2017 Çarşamba
12 Aralık 2016 Pazartesi
AX 2012 - X++ kodu ile Questionnaires çalıştırma ve Answer tablosundan answer Id alma
Questionnaires kullanımı ve çalıştırma hakkında bir çok sayfa var web'de. Bu yüzden Questionnaires nedir, nasıl kullanılır konusunda bir şey anlatmayacağım.
KMCollection - Questionnaire kayıtları tablosu. kmCollectionId anahtar alan.
KMVirtualNetworkAnswerTable - Cevaplar tablosu. kmVirtualNetworkAnswerTableId anahtar alan. evaluation alanında failed/passed veya boş olarak sonuç saklı.
KMVirtualNetworkAnswerLine - Cevap satırları tablosu.
Kod ile Questionnaire formu çalıştırma:
KMQuestionnaireRun o = new CrsKMQuestionnaireRun();
o.set(KMQuestionnaireRunMode::All,myKMCollectionId, DirPersonUser::find(curUserId()).party());
o.run();
Kod ile Answer formu çalıştırma:
KMVirtualNetworkAnswerTable answerTable;
Args args = new Args();
RecId recId = DirPersonUser::find(curUserId()).party();
select firstOnly answerTable
where answerTable.kmVirtualNetworkAnswerTableId == this.AnswerId;
args.record(answerTable);args.caller(o);
new MenuFunction(menuItemDisplayStr(KMKnowledgeCollectorUserResults), MenuItemType::Display).run(args);
Questionnaire Idlerini sakladığım kendi formumdan ve tablomdan kod ile Questionnaire formu çalıştırıp oluşan KMVirtualNetworkAnswerTable kaydının ID'sini almak için KMQuestionnaireRun_Win32 sınıfından yeni bir sınıf türettim:
class myKMQuestionnaireRun extends KMQuestionnaireRun_Win32
{
recId myRecId;
}
formu çağırdığım tablonun recId'sini saklamak için bir parm metodu ekledim:
RecId parmMyRecId(RecId _recId = myRecId)
{
myRecId =_recId;
return myRecId;
}
Daha sonra end metodunu türettim:
public void end(KMVirtualNetworkAnswerTableId _kmVirtualNetworkAnswerTableId)
{
myCallerTable tbl; //Questionnaries formunu çağıran tablo
super(_kmVirtualNetworkAnswerTableId);
if (_kmVirtualNetworkAnswerTableId == "")
return;
ttsBegin;
update_recordSet tbl setting AnswerId = _kmVirtualNetworkAnswerTableId
where tbl.RecId == myRecId;
ttsCommit;
}
Ve kendi tablomdan formu bu kodla çağırdım:
...
myKMQuestionnaireRun o = new myKMQuestionnaireRun();
myQTable c;
o.parmMyRecId(this.RecId);
o.set(KMQuestionnaireRunMode::All,this.KMCollectionId, DirPersonUser::find(curUserId()).party());
o.run();
...
KMCollection - Questionnaire kayıtları tablosu. kmCollectionId anahtar alan.
KMVirtualNetworkAnswerTable - Cevaplar tablosu. kmVirtualNetworkAnswerTableId anahtar alan. evaluation alanında failed/passed veya boş olarak sonuç saklı.
KMVirtualNetworkAnswerLine - Cevap satırları tablosu.
Kod ile Questionnaire formu çalıştırma:
KMQuestionnaireRun o = new CrsKMQuestionnaireRun();
o.set(KMQuestionnaireRunMode::All,myKMCollectionId, DirPersonUser::find(curUserId()).party());
o.run();
Kod ile Answer formu çalıştırma:
KMVirtualNetworkAnswerTable answerTable;
Args args = new Args();
RecId recId = DirPersonUser::find(curUserId()).party();
select firstOnly answerTable
where answerTable.kmVirtualNetworkAnswerTableId == this.AnswerId;
args.record(answerTable);args.caller(o);
new MenuFunction(menuItemDisplayStr(KMKnowledgeCollectorUserResults), MenuItemType::Display).run(args);
Questionnaire Idlerini sakladığım kendi formumdan ve tablomdan kod ile Questionnaire formu çalıştırıp oluşan KMVirtualNetworkAnswerTable kaydının ID'sini almak için KMQuestionnaireRun_Win32 sınıfından yeni bir sınıf türettim:
class myKMQuestionnaireRun extends KMQuestionnaireRun_Win32
{
recId myRecId;
}
formu çağırdığım tablonun recId'sini saklamak için bir parm metodu ekledim:
RecId parmMyRecId(RecId _recId = myRecId)
{
myRecId =_recId;
return myRecId;
}
Daha sonra end metodunu türettim:
public void end(KMVirtualNetworkAnswerTableId _kmVirtualNetworkAnswerTableId)
{
myCallerTable tbl; //Questionnaries formunu çağıran tablo
super(_kmVirtualNetworkAnswerTableId);
if (_kmVirtualNetworkAnswerTableId == "")
return;
ttsBegin;
update_recordSet tbl setting AnswerId = _kmVirtualNetworkAnswerTableId
where tbl.RecId == myRecId;
ttsCommit;
}
Ve kendi tablomdan formu bu kodla çağırdım:
...
myKMQuestionnaireRun o = new myKMQuestionnaireRun();
myQTable c;
o.parmMyRecId(this.RecId);
o.set(KMQuestionnaireRunMode::All,this.KMCollectionId, DirPersonUser::find(curUserId()).party());
o.run();
...
8 Haziran 2016 Çarşamba
AXAPTA - Bir malzeme çekme listesi veya satırını iptal
Tüm listenin iptali:
Bir satırın iptali:
WMSPickingRouteCancel::newWMSPickingRoute(wMSPickingRoute).run();
Bir satırın iptali:
WMSPickingLineCancel::newWMSPickingLineCancel(wMSOrderTrans).run();
6 Mayıs 2016 Cuma
AXAPTA - Sign fonksiyonu düzgün çalışmıyor
AX 2009 ve 2012'deki sign fonksiyonu düzgün çalışmıyor. Negatif değerler için -1, sıfır için 0 ve pozitif değerler için +1 döndürmesi gerekirken negatif değerler için -1 ve diğer tüm değerler için +1 döndürüyor.
Global'deki Sign:
static real sign(real num)
{
return num >= 0 ? 1 : -1;
}
Benim yaptığım düzeltme:
static int sign(real num)
{
if (num < 0)
return -1;
else
return num > 0 ? 1 : 0;
}
Global'deki Sign:
static real sign(real num)
{
return num >= 0 ? 1 : -1;
}
Benim yaptığım düzeltme:
static int sign(real num)
{
if (num < 0)
return -1;
else
return num > 0 ? 1 : 0;
}
5 Mayıs 2016 Perşembe
AXAPTA - Malzeme çekme listesi oluşturmak
Bir forum sayfasından bulduğum çözümü kendim için class haline getirdim:
class KRC_WMSOrder
{
WMSShipment wmsShipment;
SalesTable salesTable;
WMSPickingRoute wmsPickingRoute;
WMSPickingRouteLink wmsPickingRouteLink;
salesLine salesLine;
}
void createOrderLine(Qty _qty = salesLine.RemainSalesPhysical)
{
InventMovement inventMovement;
WMSOrder wmsOrder;
WMSOrderCreate orderCreate;
WMSOrderTrans wmsOrderTrans;
;
inventMovement = InventMovement::construct(salesLine);
orderCreate = WMSOrderCreate::newMovement(inventMovement,_qty);
orderCreate.parmMustBeWMSOrderControlled(true);
orderCreate.parmQty(_qty);
orderCreate.parmMaxQty(_qty);
orderCreate.run();
wmsOrder = orderCreate.parmWMSOrder();
wmsOrder.updateShipment(wmsShipment,_qty, wmsPickingRoute.PickingRouteID);
}
void createWmsPickingRoute()
{
;
wmsPickingRoute.clear();
wmsPickingRoute.initTypeOrderPick(wmsShipment, WMSExpeditionStatus::Activated,
WMSPickRequestTable::construct(salesTable),"", true);
wmsPickingRoute.ActivationDateTime = DateTimeUtil::utcNow();
wmsPickingRoute.insert();
}
void createWmsPickingRouteLink()
{
;
wmsPickingRouteLink.clear();
wmsPickingRouteLink.initFromSalesTable(salesTable);
wmsPickingRouteLink.initFromWMSPickingRoute(wmsPickingRoute);
wmsPickingRouteLink.insert();
}
void createWmsShipment()
{
;
wmsShipment.clear();
wmsShipment.initTypeOrderPick();
wmsShipment.insert();
}
SalesLine parmSalesLine(SalesLine _salesLine = salesLine)
{
;
salesLine = _salesLine;
return salesLine;
}
SalesTable parmSalesTable(SalesTable _salesTable = salesTable)
{
;
salesTable = _salesTable;
return salesTable;
}
void reserveItem(Qty _qty = salesLine.RemainSalesPhysical)
{
InventUpd_Reservation invUpdReservation;
;
invUpdReservation = InventUpd_Reservation::newInventDim(InventMovement::construct(salesLine,InventMovSubType::None),
salesLine.inventDim(),_qty,false);
invUpdReservation.updateNow();
}
Örnek kullanım:
KRC_WMSOrder kWMS = new krc_wmsorder();
kWMS.createWmsShipment();
;
ttsbegin;
kWMS.parmSalesTable(salesTable);
kWMS.createWmsPickingRoute();
kWMS.createWmsPickingRouteLink();
kWMS.parmSalesLine(salesLine);
kWMS.reserveItem();
kWMS.createOrderLine();
ttscommit;
class KRC_WMSOrder
{
WMSShipment wmsShipment;
SalesTable salesTable;
WMSPickingRoute wmsPickingRoute;
WMSPickingRouteLink wmsPickingRouteLink;
salesLine salesLine;
}
void createOrderLine(Qty _qty = salesLine.RemainSalesPhysical)
{
InventMovement inventMovement;
WMSOrder wmsOrder;
WMSOrderCreate orderCreate;
WMSOrderTrans wmsOrderTrans;
;
inventMovement = InventMovement::construct(salesLine);
orderCreate = WMSOrderCreate::newMovement(inventMovement,_qty);
orderCreate.parmMustBeWMSOrderControlled(true);
orderCreate.parmQty(_qty);
orderCreate.parmMaxQty(_qty);
orderCreate.run();
wmsOrder = orderCreate.parmWMSOrder();
wmsOrder.updateShipment(wmsShipment,_qty, wmsPickingRoute.PickingRouteID);
}
void createWmsPickingRoute()
{
;
wmsPickingRoute.clear();
wmsPickingRoute.initTypeOrderPick(wmsShipment, WMSExpeditionStatus::Activated,
WMSPickRequestTable::construct(salesTable),"", true);
wmsPickingRoute.ActivationDateTime = DateTimeUtil::utcNow();
wmsPickingRoute.insert();
}
void createWmsPickingRouteLink()
{
;
wmsPickingRouteLink.clear();
wmsPickingRouteLink.initFromSalesTable(salesTable);
wmsPickingRouteLink.initFromWMSPickingRoute(wmsPickingRoute);
wmsPickingRouteLink.insert();
}
void createWmsShipment()
{
;
wmsShipment.clear();
wmsShipment.initTypeOrderPick();
wmsShipment.insert();
}
SalesLine parmSalesLine(SalesLine _salesLine = salesLine)
{
;
salesLine = _salesLine;
return salesLine;
}
SalesTable parmSalesTable(SalesTable _salesTable = salesTable)
{
;
salesTable = _salesTable;
return salesTable;
}
void reserveItem(Qty _qty = salesLine.RemainSalesPhysical)
{
InventUpd_Reservation invUpdReservation;
;
invUpdReservation = InventUpd_Reservation::newInventDim(InventMovement::construct(salesLine,InventMovSubType::None),
salesLine.inventDim(),_qty,false);
invUpdReservation.updateNow();
}
Örnek kullanım:
KRC_WMSOrder kWMS = new krc_wmsorder();
kWMS.createWmsShipment();
;
ttsbegin;
kWMS.parmSalesTable(salesTable);
kWMS.createWmsPickingRoute();
kWMS.createWmsPickingRouteLink();
kWMS.parmSalesLine(salesLine);
kWMS.reserveItem();
kWMS.createOrderLine();
ttscommit;
AXAPTA - Formun args parametresi ile gelen kayda göre otomatik filtre yapmasını engellemek
Bu sorunun cevabını bir forum sayfasından buldum:
KRC_PlanWaves_DS.query().dataSourceNo(1).clearDynalinks();
KRC_PlanWaves_DS.query().dataSourceNo(1).clearDynalinks();
24 Mart 2016 Perşembe
AXAPTA - Sysmailer ile mail gönderirken türkçe harf sorunu
SysMailer class ile mail gönderirken aşağıdaki kırmızı satırı eklemediğinizde türkçe harfler mailde çıkmayacaktır. Bu çözümü bir blog'dan bulmuştum ancak yerini şu an hatırlayamıyorum:
SysEmailParameters parameters;
SysMailer mailer;
;
new InteropPermission(InteropKind::ComInterop).assert();
parameters = SysEmailParameters::find();
mailer = new SysMailer();
if (parameters.SMTPRelayServerName)
{
mailer.SMTPRelayServer(parameters.SMTPRelayServerName,
parameters.SMTPPortNumber,
parameters.SMTPUserName,
SysEmailParameters::password(),
parameters.NTLM);
}
else
{
mailer.SMTPRelayServer(parameters.SMTPServerIPAddress,
parameters.SMTPPortNumber,
parameters.SMTPUserName,
SysEmailParameters::password(),
parameters.NTLM);
}
mailer.fromAddress(fromAddr);
mailer.tos().appendAddress(toAddr);
mailer.subject(subject);
//türkçe harflerin düzgün gitmesi için:
mailer.bodyCharSet("Windows-1254"); if(FileName)
mailer.attachments().add(FileName);
mailer.ccs().appendAddress(ccAddr);
mailer.bccs().appendAddress(bccAddr);
mailer.htmlBody(body);
mailer.sendMail();
}
CodeAccessPermission::revertAssert();
SysEmailParameters parameters;
SysMailer mailer;
;
new InteropPermission(InteropKind::ComInterop).assert();
parameters = SysEmailParameters::find();
mailer = new SysMailer();
if (parameters.SMTPRelayServerName)
{
mailer.SMTPRelayServer(parameters.SMTPRelayServerName,
parameters.SMTPPortNumber,
parameters.SMTPUserName,
SysEmailParameters::password(),
parameters.NTLM);
}
else
{
mailer.SMTPRelayServer(parameters.SMTPServerIPAddress,
parameters.SMTPPortNumber,
parameters.SMTPUserName,
SysEmailParameters::password(),
parameters.NTLM);
}
mailer.fromAddress(fromAddr);
mailer.tos().appendAddress(toAddr);
mailer.subject(subject);
//türkçe harflerin düzgün gitmesi için:
mailer.bodyCharSet("Windows-1254"); if(FileName)
mailer.attachments().add(FileName);
mailer.ccs().appendAddress(ccAddr);
mailer.bccs().appendAddress(bccAddr);
mailer.htmlBody(body);
mailer.sendMail();
}
CodeAccessPermission::revertAssert();
Etiketler:
1254,
ax,
AXAPTA,
bodycharset,
char set,
mail,
sysmailer,
türkçe harf
2 Mart 2016 Çarşamba
AXAPTA - Bir tablo alanının label değerini bulmak
Bir tablonun bir alanının label değerini bulmanın iki yolu var:
Eğer field label değerini direk extended data tipinden alıyorsa:
if (curext()=="krc" && this.RBOInventItemGroupId == "")
ret = checkfailed(strfmt("'%1' alanı doldurulmalıdır!..",
new SysDictType(extendedTypeNum(RBORetailGroupId)).label()));
Eğer tabloda alana bir etiket yazıldıysa:
if (curext()=="krc" && this.RBOInventItemGroupId == "")
ret = checkfailed(strfmt("'%1' alanı doldurulmalıdır!..",
new SysDictField(tablenum(WholeSalesCampaignGroup),
fieldnum(WholeSalesCampaignGroup,RBOInventItemGroupId)).label()));
Eğer field label değerini direk extended data tipinden alıyorsa:
if (curext()=="krc" && this.RBOInventItemGroupId == "")
ret = checkfailed(strfmt("'%1' alanı doldurulmalıdır!..",
new SysDictType(extendedTypeNum(RBORetailGroupId)).label()));
Eğer tabloda alana bir etiket yazıldıysa:
if (curext()=="krc" && this.RBOInventItemGroupId == "")
ret = checkfailed(strfmt("'%1' alanı doldurulmalıdır!..",
new SysDictField(tablenum(WholeSalesCampaignGroup),
fieldnum(WholeSalesCampaignGroup,RBOInventItemGroupId)).label()));
5 Şubat 2016 Cuma
AXAPTA - Kullanıcının grid başlığından filtreyi değiştirmesini engelleme
SysQuery::findOrCreateRange(InventDim_DS.query().dataSourceTable(tablenum(InventDim)),fieldnum(InventDim,InventSiteId)).status(RangeStatus::Locked);
26 Ocak 2016 Salı
AX 2009 - Raporu PDF çıktı olarak arka planda çalıştırmak
Raporun Interactive property değerini No yapıyoruz. PrintMedium enum değerini değiştirerek html çıktı olarak çalışması da sağlanabilir.
DocuType docuType;
TextIo textIo;
FileIOPermission fioPermission;
#File
ReportRun report;
;
docuType = DocuType::find("Temp");
fileName = strfmt(@"%1My Test Report.PDF", docuType.ArchivePath);
fioPermission = new FileIOPermission(fileName ,"RW");
fioPermission.assert();
if(Global::isRunningOnServer())
{
if(WinAPIServer::fileExists(fileName))
WINAPIServer::deleteFile(fileName);
}
else
{
if(WinAPI::fileExists(fileName))
WINAPI::deleteFile(fileName);
}
report = new ReportRun(new Args(ReportStr(KRC_InventCoverReport)));
report.printJobSettings().setTarget(PrintMedium::File);
report.printJobSettings().preferredTarget(PrintMedium::File);
report.printJobSettings().format(PrintFormat::PDF);
report.printJobSettings().fileName(fileName);
report.query().interactive(false);
report.run();
DocuType docuType;
TextIo textIo;
FileIOPermission fioPermission;
#File
ReportRun report;
;
docuType = DocuType::find("Temp");
fileName = strfmt(@"%1My Test Report.PDF", docuType.ArchivePath);
fioPermission = new FileIOPermission(fileName ,"RW");
fioPermission.assert();
if(Global::isRunningOnServer())
{
if(WinAPIServer::fileExists(fileName))
WINAPIServer::deleteFile(fileName);
}
else
{
if(WinAPI::fileExists(fileName))
WINAPI::deleteFile(fileName);
}
report = new ReportRun(new Args(ReportStr(KRC_InventCoverReport)));
report.printJobSettings().setTarget(PrintMedium::File);
report.printJobSettings().preferredTarget(PrintMedium::File);
report.printJobSettings().format(PrintFormat::PDF);
report.printJobSettings().fileName(fileName);
report.query().interactive(false);
report.run();
22 Ocak 2016 Cuma
Axapta - Neden bazen MultiSelectionHelper bazen klasik okuma yöntemi?
Bir formda gridde seçili kayıtları okumak için klasik yöntem aşağıdaki gibidir:
c = CustTable_DS.getFirst(true);
while (c.RecId != 0)
{
info(c.Name);
c = CustTable_DS.getNext();
}
Ancak bu yöntemin bir sakıncası vardır. Bu yöntemle kayıt okuduğunuz zaman eğer ki kullanıcı listeden birkaç kayıt işaretlemeyip sadece üzerinde durduğu kaydı işlemek isterse o kayıt malesef atlanır. Bunu bertaraf etmek için aşağıdaki eklemeyi yapmak gerekir:
c = CustTable_DS.getFirst(true);
noSelected = true;
while (c.RecId != 0)
{
noSelected = false;
info(c.Name);
c = CustTable_DS.getNext();
}
if (noSelected)
info(CustTable.Name);
MultiSelectionHelper sınıfı bu sıkıntıyı bertaraf eder:
MultiSelectionHelper helper = MultiSelectionHelper::construct();
CustTable c;
;
helper.parmDatasource(CustTable_ds);
c = helper.getFirst();
while (c.RecId != 0)
{
info(c.Name);
c = helper.getNext();
}
Ancak MultiSelectionHelper sınıfının da bir dezavantajı vardır. Eğer ki kullanıcı gridde kayıtları sıralamak isterse ve o sıraya göre liste almak isterse yine yukarıdaki klasik yöntemi kullanmak gerekir zira MultiSelectionHelper sınıfı kullanıcının yaptığı sıralamayı malesef dikkate almaz.
MultiselectionHelper sınıfının bir sınıf içinde kullanılması:
public static void main(Args _args)
{
SMAServiceOrderTable serviceOrder;
MultiSelectionHelper helper;
FormRun caller = _args.caller();
FormDataSource SMAServiceOrderTable_DS;
SMAServiceOrderTable_DS = caller.dataSource();
helper = MultiSelectionHelper::createFromCaller(caller);
helper.createQueryRanges(SMAServiceOrderTable_DS.queryBuildDataSource(),fieldStr(SMAServiceOrderTable,RecId));
serviceOrder = helper.getFirst();
while(serviceOrder)
{
info(strFmt("%1",serviceOrder.RecId));
serviceOrder = helper.getNext();
}
}
c = CustTable_DS.getFirst(true);
while (c.RecId != 0)
{
info(c.Name);
c = CustTable_DS.getNext();
}
Ancak bu yöntemin bir sakıncası vardır. Bu yöntemle kayıt okuduğunuz zaman eğer ki kullanıcı listeden birkaç kayıt işaretlemeyip sadece üzerinde durduğu kaydı işlemek isterse o kayıt malesef atlanır. Bunu bertaraf etmek için aşağıdaki eklemeyi yapmak gerekir:
c = CustTable_DS.getFirst(true);
noSelected = true;
while (c.RecId != 0)
{
noSelected = false;
info(c.Name);
c = CustTable_DS.getNext();
}
if (noSelected)
info(CustTable.Name);
MultiSelectionHelper sınıfı bu sıkıntıyı bertaraf eder:
MultiSelectionHelper helper = MultiSelectionHelper::construct();
CustTable c;
;
helper.parmDatasource(CustTable_ds);
c = helper.getFirst();
while (c.RecId != 0)
{
info(c.Name);
c = helper.getNext();
}
Ancak MultiSelectionHelper sınıfının da bir dezavantajı vardır. Eğer ki kullanıcı gridde kayıtları sıralamak isterse ve o sıraya göre liste almak isterse yine yukarıdaki klasik yöntemi kullanmak gerekir zira MultiSelectionHelper sınıfı kullanıcının yaptığı sıralamayı malesef dikkate almaz.
MultiselectionHelper sınıfının bir sınıf içinde kullanılması:
public static void main(Args _args)
{
SMAServiceOrderTable serviceOrder;
MultiSelectionHelper helper;
FormRun caller = _args.caller();
FormDataSource SMAServiceOrderTable_DS;
SMAServiceOrderTable_DS = caller.dataSource();
helper = MultiSelectionHelper::createFromCaller(caller);
helper.createQueryRanges(SMAServiceOrderTable_DS.queryBuildDataSource(),fieldStr(SMAServiceOrderTable,RecId));
serviceOrder = helper.getFirst();
while(serviceOrder)
{
info(strFmt("%1",serviceOrder.RecId));
serviceOrder = helper.getNext();
}
}
Etiketler:
ax,
ax 2012,
AXAPTA,
getfirst,
getnext,
grid,
işaretli,
kayıt,
multi,
multiselect,
multiselectionhelper,
oku,
okuma,
seç,
seçim,
select,
sıralama
19 Ocak 2016 Salı
Axapta - Query'ye boyut (dimension) bazında filtre eklemek
StrFmt ile boyut bazında filtre eklemek istediğimizde dimension alanın köşeli parantezleri dimension[2] = "0001" tarzı filtre eklemek istediğimizde hata veriyor. Doğru yöntemi bir forum sayfasında buldum:
QueryBuildDataSource qbds = query.addDataSource(tablenum(EmplTable));
...
qbds.addRange(fieldid2Ext(fieldnum(EmplTable, Dimension),1)).value("600742");
QueryBuildDataSource qbds = query.addDataSource(tablenum(EmplTable));
...
qbds.addRange(fieldid2Ext(fieldnum(EmplTable, Dimension),1)).value("600742");
23 Aralık 2015 Çarşamba
Axapta - XPO export dialog formunda dosya adının tarih - saat ile gelmesi
Bu sayede XPO'larımız versiyon kontrollü olmuş oluyor. Yedekleme açısından çok faydalı olan aşağıdaki kodu Eren Polat'dan aldım.
SysExportDialog formunun metodlarına aşağıdaki kodları ekleyin:
classDeclaration:
str sDate, sTime, sDateTime;
str sMilliSeconds;
init:
sMilliSeconds = int2str(winApi::getTickCount());
sDate = int2str(year(today())) + strReplace(num2str(mthofyr(today()),2,0,0,0), ' ', '0') + strReplace(num2str(dayofmth(today()),2,0,0,0), ' ', '0');
sTime = strfmt("%1:%2", time2str(timeNow(),1,1), substr(sMilliSeconds, strlen(sMilliSeconds)-2,2));
sTime = strReplace(sTime,":","");
sDateTime = strfmt("_%1%2",sDate,sTime);
run:
//element.updateBox(fileNameNext(strfmt('%1%2_%3%4', filePath, preFix, treeNode.treeNodeName(), #xpo)));
element.updateBox(fileNameNext(strfmt('%1%2_%3%4%5', filePath, preFix, treeNode.treeNodeName(), sDateTime, #xpo)));
SysExportDialog formunun metodlarına aşağıdaki kodları ekleyin:
classDeclaration:
str sDate, sTime, sDateTime;
str sMilliSeconds;
init:
sMilliSeconds = int2str(winApi::getTickCount());
sDate = int2str(year(today())) + strReplace(num2str(mthofyr(today()),2,0,0,0), ' ', '0') + strReplace(num2str(dayofmth(today()),2,0,0,0), ' ', '0');
sTime = strfmt("%1:%2", time2str(timeNow(),1,1), substr(sMilliSeconds, strlen(sMilliSeconds)-2,2));
sTime = strReplace(sTime,":","");
sDateTime = strfmt("_%1%2",sDate,sTime);
run:
//element.updateBox(fileNameNext(strfmt('%1%2_%3%4', filePath, preFix, treeNode.treeNodeName(), #xpo)));
element.updateBox(fileNameNext(strfmt('%1%2_%3%4%5', filePath, preFix, treeNode.treeNodeName(), sDateTime, #xpo)));
22 Aralık 2015 Salı
AX 2012 - Yeni WMS el terminali geliştirme
Microsoft kendi geliştirdiği WMS-II çözümünü bırakıp başka bir firmadan satın aldığı WMS çözümünü AX içine koydu. Bu yeni WMS çözümünün web ortamında çalışan kendine ait bir el terminali çözümü de var. El terminali çözümü tamamen web ortamında çalışırken geliştirme yaparken AX içinden çalıştırılması da sağlanmış. WHSWorkExecute isimli menu item ile AX tarafında bu çözümü çalıştırabiliriz. Microsoft WMS ve TM için ayrıntılı birer klavuz yayınlamış. WMS klavuzunda el terminali için kullanıcı tanımlama ve ayarlarını yapma anlatılmış. Ben bunları geçerek direk konuya giriyorum.
Klavuzda geliştirme hakkında bir bilgi yok. Ben bu konuda bulduğum bir blogdan faydalandım. Kendim uğraşsam bulamayacağımı sandığım püf noktalarını da hiçbir çaba sarfetmeden bu blogdan öğrenmiş oldum. :)
El terminali geliştirme yöntemini anlatırken WMS dökümanında anlatılan konuları bildiğinizi farzedeceğim.
El terminali geliştirmesi tamamen X++ classlar üzerinden çalışıyor. Yaptığınız her yeni menu item için bir class oluyor. Tüm menu item classları WMSWorkExecuteDisplay ile başlıyor.
Kendi menu itemimizi geliştirdiğimizi farzedelim. Eğer kendi menu itemimizi geliştirmeyeceksek bu adımı atlayabiliriz:
Yeni bir work ve/veya indirect menu item ekleyeceğiniz zaman WHSWorkCreationProcess enumuna bunu yeni bir eleman olarak eklemelisiniz. Eğer eklediğiniz menu item bir work ise ayrıca WHSWorkExecuteMode enum içine de eklemeniz gerekiyor. Okuduğum blogda yazdığına göre WHSWorkExecuteMode içine eklediğiniz elemanın adı ve label içeriği WHSWorkCreationProcess içine eklediğiniz ile birebir aynı olmalıymış, ben bunu hiç test etmedim, aynen söylenene uydum. Bizim elemanın adı Test olsun.
Bizim sınıfın adının WMSWorkExecuteDisplayTest olduğunu farzedelim. Sınıfımız WHSWorkExecuteDisplay sınıfından türeyecek.
Yukarıda anlattığımız enumlara eklenen eleman sayesinde kullanıcıya menu item tanımlama ekranında (Mobile device menu items ->Genel->Work creation process) yeni bir menu item daha görülebilecek. Ancak onun çağrılabilmesini sağlamak için yapılması gereken birşey daha var; WHSWorkExecuteDisplay sınıfının construct metodundaki switch/case bloğuna aşağıdaki kod parçasını eklemek:
case WHSWorkExecuteMode::MyTest : return WHSWorkExecuteDisplayTest::construct();
El terminali geliştirmesindeki tüm menu itemler kendi sınıfları içindeki displayForm metodu vasıtasıyla çalışıyor. Ben mevcut sınıflardan birini alıp kopyaladım ve onun üzerinde yaptığım değişikliklerle işimi gördüm. displayForm metodu aşamalar şeklinde çalışıyor. Bunu step isimli değişkenle takip ediyor. birinci aşama sıfır. Benim kopyaladığım sınıfta son aşama 2 olan kayıt aşamasıydı. Aşamaları orijinal sınıflarda da yapıldığı gibi displayForm metodunda bir switch/case ile takip edebilirsiniz.
Web formumuza yeni bir kontrol eklemek için buildControl metodunu kullanıyoruz:
ret += [this.buildControl(#RFText, #vendor, "@SYS14048", 1, pass.lookup(#vendor), extendedTypeNum(VendAccount), '', 0,false)];
Yukarıdaki kontroldeki #vendor makrosu WHSRF makrosunda yoksa bizim bunu ayrıca eklememiz gerekiyor. Yine blogdan öğrendiğim üzere bu metodun parametreleri şöyle (ordan copy/paste yapıp türkçeye çevirdim sadece):
Kontrolde kullandığımız datanın map edilip edilmediğini öğrenmek için exists, edilmişse de değerini öğrenmek için lookup metodlarını kullanıyoruz. Genelde aşağıdaki şekilde kullanılıyor:
if (pass.exists(#vendor) && pass.lookup(#vendor) != '")
Data değerini eklemek/değiştirmek için insert metodunu kullanıyoruz:
pass.insert(#vendor,purchTable.OrderAccount);
Bu arada Mobile device menu items formunda diğer menu itemlerinde gözüken ancak sizinkinde gözükmeyen seçenekleri görmek istiyorsanız bunun için (daire içinde işaretlediklerim)
WHSRFMenuItem formunun togglefields metodunda ufak bir değişiklik gerekiyor:
if (whsrfMenuItemTable.WorkCreationProcess == WHSWorkCreationProcess::PurchaseOrderItemReceiving ||
whsrfMenuItemTable.WorkCreationProcess ==
...
...
//memre 22.12.2015
whsrfMenuItemTable.WorkCreationProcess == WHSWorkCreationProcess::PurchaseOrderLineReceivingWithVendor)
//memre
...
...
Aynı zamanda WHSRFControlData sınıfının processControl metodunda ekstra güncellemeler yapmanız gerekebilir. Benim yaptığım bir geliştirmede orijinalinden kopyaladığım sınıfta orijinalinde LP (License Plate) oluşurken benimkinde oluşmuyordu. Sebebiyse enum ile yapılan LP kontrolüydü. Benim için aşağıdaki güncelleme iş gördü:
case #LicensePlateId:
...
...
else if (mode != WHSWorkExecuteMode::AdjustmentIn &&
mode != WHSWorkExecuteMode::ReportAsFinished &&
...
...
...
//memre 22.12.2015
mode != WHSWorkExecuteMode::PurchaseOrderLineReceivingWithVendor &&
//memre
mode != WHSWorkExecuteMode::PurchaseOrderItemReceivingAndLocate &&
...
...
Bildiğim kadarıyla tüm temel noktalar bunlar. Daha fazla ayrıntı için benim de faydalandığım blog ve WMS dökümanından faydalanabilirsiniz.
Klavuzda geliştirme hakkında bir bilgi yok. Ben bu konuda bulduğum bir blogdan faydalandım. Kendim uğraşsam bulamayacağımı sandığım püf noktalarını da hiçbir çaba sarfetmeden bu blogdan öğrenmiş oldum. :)
El terminali geliştirme yöntemini anlatırken WMS dökümanında anlatılan konuları bildiğinizi farzedeceğim.
El terminali geliştirmesi tamamen X++ classlar üzerinden çalışıyor. Yaptığınız her yeni menu item için bir class oluyor. Tüm menu item classları WMSWorkExecuteDisplay ile başlıyor.
Kendi menu itemimizi geliştirdiğimizi farzedelim. Eğer kendi menu itemimizi geliştirmeyeceksek bu adımı atlayabiliriz:
Yeni bir work ve/veya indirect menu item ekleyeceğiniz zaman WHSWorkCreationProcess enumuna bunu yeni bir eleman olarak eklemelisiniz. Eğer eklediğiniz menu item bir work ise ayrıca WHSWorkExecuteMode enum içine de eklemeniz gerekiyor. Okuduğum blogda yazdığına göre WHSWorkExecuteMode içine eklediğiniz elemanın adı ve label içeriği WHSWorkCreationProcess içine eklediğiniz ile birebir aynı olmalıymış, ben bunu hiç test etmedim, aynen söylenene uydum. Bizim elemanın adı Test olsun.
Bizim sınıfın adının WMSWorkExecuteDisplayTest olduğunu farzedelim. Sınıfımız WHSWorkExecuteDisplay sınıfından türeyecek.
Yukarıda anlattığımız enumlara eklenen eleman sayesinde kullanıcıya menu item tanımlama ekranında (Mobile device menu items ->Genel->Work creation process) yeni bir menu item daha görülebilecek. Ancak onun çağrılabilmesini sağlamak için yapılması gereken birşey daha var; WHSWorkExecuteDisplay sınıfının construct metodundaki switch/case bloğuna aşağıdaki kod parçasını eklemek:
case WHSWorkExecuteMode::MyTest : return WHSWorkExecuteDisplayTest::construct();
El terminali geliştirmesindeki tüm menu itemler kendi sınıfları içindeki displayForm metodu vasıtasıyla çalışıyor. Ben mevcut sınıflardan birini alıp kopyaladım ve onun üzerinde yaptığım değişikliklerle işimi gördüm. displayForm metodu aşamalar şeklinde çalışıyor. Bunu step isimli değişkenle takip ediyor. birinci aşama sıfır. Benim kopyaladığım sınıfta son aşama 2 olan kayıt aşamasıydı. Aşamaları orijinal sınıflarda da yapıldığı gibi displayForm metodunda bir switch/case ile takip edebilirsiniz.
Web formumuza yeni bir kontrol eklemek için buildControl metodunu kullanıyoruz:
ret += [this.buildControl(#RFText, #vendor, "@SYS14048", 1, pass.lookup(#vendor), extendedTypeNum(VendAccount), '', 0,false)];
Yukarıdaki kontroldeki #vendor makrosu WHSRF makrosunda yoksa bizim bunu ayrıca eklememiz gerekiyor. Yine blogdan öğrendiğim üzere bu metodun parametreleri şöyle (ordan copy/paste yapıp türkçeye çevirdim sadece):
| Paremetre | Data tipi | Açıklama |
| _controlType | str | Kontrolün türü. Bu türler WHSRF makrosunda eklenen türlerden biri olmak zorunda: #define.RFButton('button') #define.RFLabel('label') #define.RFText('text') #define.RFPassword('password') #define.RFListbox('listbox') #define.RFCombobox('combobox') #define.RFError('error') |
| _name | str | Kontrolün ismi. Kontrolde saklanan dataya ulaşmak için bu ismi kullanacağız. |
| _label | str | UI'de gözükecek text içeriği. |
| _newLine | int | 1 ise kontrol yeni bir satırda olacak, 0 ise aynı satırda. |
| _data | str | Kontrolde gösterilecek data. |
| _inputType | ExtendedTypeId | Kontrolün data türü. Doğrulama için bu önemli. Doğrulama gerekmiyorsa #WHSRFUndefinedDataType makrosu kullanılabilir. |
| _error | str | Doğrulama gerçekleşmediğinde çıkacak mesaj. |
| _defaultButton | int | 1 ise buton kontrolü varsayılan kontrol demektir, Genellikle "Tamam" butonu için kullanılır. |
| _enabled | boolean | true olduğunda kontrol enabled olur, false olduğunda disabled, default enabled. |
| _selected | int | 1 olduğunda aktif kontrol olur. |
| _color | WHSRFColorText | Kontrolün rengi. WHSRFColorText enumda tanımlı birkaç renk var. |
Kontrolde kullandığımız datanın map edilip edilmediğini öğrenmek için exists, edilmişse de değerini öğrenmek için lookup metodlarını kullanıyoruz. Genelde aşağıdaki şekilde kullanılıyor:
if (pass.exists(#vendor) && pass.lookup(#vendor) != '")
Data değerini eklemek/değiştirmek için insert metodunu kullanıyoruz:
pass.insert(#vendor,purchTable.OrderAccount);
Bu arada Mobile device menu items formunda diğer menu itemlerinde gözüken ancak sizinkinde gözükmeyen seçenekleri görmek istiyorsanız bunun için (daire içinde işaretlediklerim)
WHSRFMenuItem formunun togglefields metodunda ufak bir değişiklik gerekiyor:
if (whsrfMenuItemTable.WorkCreationProcess == WHSWorkCreationProcess::PurchaseOrderItemReceiving ||
whsrfMenuItemTable.WorkCreationProcess ==
...
...
//memre 22.12.2015
whsrfMenuItemTable.WorkCreationProcess == WHSWorkCreationProcess::PurchaseOrderLineReceivingWithVendor)
//memre
...
...
Aynı zamanda WHSRFControlData sınıfının processControl metodunda ekstra güncellemeler yapmanız gerekebilir. Benim yaptığım bir geliştirmede orijinalinden kopyaladığım sınıfta orijinalinde LP (License Plate) oluşurken benimkinde oluşmuyordu. Sebebiyse enum ile yapılan LP kontrolüydü. Benim için aşağıdaki güncelleme iş gördü:
case #LicensePlateId:
...
...
else if (mode != WHSWorkExecuteMode::AdjustmentIn &&
mode != WHSWorkExecuteMode::ReportAsFinished &&
...
...
...
//memre 22.12.2015
mode != WHSWorkExecuteMode::PurchaseOrderLineReceivingWithVendor &&
//memre
mode != WHSWorkExecuteMode::PurchaseOrderItemReceivingAndLocate &&
...
...
Bildiğim kadarıyla tüm temel noktalar bunlar. Daha fazla ayrıntı için benim de faydalandığım blog ve WMS dökümanından faydalanabilirsiniz.
Etiketler:
2012,
ax,
AXAPTA,
development,
el,
el terminali,
geliştirme,
new,
terminal,
wms,
yeni
1 Aralık 2015 Salı
AX 2012 - Try - catch
Try/catch hakkında güzel bir uyarı yazısı var. Aşağıdaki kod oradan alıntı:
void post(int amount)
{
#OCCRetryCount
MyPostings debit;
MyPostings credit;
System.Exception ex;
try
{
ttsBegin;
debit = MyPostings::find('debit', true);
debit.Amount += amount;
debit.update();
credit = MyPostings::find('credit', true);
credit.Amount -= amount;
credit.update();
ttsCommit;
}
catch (Exception::UpdateConflict)
{
if (appl.ttsLevel() != 0)
{
throw Exception::UpdateConflict;
}
if (xSession::currentRetryCount() >= #RetryNum)
{
throw Exception::UpdateConflictNotRecovered;
}
retry;
}
catch (Exception::DuplicateKeyException)
{
if (appl.ttsLevel() != 0)
{
throw Exception::DuplicateKeyException;
}
if (xSession::currentRetryCount() >= #RetryNum)
{
throw Exception::DuplicateKeyExceptionNotRecovered;
}
retry;
}
catch (Exception::Deadlock)
{
if (xSession::currentRetryCount() >= #RetryNum)
{
throw Exception::Deadlock;
}
retry;
}
catch(Exception::CLRError)
{
ex = ClrInterop::getLastException();
if (ex != null)
{
ex = ex.get_InnerException();
if (ex != null)
{
error(ex.ToString());
}
else
error(AifUtil::getClrErrorMessage());
}
else
error(AifUtil::getClrErrorMessage());
{
warning(infolog.text());
if (appl.ttsLevel() != 0)
{
throw error("Something happened, that the logic was not designed to handle – please log a bug.");
}
error("Something bad happened - try again later");
}
}
void post(int amount)
{
#OCCRetryCount
MyPostings debit;
MyPostings credit;
System.Exception ex;
try
{
ttsBegin;
debit = MyPostings::find('debit', true);
debit.Amount += amount;
debit.update();
credit = MyPostings::find('credit', true);
credit.Amount -= amount;
credit.update();
ttsCommit;
}
catch (Exception::UpdateConflict)
{
if (appl.ttsLevel() != 0)
{
throw Exception::UpdateConflict;
}
if (xSession::currentRetryCount() >= #RetryNum)
{
throw Exception::UpdateConflictNotRecovered;
}
retry;
}
catch (Exception::DuplicateKeyException)
{
if (appl.ttsLevel() != 0)
{
throw Exception::DuplicateKeyException;
}
if (xSession::currentRetryCount() >= #RetryNum)
{
throw Exception::DuplicateKeyExceptionNotRecovered;
}
retry;
}
catch (Exception::Deadlock)
{
if (xSession::currentRetryCount() >= #RetryNum)
{
throw Exception::Deadlock;
}
retry;
}
catch(Exception::CLRError)
{
ex = ClrInterop::getLastException();
if (ex != null)
{
ex = ex.get_InnerException();
if (ex != null)
{
error(ex.ToString());
}
else
error(AifUtil::getClrErrorMessage());
}
else
error(AifUtil::getClrErrorMessage());
}
catch {
warning(infolog.text());
if (appl.ttsLevel() != 0)
{
throw error("Something happened, that the logic was not designed to handle – please log a bug.");
}
error("Something bad happened - try again later");
}
}
AX 2012 - Müşteri ve satıcı hesabı ekleme/güncelleme
Müşteri hesabı:
CustTable custTable;
DirParty dirParty;
DirPartyPostalAddressView dirPartyPostalAddressView;
DirPartyContactInfoView dirPartyContactInfo;
CustGroup custGroup;
DirPartyTable partyTable;
DirPartyLocation dirLocation;
LogisticsPostalAddress address;
LogisticsLocation logisticsLocation;
;
select firstOnly forUpdate custTable
where custTable.AccountNum == custAccount;
//-------------------- custtable --------------------------
if (custTable.RecId == 0)
{
custTable.initValue();
custTable.AccountNum = custAccount;
custTable.CustGroup = custGroupId;
custTable.VATNum = vatNum;
custTable.IdentificationNumber = identificationNumber;
custTable.TaxOfficeName_TR = taxOfficeName_TR;
custTable.Blocked = custBlocked;
custTable.insert(DirPartyType::Organization, custName);
}
else
{
custTable.CustGroup = custGroupId;
custTable.VATNum = vatNum;
custTable.TaxOfficeName_TR = taxOfficeName_TR;
custTable.IdentificationNumber = identificationNumber;
custTable.Blocked = custBlocked;
custTable.update();
update_recordSet partyTable setting name = custName, NameAlias = nameAlias
where partyTable.RecId == custTable.Party;
}
//-------------------- adres -----------------------------
dirParty = DirParty::constructFromCommon(custTable);
select firstonly dirPartyPostalAddressView
where dirPartyPostalAddressView.Party == custTable.Party &&
dirPartyPostalAddressView.LocationName == "Adres";
dirPartyPostalAddressView.LocationName = "Adres";
dirPartyPostalAddressView.City = city;
dirPartyPostalAddressView.State = state;
dirPartyPostalAddressView.Street = street;
dirPartyPostalAddressView.IsPrimary = NoYes::Yes;
dirPartyPostalAddressView.CountryRegionId = countryRegionId;
dirParty.createOrUpdatePostalAddress(dirPartyPostalAddressView);
if (phone)
{
dirParty = DirParty::constructFromCommon(custTable);
select dirPartyContactInfo
where firstonly dirPartyContactInfo.Party == custTable.Party &&
dirPartyContactInfo.LocationName == "Telefon";
dirPartyContactInfo.LocationName ="Telefon";
dirPartyContactInfo.Locator = phone;
dirPartyContactInfo.IsPrimary = NoYes::Yes;
dirPartyContactInfo.Type = LogisticsElectronicAddressMethodType::Phone;
dirParty.createOrUpdateContactInfo(dirPartyContactInfo);
}
if (email)
{
select firstonly dirPartyContactInfo
where dirPartyContactInfo.Party == custTable.Party &&
dirPartyContactInfo.LocationName == "E-mail";
dirPartyContactInfo.LocationName ="E-mail";
dirPartyContactInfo.Locator = email;
dirPartyContactInfo.IsPrimary = NoYes::Yes;
dirPartyContactInfo.Type = LogisticsElectronicAddressMethodType::Email;
dirParty.createOrUpdateContactInfo(dirPartyContactInfo);
}
Satıcı hesabı eklemenin müşteri hesabı eklemekten tek farkı dirParty kaydının ayrıca oluşturulması . Eğer hesap organizasyon yerine bir kişi ise DirOrganization tablosu yerine DirPersonName tablosu kullanılıyor:
VendTable vendTable;
DirParty dirParty;
DirPartyPostalAddressView dirPartyPostalAddressView;
DirPartyContactInfoView dirPartyContactInfo;
VendGroup vendGroup;
DirPartyTable partyTable;
DirPartyLocation dirLocation;
LogisticsPostalAddress address;
LogisticsLocation logisticsLocation;
DirOrganization organization;
;
select firstOnly forUpdate vendTable
where vendTable.AccountNum == vendAccount;
//-------------------- vendTable --------------------------
if (vendTable.RecId == 0)
{
organization.Name = vendName;
organization.NameAlias = nameAlias;
organization.LanguageId = CompanyInfo::languageId();
organization.insert();
vendTable.initValue();
vendTable.party = organization.recid;
vendTable.AccountNum = vendAccount;
vendTable.vendGroup = vendGroupId;
vendTable.VATNum = vatNum;
vendTable.Blocked = VendBlocked;
vendTable.TaxOfficeName_TR = taxOfficeName_TR;
vendTable.insert();
}
else
{
vendTable.vendGroup = vendGroupId;
vendTable.VATNum = vatNum;
vendTable.Blocked = VendBlocked;
vendTable.update();
update_recordSet organization setting name = vendName, NameAlias = nameAlias
where organization.RecId == vendTable.Party;
}
CustTable custTable;
DirParty dirParty;
DirPartyPostalAddressView dirPartyPostalAddressView;
DirPartyContactInfoView dirPartyContactInfo;
CustGroup custGroup;
DirPartyTable partyTable;
DirPartyLocation dirLocation;
LogisticsPostalAddress address;
LogisticsLocation logisticsLocation;
;
select firstOnly forUpdate custTable
where custTable.AccountNum == custAccount;
//-------------------- custtable --------------------------
if (custTable.RecId == 0)
{
custTable.initValue();
custTable.AccountNum = custAccount;
custTable.CustGroup = custGroupId;
custTable.VATNum = vatNum;
custTable.IdentificationNumber = identificationNumber;
custTable.TaxOfficeName_TR = taxOfficeName_TR;
custTable.Blocked = custBlocked;
custTable.insert(DirPartyType::Organization, custName);
}
else
{
custTable.CustGroup = custGroupId;
custTable.VATNum = vatNum;
custTable.TaxOfficeName_TR = taxOfficeName_TR;
custTable.IdentificationNumber = identificationNumber;
custTable.Blocked = custBlocked;
custTable.update();
update_recordSet partyTable setting name = custName, NameAlias = nameAlias
where partyTable.RecId == custTable.Party;
}
//-------------------- adres -----------------------------
dirParty = DirParty::constructFromCommon(custTable);
select firstonly dirPartyPostalAddressView
where dirPartyPostalAddressView.Party == custTable.Party &&
dirPartyPostalAddressView.LocationName == "Adres";
dirPartyPostalAddressView.LocationName = "Adres";
dirPartyPostalAddressView.City = city;
dirPartyPostalAddressView.State = state;
dirPartyPostalAddressView.Street = street;
dirPartyPostalAddressView.IsPrimary = NoYes::Yes;
dirPartyPostalAddressView.CountryRegionId = countryRegionId;
dirParty.createOrUpdatePostalAddress(dirPartyPostalAddressView);
if (phone)
{
dirParty = DirParty::constructFromCommon(custTable);
select dirPartyContactInfo
where firstonly dirPartyContactInfo.Party == custTable.Party &&
dirPartyContactInfo.LocationName == "Telefon";
dirPartyContactInfo.LocationName ="Telefon";
dirPartyContactInfo.Locator = phone;
dirPartyContactInfo.IsPrimary = NoYes::Yes;
dirPartyContactInfo.Type = LogisticsElectronicAddressMethodType::Phone;
dirParty.createOrUpdateContactInfo(dirPartyContactInfo);
}
if (email)
{
select firstonly dirPartyContactInfo
where dirPartyContactInfo.Party == custTable.Party &&
dirPartyContactInfo.LocationName == "E-mail";
dirPartyContactInfo.LocationName ="E-mail";
dirPartyContactInfo.Locator = email;
dirPartyContactInfo.IsPrimary = NoYes::Yes;
dirPartyContactInfo.Type = LogisticsElectronicAddressMethodType::Email;
dirParty.createOrUpdateContactInfo(dirPartyContactInfo);
}
Satıcı hesabı eklemenin müşteri hesabı eklemekten tek farkı dirParty kaydının ayrıca oluşturulması . Eğer hesap organizasyon yerine bir kişi ise DirOrganization tablosu yerine DirPersonName tablosu kullanılıyor:
VendTable vendTable;
DirParty dirParty;
DirPartyPostalAddressView dirPartyPostalAddressView;
DirPartyContactInfoView dirPartyContactInfo;
VendGroup vendGroup;
DirPartyTable partyTable;
DirPartyLocation dirLocation;
LogisticsPostalAddress address;
LogisticsLocation logisticsLocation;
DirOrganization organization;
;
select firstOnly forUpdate vendTable
where vendTable.AccountNum == vendAccount;
//-------------------- vendTable --------------------------
if (vendTable.RecId == 0)
{
organization.Name = vendName;
organization.NameAlias = nameAlias;
organization.LanguageId = CompanyInfo::languageId();
organization.insert();
vendTable.initValue();
vendTable.party = organization.recid;
vendTable.AccountNum = vendAccount;
vendTable.vendGroup = vendGroupId;
vendTable.VATNum = vatNum;
vendTable.Blocked = VendBlocked;
vendTable.TaxOfficeName_TR = taxOfficeName_TR;
vendTable.insert();
}
else
{
vendTable.vendGroup = vendGroupId;
vendTable.VATNum = vatNum;
vendTable.Blocked = VendBlocked;
vendTable.update();
update_recordSet organization setting name = vendName, NameAlias = nameAlias
where organization.RecId == vendTable.Party;
}
Kaydol:
Kayıtlar (Atom)