acumatica
Acumatica प्लेटफ़ॉर्म संदर्भ संदर्भित करता है
खोज…
PXFormula विशेषता
सामान्य विवरण
एक्यूमैटिक में एक सूत्र एक डीएसी क्षेत्र है जिसकी गणना अन्य वस्तु क्षेत्रों के मूल्यों के आधार पर की जाती है।
सूत्र की गणना करने के लिए, औयुमतिउवा फ्रेमवर्क विभिन्न कार्यों और कार्यों (जैसे अंकगणितीय, तार्किक और तुलनात्मक संचालन और स्ट्रिंग प्रसंस्करण कार्यों का एक सेट प्रदान करता है; देखें निर्मित-सामान्य सूत्रों की सूची )। क्षेत्र मानों के अलावा, एक सूत्र Acumatica के मूल और अनुप्रयोग समाधानों द्वारा प्रदान किए गए विभिन्न स्थिरांक का उपयोग कर सकता है। इसके अलावा, एक सूत्र न केवल वर्तमान रिकॉर्ड से, बल्कि अन्य स्रोतों से भी गणना के लिए मान प्राप्त कर सकता है ( फॉर्मूला संदर्भ और इसके प्रारूप देखें )।
सूत्र की सुंदरता यह है कि वे सही समय पर मूल्य का पुन: गणना करेंगे:
- फ़ील्ड
FieldDefaulting
(नई पंक्ति सम्मिलित करना;FieldDefaulting
इवेंट हैंडलर ऑफ़ फॉर्मूला फ़ील्ड) - निर्भर क्षेत्रों के अद्यतन पर (प्रत्येक आश्रित क्षेत्र के
FieldUpdated
ईवेंट हैंडलर) - डेटाबेस चयन पर (केवल अनबाउंड फ़ील्ड के लिए;
RowSelecting
इवेंट हैंडलर) - यदि आवश्यक हो तो डेटाबेस
RowPersisted
रखने पर (डेवलपर को इसे स्पष्ट रूप से निर्दिष्ट करना चाहिए;RowPersisted
इवेंट हैंडलर)
किसी निर्भर फ़ील्ड के अद्यतन पर सूत्र फ़ील्ड मान का FieldUpdated
करने से सूत्र फ़ील्ड के लिए FieldUpdated
ईवेंट बढ़ जाता है। यह आपको आश्रित सूत्रों की एक श्रृंखला बनाने की अनुमति देता है (सूत्रों में प्रत्यक्ष और मध्यस्थता सन्दर्भ देखें)।
एप्लिकेशन डेवलपर्स अपने स्वयं के एप्लिकेशन-साइड सूत्र लिख सकते हैं।
उपयोग के साधन
एक सूत्र का उपयोग तीन मुख्य तरीकों में किया जा सकता है:
- केवल मान की गणना करके उसे सूत्र फ़ील्ड में निर्दिष्ट करना ( मूल उपयोग देखें)
- सूत्र फ़ील्ड के मौजूदा मानों से कुल मान की गणना करना और मूल ऑब्जेक्ट में निर्दिष्ट फ़ील्ड पर असाइन करना (देखें अतिरिक्त उपयोग )
- मिश्रित मोड: सूत्र मान की गणना, सूत्र फ़ील्ड पर असाइन करना, कुल मान की गणना करना और मूल ऑब्जेक्ट में फ़ील्ड को असाइन करना ( संयुक्त उपयोग देखें)
एक और सहायक मोड है, अनबाउंड फॉर्मूले, जो कि मिश्रित मोड के समान है, लेकिन सूत्र के परिकलित मान सूत्र फ़ील्ड को असाइन नहीं किए जाते हैं। एकत्रित मूल्य को तुरंत गणना करके मूल ऑब्जेक्ट के क्षेत्र को सौंपा गया है। अधिक जानकारी के लिए अनबाउंड फॉर्मूले का उपयोग देखें।
PXFormulaAttribute
गुण और कंस्ट्रक्टर पैरामीटर
सूत्र कार्यक्षमता को PXFormulaAttribute
द्वारा कार्यान्वित किया PXFormulaAttribute
। PXFormulaAttribute के निर्माता के निम्नलिखित हस्ताक्षर हैं:
public PXFormulaAttribute(Type formulaType) { // ... }
एकल पैरामीटर formulaType
एक प्रकार का सूत्र अभिव्यक्ति है जो समान डेटा रिकॉर्ड के अन्य फ़ील्ड से फ़ील्ड मान की गणना करने के लिए है। इस पैरामीटर को निम्नलिखित में से एक शर्तों को पूरा करना चाहिए:
- IBqlField इंटरफ़ेस को लागू करना चाहिए
- एक BQL स्थिर होना चाहिए
- IBqlCreator इंटरफ़ेस को लागू करना चाहिए (देखें सामान्य-निर्मित सूत्रों की सूची )
public PXFormulaAttribute(Type formulaType, Type aggregateType) { // ... }
पहला पैरामीटर, formulaType
, पहले कंस्ट्रक्टर के समान है। दूसरा पैरामीटर, aggregateType
टाइप, एक प्रकार का एकत्रीकरण फॉर्मूला है, जो चाइल्ड डेटा रिकॉर्ड फ़ील्ड से पेरेंट डेटा रिकॉर्ड फ़ील्ड की गणना करता है। एक एकत्रीकरण समारोह का उपयोग किया जा सकता है, जैसे कि SumCalc, CountCalc, MinCalc और MaxCalc। एप्लिकेशन डेवलपर्स अपने स्वयं के एकत्रीकरण सूत्र बना सकते हैं।
एक समग्र सूत्र प्रकार एक सामान्य प्रकार होना चाहिए और IBqlAggregateCalculator
इंटरफ़ेस को लागू करना चाहिए। एग्रीगेट फॉर्मूला टाइप का पहला जेनेरिक पैरामीटर IBqlField
इंटरफ़ेस को लागू करना चाहिए और पैरेंट ऑब्जेक्ट का फ़ील्ड प्रकार होना चाहिए।
public virtual bool Persistent { get; set; }
PXFormulaAttribute.Persistent
गुण इंगित करता है कि डेटाबेस में सहेजे जाने के बाद विशेषता सूत्र को पुन: PXFormulaAttribute.Persistent
करता है या नहीं। यदि फ़ील्ड सूत्र पर निर्भर करता है, तो आपको RowPersisting
इवेंट पर अपडेट किए जाने पर पुनर्गणना की आवश्यकता हो सकती है। डिफ़ॉल्ट रूप से, संपत्ति false
बराबर होती false
।
प्रयोग
ज्यादातर मामलों में, सूत्र समान डेटा रिकॉर्ड के अन्य फ़ील्ड से सूत्र फ़ील्ड के मान की प्रत्यक्ष गणना के लिए उपयोग किए जाते हैं।
सूत्र उपयोग का सबसे सरल उदाहरण:
[PXDBDate] [PXFormula(typeof(FADetails.receiptDate))] [PXDefault] [PXUIField(DisplayName = Messages.PlacedInServiceDate)] public virtual DateTime? DepreciateFromDate { get; set; }
इस उदाहरण में, ReceiptDate फ़ील्ड का मान एक नए रिकॉर्ड की प्रविष्टि पर और ReceiptDate फ़ील्ड के अद्यतन पर DepreciateFromDate फ़ील्ड को असाइन किया गया है।
थोड़ा और जटिल उदाहरण:
[PXCurrency(typeof(APPayment.curyInfoID), typeof(APPayment.unappliedBal))] [PXUIField(DisplayName = "Unapplied Balance", Visibility = PXUIVisibility.Visible, Enabled = false)] [PXFormula(typeof(Sub<APPayment.curyDocBal, APPayment.curyApplAmt>))] public virtual Decimal? CuryUnappliedBal { get; set; }
यहां, दस्तावेज़ के अनपेक्षित शेष की गणना दस्तावेज़ के संतुलन और लागू राशि के बीच अंतर के रूप में की जाती है।
डिफ़ॉल्ट मान के साथ एकाधिक पसंद का उदाहरण:
[PXUIField(DisplayName = "Class Icon", IsReadOnly = true)] [PXImage] [PXFormula(typeof(Switch< Case<Where<EPActivity.classID, Equal<CRActivityClass.task>>, EPActivity.classIcon.task, Case<Where<EPActivity.classID, Equal<CRActivityClass.events>>, EPActivity.classIcon.events, Case<Where<EPActivity.classID, Equal<CRActivityClass.email>, And<EPActivity.isIncome, NotEqual<True>>>, EPActivity.classIcon.email, Case<Where<EPActivity.classID, Equal<CRActivityClass.email>, And<EPActivity.isIncome, Equal<True>>>, EPActivity.classIcon.emailResponse, Case<Where<EPActivity.classID, Equal<CRActivityClass.history>>, EPActivity.classIcon.history>>>>>, Selector<Current2<EPActivity.type>, EPActivityType.imageUrl>>))] public virtual string ClassIcon { get; set; }
खेतों का आदेश
सूत्र गणना को सही करने के लिए DAC में फ़ील्ड्स का क्रम महत्वपूर्ण है। अन्य फ़ार्मुलों सहित सभी स्रोत फ़ील्ड (जहाँ से सूत्र की गणना की जाती है) को सूत्र फ़ील्ड से पहले DAC में परिभाषित किया जाना चाहिए। अन्यथा, फ़ील्ड गलत तरीके से गणना की जा सकती है या रनटाइम त्रुटि का कारण बन सकती है।
सूत्र संदर्भ और इसके संशोधक
डिफ़ॉल्ट रूप से, सूत्र परिकलन के संदर्भ को सूत्र घोषणा वाले वर्ग के वर्तमान ऑब्जेक्ट (रिकॉर्ड) द्वारा प्रतिबंधित किया जाता है। इसे स्थिरांक ( Constant<>
वंशज Constant<>
वर्ग) का उपयोग करने की भी अनुमति है।
एक सूत्र जो केवल अपनी वस्तु के क्षेत्रों का उपयोग करता है:
public partial class Contract : IBqlTable, IAttributeSupport { //... [PXDecimal(4)] [PXDefault(TypeCode.Decimal, "0.0", PersistingCheck = PXPersistingCheck.Nothing)] [PXFormula(typeof(Add<Contract.pendingRecurring, Add<Contract.pendingRenewal, Contract.pendingSetup>>))] [PXUIField(DisplayName = "Total Pending", Enabled=false)] public virtual decimal? TotalPending { get; set; } //... }
हालांकि, अन्य स्रोतों से सूत्र गणना के लिए इनपुट मान प्राप्त करना संभव है:
- बीएलसी में किसी भी कैश का एक वर्तमान रिकॉर्ड (यदि असाइन किया गया है)।
-
PXSelectorAttribute
द्वारा निर्दिष्ट एक विदेशी रिकॉर्ड। -
PXParentAttribute
द्वारा निर्दिष्ट एक मूल रिकॉर्ड।
सूत्र निम्नलिखित संदर्भ संशोधक का समर्थन करता है।
Current<TRecord.field>
और Current2<TRecord.field>
TRecord कैश की Current
संपत्ति में संग्रहीत रिकॉर्ड से फ़ील्ड मान प्राप्त करता है।
यदि कैश की Current
प्रॉपर्टी या फ़ील्ड में स्वयं शून्य है:
- वर्तमान <> फ़ील्ड को डिफ़ॉल्ट बनाता है और डिफ़ॉल्ट फ़ील्ड मान लौटाता है।
- करंट 2 <> अशक्त देता है।
उदाहरण:
[PXFormula(typeof(Switch< Case<Where< ARAdjust.adjgDocType, Equal<Current<ARPayment.docType>>, And<ARAdjust.adjgRefNbr, Equal<Current<ARPayment.refNbr>>>>, ARAdjust.classIcon.outgoing>, ARAdjust.classIcon.incoming>))] protected virtual void ARAdjust_ClassIcon_CacheAttached(PXCache sender)
Parent<TParent.field>
मूल डेटा रिकॉर्ड से फ़ील्ड मान प्राप्त करता है जैसा कि वर्तमान DAC पर रहने वाले PXParentAttribute द्वारा परिभाषित किया गया है।
public class INTran : IBqlTable { [PXParent(typeof(Select< INRegister, Where< INRegister.docType, Equal<Current<INTran.docType>>, And<INRegister.refNbr,Equal<Current<INTran.refNbr>>>>>))] public virtual String RefNbr { ... } [PXFormula(typeof(Parent<INRegister.origModule>))] public virtual String OrigModule { ... } }
IsTableEmpty<TRecord>
यदि निर्दिष्ट DAC के अनुरूप DB तालिका में कोई रिकॉर्ड नहीं है, तो यह true
, अन्यथा false
है।
public class APRegister : IBqlTable { [PXFormula(typeof(Switch< Case<Where< IsTableEmpty<APSetupApproval>, Equal<True>>, True, Case<Where< APRegister.requestApproval, Equal<True>>, False>>, True>))] public virtual bool? DontApprove { get; set; } }
Selector<KeyField, ForeignOperand>
मौजूदा DAC के विदेशी कुंजी क्षेत्र (KeyField) पर एक PXSelectorAttribute परिभाषित किया गया है।
वर्तमान में चयनकर्ता द्वारा संदर्भित विदेशी डेटा रिकॉर्ड प्राप्त करता है।
गणना करता है और उस डेटा रिकॉर्ड पर एक अभिव्यक्ति देता है जैसा कि फॉरेनऑपरैंड द्वारा परिभाषित किया गया है।
public class APVendorPrice : IBqlTable { // Note: inventory attribute is an // aggregate containing a PXSelectorAttribute // inside, which is also valid for Selector<>. // - [Inventory(DisplayName = "Inventory ID")] public virtual int? InventoryID [PXFormula(typeof(Selector< APVendorPrice.inventoryID, InventoryItem.purchaseUnit>))] public virtual string UOM { get; set; } }
अनबाउंड फ़ील्ड पर सूत्र का उपयोग करना
यदि सूत्र फ़ील्ड एक अनबाउंड फ़ील्ड है जो कि PXFieldAttribute
वंशजों (जैसे PXIntAttribute
या PXStringAttribute
) में से किसी एक के साथ चिह्नित है, तो इसकी गणना RowSelecting
ईवेंट के दौरान अतिरिक्त रूप से चालू हो जाती है।
निर्मित में सामान्य सूत्रों की सूची
TBD
सूत्र में प्रत्यक्ष और मध्यस्थता सन्दर्भ
TBD
सशर्त सूत्रों में नियंत्रण प्रवाह
TBD
एक क्षेत्र पर कई सूत्र का उपयोग करना
TBD
PXRestrictor विशेषता
परिचय
PXSelectorAttribute विशेषता (चयनकर्ता के रूप में भी संदर्भित), जबकि महत्वपूर्ण और अक्सर उपयोग की जाने वाली, हालांकि दो प्रमुख कमियां हैं:
- यदि कोई आइटम चयनकर्ता की स्थिति को संतुष्ट करने के लिए नहीं मिलता है, तो यह
"<object_name> cannot be found in the system"
एक"<object_name> cannot be found in the system"
। - यदि आप रिकॉर्ड के अन्य क्षेत्रों को अपडेट करते हैं तो वही त्रुटि संदेश उत्पन्न करता है लेकिन चयनकर्ता द्वारा संदर्भित ऑब्जेक्ट पहले से बदल गया है और अब उसकी स्थिति से मिलता नहीं है। यह व्यवहार स्पष्ट रूप से गलत है क्योंकि कानून को पूर्वव्यापी नहीं होना चाहिए।
इन समस्याओं को हल करने के लिए PXRestrictorAttribute
( PXRestrictorAttribute
प्रतिबंधितकर्ता भी कहा जाता है) का उपयोग किया जा सकता है।
विवरण
PXRestrictorAttribute
अकेले काम नहीं करता है; इसे हमेशा PXSelectorAttribute
के साथ जोड़ा जाना चाहिए। चयनकर्ता के बिना प्रतिबंधक के उपयोग से कोई प्रभाव नहीं पड़ेगा।
प्रतिबंधक एक ही क्षेत्र पर चयनकर्ता को ढूंढता है, इसे एक अतिरिक्त स्थिति और इसी त्रुटि संदेश में इंजेक्ट करता है। प्रतिबंधक स्थिति को बूलियन और के माध्यम से चयनकर्ता की स्थिति में जोड़ा जाता है, और एक उचित त्रुटि संदेश उत्पन्न होता है यदि संदर्भित ऑब्जेक्ट प्रतिबंधक बाधा का उल्लंघन करता है। इसके अलावा, यदि संदर्भित ऑब्जेक्ट बदल गया है और अब प्रतिबंधक की स्थिति को पूरा नहीं करता है, तो जब आप संदर्भित ऑब्जेक्ट के किसी अन्य फ़ील्ड को बदलते हैं तो कोई त्रुटि संदेश उत्पन्न नहीं होता है।
सामान्य उपयोग:
[PXDBInt] [PXSelector(typeof(Search<FAClass.assetID, Where<FAClass.recordType, Equal<FARecordType.classType>>>), typeof(FAClass.assetCD), typeof(FAClass.assetTypeID), typeof(FAClass.description), typeof(FAClass.usefulLife), SubstituteKey = typeof(FAClass.assetCD), DescriptionField = typeof(FAClass.description), CacheGlobal = true)] [PXRestrictor(typeof(Where<FAClass.active, Equal<True>>), Messages.InactiveFAClass, typeof(FAClass.assetCD))] [PXUIField(DisplayName = "Asset Class", Visibility = PXUIVisibility.Visible)] public virtual int? ClassID { get; set; }
एकाधिक चयनकर्ताओं को एक चयनकर्ता विशेषता के साथ उपयोग किया जा सकता है। इस मामले में, सभी अतिरिक्त प्रतिबंधक शर्तों को एक गैर-निर्धारित क्रम में लागू किया जाता है। किसी भी स्थिति का उल्लंघन होने पर, उपयुक्त त्रुटि संदेश उत्पन्न होता है।
Where<>
चयनकर्ता ही की हालत सभी restrictor की स्थिति के बाद लागू किया जाता है।
[PXDefault] // An aggregate attribute containing the selector inside. // - [ContractTemplate(Required = true)] [PXRestrictor(typeof(Where<ContractTemplate.status, Equal<Contract.status.active>>), Messages.TemplateIsNotActivated, typeof(ContractTemplate.contractCD))] [PXRestrictor(typeof(Where<ContractTemplate.effectiveFrom, LessEqual<Current<AccessInfo.businessDate>>, Or<ContractTemplate.effectiveFrom, IsNull>>), Messages.TemplateIsNotStarted)] [PXRestrictor(typeof(Where<ContractTemplate.discontinueAfter, GreaterEqual<Current<AccessInfo.businessDate>>, Or<ContractTemplate.discontinueAfter, IsNull>>), Messages.TemplateIsExpired)] public virtual int? TemplateID { get; set; }
विकल्प
PXRestrictorAttribute का निर्माता तीन पैरामीटर लेता है:
- प्रतिबंधक की अतिरिक्त स्थिति। इस BQL प्रकार को
IBqlWhere
इंटरफ़ेस को लागू करना चाहिए। - उपयुक्त त्रुटि संदेश। संदेश में संदर्भ दिखाने के लिए प्रारूप तत्व (घुंघराले कोष्ठक) हो सकते हैं। संदेश एक स्थानीय स्थैतिक वर्ग (जैसे
PX.Objects.GL.Messages
) में परिभाषित एक स्ट्रिंग स्थिरांक होना चाहिए। - फ़ील्ड प्रकारों की एक सरणी। ये फ़ील्ड वर्तमान ऑब्जेक्ट से संबंधित होनी चाहिए और
IBqlField
इंटरफ़ेस को लागू करना चाहिए। फ़ील्ड के मान त्रुटि संदेश स्वरूपण के लिए उपयोग किए जाएंगे।
इसके अलावा, कई विकल्प हैं जो प्रतिबंधक व्यवहार को निर्दिष्ट करते हैं।
ओवरराइडिंग इनहेरिट किए गए प्रतिबंध
ReplaceInherited
की ReplaceInherited
संपत्ति इंगित करती है कि क्या मौजूदा प्रतिबंधक को विरासत में मिले प्रतिबंधों को ओवरराइड करना चाहिए। यदि यह संपत्ति सही पर सेट होती है, तो सभी विरासत वाले प्रतिबंधित (किसी भी एग्रीगेट विशेषताओं या आधार विशेषता पर रखे गए) को बदल दिया जाएगा।
विरासत में मिले प्रतिबंधित
[CustomerActive(Visibility = PXUIVisibility.SelectorVisible, Filterable = true, TabOrder = 2)] [PXRestrictor(typeof(Where<Customer.status, Equal<CR.BAccount.status.active>, Or<Customer.status, Equal<CR.BAccount.status.oneTime>, Or<Customer.status, Equal<CR.BAccount.status.hold>, Or<Customer.status, Equal<CR.BAccount.status.creditHold>>>>>), Messages.CustomerIsInStatus, typeof(Customer.status), ReplaceInherited = true)] // Replaced all restrictors from CustomerActiveAttribute [PXUIField(DisplayName = "Customer")] [PXDefault()] public override int? CustomerID { get; set; }
कृपया ध्यान दें कि जब उचित विकल्प मौजूद हों, तो हम यह सलाह नहीं देते कि आप ReplaceInherited
कोड का उपयोग अनुप्रयोग कोड में करें। यह संपत्ति मुख्य रूप से अनुकूलन में उपयोग करने के लिए अभिप्रेत है।
ग्लोबल कैशिंग
CacheGlobal
उसी तरह से वैश्विक डिक्शनरी कार्यक्षमता का समर्थन करता है जैसे कि PXSelectorAttribute
।
उपयोग करने के लिए सिफारिशें
केवल प्रतिबंधक शर्तों का उपयोग करें
जब प्रतिबंधक और एक चयनकर्ता का एक साथ उपयोग किया जाता है, तो उत्तरार्द्ध में IBqlWhere
खंड नहीं होना चाहिए। आदर्श रूप से, सभी शर्तों को प्रतिबंधक में स्थानांतरित किया जाना चाहिए। यह दृष्टिकोण अधिक उपयोगकर्ता के अनुकूल त्रुटि संदेश प्रदान करता है और अनावश्यक पूर्वव्यापी त्रुटियों को समाप्त करता है।
एक आदर्श उदाहरण:
[PXDBString(5, IsFixed = true, IsUnicode = false)] [PXUIField(DisplayName = "Type", Required = true)] [PXSelector(typeof(EPActivityType.type), DescriptionField = typeof(EPActivityType.description))] [PXRestrictor(typeof(Where<EPActivityType.active, Equal<True>>), Messages.InactiveActivityType, typeof(EPActivityType.type))] [PXRestrictor(typeof(Where<EPActivityType.isInternal, Equal<True>>), Messages.ExternalActivityType, typeof(EPActivityType.type))] public virtual string Type { get; set; }
संभावित पूर्वव्यापी त्रुटियां:
[PXDBInt] [PXUIField(DisplayName = "Contract")] [PXSelector(typeof(Search2<Contract.contractID, LeftJoin<ContractBillingSchedule, On<Contract.contractID, Equal<ContractBillingSchedule.contractID>>>, Where<Contract.isTemplate, NotEqual<True>, And<Contract.baseType, Equal<Contract.ContractBaseType>, And<Where<Current<CRCase.customerID>, IsNull, Or2<Where<Contract.customerID, Equal<Current<CRCase.customerID>>, And<Current<CRCase.locationID>, IsNull>>, Or2<Where<ContractBillingSchedule.accountID, Equal<Current<CRCase.customerID>>, And<Current<CRCase.locationID>, IsNull>>, Or2<Where<Contract.customerID, Equal<Current<CRCase.customerID>>, And<Contract.locationID, Equal<Current<CRCase.locationID>>>>, Or<Where<ContractBillingSchedule.accountID, Equal<Current<CRCase.customerID>>, And<ContractBillingSchedule.locationID, Equal<Current<CRCase.locationID>>>>>>>>>>>>, OrderBy<Desc<Contract.contractCD>>>), DescriptionField = typeof(Contract.description), SubstituteKey = typeof(Contract.contractCD), Filterable = true)] [PXRestrictor(typeof(Where<Contract.status, Equal<Contract.status.active>>), Messages.ContractIsNotActive)] [PXRestrictor(typeof(Where<Current<AccessInfo.businessDate>, LessEqual<Contract.graceDate>, Or<Contract.expireDate, IsNull>>), Messages.ContractExpired)] [PXRestrictor(typeof(Where<Current<AccessInfo.businessDate>, GreaterEqual<Contract.startDate>>), Messages.ContractActivationDateInFuture, typeof(Contract.startDate))] [PXFormula(typeof(Default<CRCase.customerID>))] [PXDefault(PersistingCheck = PXPersistingCheck.Nothing)] public virtual int? ContractID { get; set; }