📄 technicaldocs.sgml
字号:
is. We will call these two accounts the "payment GL account" and the "offsetting GL account."</para> <para> Payments are posted to GL using the the <code>postPaymentToGl</code> service. It also uses paymentMethodType, lookups PaymentGlAccountTypeMap to get a glAccountTypeId, and then uses <code>getProductOrgGlAccount</code> to determine what the offsetting GL account should be. Then it calls <code>getPaymentAccountAndParties</code> to get the payment's GL account. Next, it does a conversion of the payment amount to the currency of the organization party. After that, it first looks at paymentType to determine what kind of a payment it is and who the organizationPartyId (ie, partyId for our company) and transactionPartyId (ie, partyId for outside company is): <itemizedlist> <listitem> <para>PaymentType's parentTypeId = DISBURSEMENT, transaction entry is a debit to the offsetting (PaymentGlAccountTypeMap) GL account and a credit to the Payment GL account.</para> </listitem> <listitem> <para>PaymentType's parentTypeId = RECEIPT, the transaction is a debit to the Payment's GL account and a credit to the offsetting (PaymentGlAccountTypeMap) GL account.</para> </listitem> </itemizedlist> Finally, it creates the AcctgTransEntry entities and calls createAcctgTransAndEntries to post them. </para> <para><code>postPaymentToGl</code> is written so that it can post a List of debit and a List of credit entries with separate amounts for each entry. At this point, the only application of this is if the payment is a tax payment.</para> <para>For tax payments, postPaymentToGl will look through the PaymentApplication entity. For each geo to which the payment was applied, it will find the GL account (from TaxAuthorityGlAccount) and use the amount of the PaymentApplication as the amount to post to this GL account. This entire Map of geos and their associated GL accounts are then posted to the transaction.</para> <para> The service <code>getPaymentAccountAndParties</code> takes in a paymentId and returns a glAccountId associated with this payment. It does it by looking, in the following sequence, for: <orderedlist> <listitem> <para>PaymentMethod associated with Payment, to see if it has a glAccountId;</para> </listitem> <listitem> <para>CreditCardTypeGlAccount, if the payment method is a credit card.</para> </listitem> <listitem> <para>PaymentMethodTypeGlAccount, associated with the Payment's PaymentMethodType and the organizationPartyId, to see if there is a glAccountId here;</para> </listitem> <listitem> <para>PaymentMethodType, to see if it has a defaultGlAccountId</para> </listitem> </orderedlist> </para> <para> It also returns the organizationPartyId and transactionPartyId as follows: <itemizedlist> <listitem> <para>PaymentType's parentTypeId = DISBURSEMENT, then organizationPartyId = Payment.fromPartyId, transactionPartyId = Payment.toPartyId. </para> </listitem> <listitem> <para>PaymentType's parentTypeId = RECEIPT, transactionPartyId = Payment.fromPartyId, organizationPartyId = Payment.toPartyId. </para> </listitem> </itemizedlist> </para> </section> <section> <title>Inventory or Shipment Receipt</title> <para><code>postShipmentReceiptToGl</code> will post to the INVENTORY and UNINVOICED_SHIP_RCPT GL accounts for a given shipmentReceiptId. It is designed to run as a SECA to the <code>createShipmentReceipt</code> service.</para> </section> <section> <title>Inventory Variance</title> <para>Create a VarianceReasonGlAccount entity (organizationPartyId*, varianceReasonId*, glAccountId) foreign-key Party, VarianceReason, and GlAccount. (applications/accounting/entitydef/entitymodel.xml).</para> <para>Service <code>getInventoryItemOwner</code> takes inventoryItemId and returns the ownerPartyId of the inventory item. This is found from the InventoryItem's Facility's ownerPartyId. (simple-xml: hot-deploy/accounting/entitydef/services_ledger.xml).</para> <para>Service <code>postInventoryVarianceToGl</code> takes inventoryItemId and physicalInventoryId. If quantityOnHandVar is not zero, then do the following: Get the owner's PartyAcctgPreference entity and see if COGSMethodId = "COGS_AVG_COST". If so, amount = quantityOnHandVar* getProductAverageCost(service) for ownerPartyId, productId. <emphasis>Other types of COGS Method are not implemented right now.</emphasis> From productId of the inventory item, find the GL account from ProductGlAccount of type "INVENTORY". Otherwise, we're using the INVENTORY_ACCOUNT of the ownerPartyId. This is the inventory GL account. Then, get the varianceReasonGlAccountId from the VarianceReason entity matching the varianceReasonId (from inventory variance) and ownerParty Id. This is the Variance Expense GL Acount. Create two AcctgTransEntries, one which debits the inventory GL account and one which credits variance expense GL account (see <code>postInvoiceToGl</code> service for example.) (organizationPartyId=ownerPartyId, acctgTransEntryTypeId="_NA_") Call <code>createAcctgTransAndEntries</code> to post these two entries. (glFiscalTypeId = "ACTUAL", acctgTransTypeId="ITEM_VARIANCE_ACCTG_").</para> </section> <section> <title>Payment Applications</title> <para> Accounting transactions only need to be created when the payment being applied is either a CUSTOMER_DEPOSIT or VENDOR_PREPAY: <itemizedlist> <listitem> <para>if CUSTOMER_DEPOSIT, debit the CUSTOMER_DEPOSIT GL account and credit the ACCOUNTS_RECEIVABLE GL account. OrganizationPartyId = Payment.toPartyId, transactionPartyId = Payment.fromPartyId.</para> </listitem> <listitem> <para>if VENDOR_PREPAY, debit the ACCOUNTS_PAYABLE GL account and credit the PREPAID_EXPENSES GL account, organizationPartyId = Payment.fromPartyId, transactionPartyId = Payment.toPartyId</para> </listitem> </itemizedlist> </para> </section> <section> <title>Returns</title> <para>Returns are recorded in the ReturnHeader and ReturnItem entities. When there is a facility for a return, a "Receive Items" tab also shows up on the order manager's returns page, and you can go into the facility manager to receive the items back into inventory. If a return is done for refund, a cash payment is done. When a return is done for credit, the amount is added to the customer's BillingAccount. If the customer has no billing account, then a new one is created for him.</para> <para>Currently, the business logic for returns is done as an SECA. When the <code>updateReturnHeader</code> is called and the result is a status of RETURN_RECEIVED, <code>processRefundReturn</code>, <code>processCreditReturn</code>, and <code>processReplacementReturn</code> are called. When returns are received, the "receiveReturnedProduct" request calls service-groups <code>prepareInventoryReceipt</code> and <code>createShipmentReceipt</code>, which triggers a SECA for <code>updateReturnStatusFromReceipt</code>.</para> <para>When <code>updateReturnHeader</code> is called, we should add an additional SECA to call service <code>postReturnToGl</code>. <code>postReturnToGl</code> takes a returnHeaderId and will create AcctgTrans and AcctgTransEntry entities using <code>createAcctgTransAndEntries</code>. The value of each returned item needs to be debited from the organization's SALES GL account, and the aggregate value of the return needs to be credited to the organization's CUSTOMER_CREDITS GL account. This will ensure that each item's SALES GL account is correctly tracked over time, through both invoices and returns. <code>postReturnToGl</code> will look through the OrderItem to OrderAdjustment and figure out the portion of the return price that was a sales tax. That portion will be debited to the tax account in OrderAdjustment. The rest will be debited to the SALES GL account.</para> <para>When <code>processRefundReturn</code> is called, it is calling <code>refundPayment</code> with the original order's payment preferences and the refund amount. This c <code>createPayment</code> to create a Payment of paymentTypeId CUSTOMER_REFUND. CUSTOMER_REFUND is a DISBURSEMENT payment type, so this payment will cause the GL account defined for CREDIT_REFUND in PaymentTypeGlAccountMap to be debited and the GL account for the payment itself to be credited.</para> <para>When <code>processCreditReturn</code> is called, we need also create a Payment of CUSTOMER_REFUND type. Since credit refunds are done against billing accounts right now, this means that we need to configure the paymentMethodTypeId of "EXT_BILLACT" to have a GL account for Accounts Receivables.</para> <para>When <code>processReplacementReturn</code> is called, nothing else needs to be done. Another order is created during processReplacementReturn with storeOrder, starting a new cycle of invoices, payments, and shipment issuance. Since we have already posted to SALES_RETURNS and CUSTOMER_CREDITS, we should be fine. <emphasis>Obviously, we should verify this at some point.</emphasis></para> <para>When <code>updateReturnStatusFromReceipt</code> is commited with "RETURN_RECEIVED" (current ECA for launching process return services), we should put in a SECA service, <code>postReturnInventoryToGl</code>. <code>postReturnInventoryToGl</code> takes returnHeaderId and will debit INVENTORY and credit COGS accounts for the return-to Party. This will be done for each item on the return. If the return-to Party's COGS method is AVERAGE_COST, then it will use <code>getProductAverageCost</code> to get the per item cost of each item. <emphasis>We'll implement with LIFO and FIFO later</emphasis>.</para> </section> </chapter> <chapter> <title>Sales and Other Taxes</title> <para>When sales tax is calculated, it is stored in the OrderAdjustment entity and related to OrderItem or OrderHeader entities. The OrderAdjustment entity should have the overrideGlAccountId, taxAuthPartyId, taxAuthGeoId for the sales tax filled in from the TaxAuthorityGlAccount entity. (The overrideGlAccountId is the GL account in TaxAuthorityGlAccount.) As the invoice is created, those fields are copied to the InvoiceItem entity for the sales tax items.</para> <para>When the invoice is posted to GL, the GL account is from either the overrideGlAccountId, or if for some reason that is not avaialble, from the GL account for the invoice item type. If the item is a tax item, the party of the AcctgTransEntry is the taxAuthPartyId rather than the partyId of the rest of the transaction.</para> <para>For a return, each <code>ReturnItem</code> is related to an <code>OrderItem</code>, which in is related to an <code>OrderAdjustment</code>. The service <code>getReturnableQuantity</code> calculates a return price based on the original price on the <code>OrderItem</code> and its related <code>OrderAdjustments</code>. Similarly, when posting returns, we can calculate the amount of the sales tax by finding the SALES_TAX <code>OrderAdjustments</code>. The amount is (return quantity / order item adjustment quantity) * order item adjustment amount. The <code>OrderAdjustment</code> entity also holds the GL accounts and tax authority partyId for the return. </para> </chapter> <chapter> <title>Calculating and Tracking Average Costs</title> <para>New entity <code>ProductAverageCost</code> (organzationPartyId*, productId*, averageCost, fromDate, thruDate) for tracking average costs.</para> <para>Service <code>getOrgInventoryQuantity</code> takes organizationPartyId, productId and returns a inventoryQuantity, which is the units of QOH quantity available in all facilities of the organizationPartyId.</para>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -