หลังจากที่เล่นไปเล่นมา ก็ไม่ได้มีปัญหาอะไร ใช้งานได้ดี ค่อนข้างง่าย สะดวกสบายดี แต่เรื่องมันเกิดขึ้นอยู่ตอนที่ผมเล่นไปเล่นมามันติด bug นี่สิครับ จะทำไงล่ะทีนี้ ก็เลยต้องหาทางแก้ล่ะครับ
ปัญหาที่ผมบอกมันเกิดตอนที่ผมใช้ module accounting/Chart of Accounts ซึ่งตอนนั้นผมพยายามจะนทึก Journal Entry (อยากเป็นนักบัญชีจำเป็นก็เลยลอง)
ทดลอง ใส่ข้อมูล ก็พบว่ามันเกิด error เยอะมากเลย
อ่าน message ดูแล้ว ก็พบว่ามันเป็น error ที่ระดับ database
violation of foreign key constraint 'ACCTTXENT_GLACOG' for key (121900,Company).ตาม ไปดูใน model definition (applications/accounting/entitydef/entitymodel.xml)
ก็จะเห็นดังนี้
rel-entity-name="GlAccountOrganization">
<key-map field-name="glAccountId"/>
<key-map field-name="organizationPartyId"/>
</relation>
จะ เห็นว่ามัน link กับ entity GlAccountOrganization
ถ้าตามไปดูต่อ ก็จะเห็น definition ดังนี้
package-name="org.ofbiz.accounting.ledger"
title="GL Account Organization Entity">
<field name="glAccountId" type="id-
ne"></field>
<field name="organizationPartyId" type="id-
ne"></field>
<field name="roleTypeId" type="id-
ne"></field>
<field name="fromDate" type="date-
time"></field>
<field name="thruDate" type="date-
time"></field>
<field name="postedBalance" type="currency-
amount"></field>
...
อ้า ฮ้า มันคือ table ที่เก็บความสัมพันธ์ระหว่างหน่วยงาน กับ รหัสบัญชี
ลอง select ข้อมูลดูโดยใช้ webtool ก็พบว่า มันมีข้อมูลมาให้รายการเดียว
ดัง นั้นเป้าหมายแรก ก็คือต้องเพิ่มรายการลงไป
อันนี้หาง่ายหน่อย อยู่ในกลุ่มงาน Chart of Account
ชื่อหัวข้องานว่า Assign GL Account
ส่วน หน้าจอ listing ก็อยู่ในข้อข้องานว่า List GL Organize
หลัง จากใส่ข้อมูลแล้ว ก็ insert ข้อมูลผ่านฉลุย
ขั้นถัดไป ก็คือ อยากทดลอง add บัญชีใหม่ๆเข้าไป
ตรงนี้พบว่า ไม่ว่าจะ click หาหัวข้อใน menu ไหน ก็หาไม่เจอ
สุดท้ายก็ต้องตามไปแกะที่ applications/accounting/webapp/accounting/WEB-INF/controller.xml
พบ ว่ามีการ define uri ไว้ดังนี้
<security https="true" auth="true"/>
<response name="success" type="view"
value="AddGlAccount"/>
</request-map>
ก็ เลยลองเอาไปใส่ url ตรงๆดู
ได้ผลแฮะ ได้หน้าจอมาหนึ่งหน้าจอ
ทดลอง ป้อนข้อมูลดู กด save
ได้ error มาใหม่อีกหนึ่งตัว
คราวนี้มันบอกว่า
GlAccountId ไม่ได้ระบุ
อ้าว ก็ไม่มี field ให้ป้อนนี่น่า แล้วมันจะระบุที่ไหนหล่ะ
ตาม ไปดู view definition
<view-map name="AddGlAccount" type="screen"page="component://accounting/widget/Accounting
Screens.xml#AddGlAccount"/>
เห็น ว่าชี้ไปที่ applications/accounting/widget/AccountingScreens.x
ml#AddGlAccount
ตาม ไปดูก็จะเห็น define ไว้แบบนี้
<section>
<actions>
<set field="titleProperty"
value="PageTitleAddGlAccount"/>
<set field="tabButtonItem" value=""/>
<set field="labelTitleProperty" value=""/>
</actions>
<widgets>
<decorator-screen name="main-decorator"
location="${parameters.mainDecoratorLocation}
"> <decorator-section name="body">
<include-form name="EditGlAccount"
location="component://accounting/webapp/
accounting/chartofaccounts/GlAccountForms.xml"/>
<!-- include-screen screen-name="
ListGlAccounts" name="ListGlAccounts" / --> <!-- tree name="GlAccountTree"
location="component://accounting/widget/
AccountingTrees.xml"/ -->
</decorator-section>
</decorator-screen>
</widgets>
</section>
</screen>
จะ เห็นว่ามันเป็นแค่ decorator
ตัว form จริงๆอยู่ใน applications/accounting/webapp/accounting/
chartofaccounts/GlAcountForms.xml
<form name="EditGlAccount" type="single"
target="updateGlAccount" title="" default-map-
name="glAccount">
<alt-target use-when="glAccount==null"
target="createGlAccount"/>
<auto-fields-service service-
name="updateGlAccount" map-name=""/>
<field use-when="glAccount!=null"
name="glAccountId"
tooltip="${uiLabelMap.AccountingNotModificatio
nRecrationGlAccount}"><display
/></field> <field use-when="glAccount==null&&
glAccountId!=null" name="glAccountId" tooltip="${uiLabelMap.AccountingCouldNotFind
GlAccount} [${glAccountId}]"><text
size="20" maxlength="20"/></field>
<!-- this to be taken care of with auto-fields-
service as soon as it uses entity field info too --> <field use-when="glAccount==null&&
glAccountId==null" name="glAccountId"><text size="20"
maxlength="20"/></field>
<field name="glAccountTypeId">
<drop-down allow-empty="false">
<entity-options entity-name="GlAccountType"
description="${description}">
<entity-order-by field-
name="description"/>
</entity-options>
</drop-down>
</field>
...
อืม ม์มัน reuse ใช้ form ทั้งหน้าจอ insert และ update
จะเห็นว่ามันตั้ง เงื่อนไขในการแสดง field glAccountId ไว้ดังนี้
1. กรณี glAccount ไม่เป็น null แสดงว่าเป็น mode update
ก็ให้แสดงค่า glAccountId โดยใช้ display tag และอนุญาติให้ดูได้อย่างเดียว ห้ามแก้ไข
2. กรณี glAccount เป็น null และมีหรือไม่มีค่า glAccountId
หน้าจอจะแสดง textfield ให้ใส่
อืมม์ case ของเรามันน่าจะตกข้อ 2, แต่มันทำไม่ไม่แสดง textfield ให้เราใส่
ผมก็เลยไปลองดูในหน้าจอ update ดูว่ามันทำงานอย่างไร
โดยดูใน applications/accounting/widget/AccountingScreens.xml#GlAccountNavigate
ปราก ฎว่า flow ก่อนที่จะเข้าหน้าจอ update
มันทำแบบนี้
<section>
<actions>
... <!-- parameters includes requestAttributes and
parameter map -->
<!-- requestParameters is just the parameter
map -->
<set field="glAccountId" from-
field="requestParameters.glAccountId"/>
... <entity-one entity-name="GlAccount"
value-name="glAccount"/>
</actions>
<widgets>
... </widgets>
</section>
</screen>
ลอง กลับไปดู flow ในหน้าจอ AddGlAccount
มันไม่ได้ set entity นี่หน่า
ทดลอง ใส่บรรทัดนี้เพิ่มลงไป
<section>
<actions>
<set field="titleProperty"
value="PageTitleAddGlAccount"/>
<set field="tabButtonItem" value=""/>
<set field="labelTitleProperty" value=""/>
<entity-one entity-name="GlAccount"
value-name="glAccount"/>
</actions>
...
ลอง restart OFBiz แล้วเปิด browser ดู
พบว่าได้ผลครับ มี textfield ให้ป้อนแล้ว
ทดลองป้อนแล้ว submit ดู ก็พบว่ามันบันทึกลง Database ได้แล้ว