# Purchase Order

## Purchase Order's Database

<table><thead><tr><th>UI Name</th><th>Database</th><th>Type</th><th>Remarks</th></tr></thead><tbody><tr><td>P/O No</td><td><pre><code>Doc
</code></pre></td><td><strong><code>String</code></strong></td><td><p>Avoid using the same <strong><code>P/O No</code></strong> to prevent overwrite.</p><p>E.g.: <code>PO-123456</code></p></td></tr><tr><td>P/O Key</td><td><pre><code>DocKey
</code></pre></td><td><strong><code>Number</code></strong></td><td>E.g.: <code>123456</code></td></tr><tr><td>Last Modified</td><td><pre><code>LastModified
</code></pre></td><td><strong><code>String</code></strong></td><td>E.g.: <code>2024-12-19T08:57:37.557</code></td></tr><tr><td>Creditor</td><td><pre><code>CreditorCode
</code></pre></td><td><strong><code>String</code></strong></td><td><p><strong><code>Creditor</code></strong> must match existing <strong>creditor code</strong>, and they must be <strong>active</strong> state.</p><p>E.g.: <code>400-C001</code></p></td></tr><tr><td>Name</td><td><pre><code>CreditorName
</code></pre></td><td><strong><code>String</code></strong></td><td>E.g.: <code>ABC SUPPLIER</code></td></tr><tr><td>Supplier DO No</td><td><pre><code>SupplierDONo
</code></pre></td><td><strong><code>String</code></strong></td><td>E.g.: <code>DO-654321</code></td></tr><tr><td>Address [Line 1]</td><td><pre><code>InvAddr1
</code></pre></td><td><strong><code>String</code></strong></td><td>E.g.: <code>123 INDUSTRIAL PARK</code></td></tr><tr><td>Address [Line 2]</td><td><pre><code>InvAddr2
</code></pre></td><td><strong><code>String</code></strong></td><td>E.g.: <code>ZONE 4</code></td></tr><tr><td>Address [Line 3]</td><td><pre><code>InvAddr3
</code></pre></td><td><strong><code>String</code></strong></td><td>E.g.: <code>CITY, STATE 12345</code></td></tr><tr><td>Address [Line 4]</td><td><pre><code>InvAddr4
</code></pre></td><td><strong><code>String</code></strong></td><td>E.g.: <code>null</code></td></tr><tr><td>Date</td><td><pre><code>DocDate
</code></pre></td><td><strong><code>String</code></strong></td><td>E.g.: <code>2024-12-19T00:00:00</code></td></tr><tr><td>Branch</td><td><pre><code>BranchCode
</code></pre></td><td><strong><code>String</code></strong></td><td>E.g.: <code>BR001</code></td></tr><tr><td>Credit Term</td><td><pre><code>DisplayTerm
</code></pre></td><td><strong><code>String</code></strong></td><td>E.g.: <code>NET 30</code></td></tr><tr><td>Purchase Location</td><td><pre><code>PurchaseLocation
</code></pre></td><td><strong><code>String</code></strong></td><td><p>Must have existing <strong><code>Purchase Location</code></strong> in the accounting system.</p><p>E.g.: <code>NY</code></p></td></tr><tr><td>Purchase Agent</td><td><pre><code>PurchaseAgent
</code></pre></td><td><strong><code>String</code></strong></td><td>E.g.: <code>JOHN SMITH</code></td></tr><tr><td>Ship Via</td><td><pre><code>ShipVia
</code></pre></td><td><strong><code>String</code></strong></td><td>E.g.: <code>AIR</code></td></tr><tr><td>Ship Info</td><td><pre><code>ShipInfo
</code></pre></td><td><strong><code>String</code></strong></td><td>E.g.: <code>EXPRESS</code></td></tr><tr><td>Total (ex)</td><td><pre><code>TotalExTax
</code></pre></td><td><strong><code>Number</code></strong></td><td>E.g.: <code>1000</code></td></tr><tr><td>Inclusive</td><td><pre><code>InclusiveTax
</code></pre></td><td><strong><code>String</code></strong></td><td>E.g.: <code>T</code></td></tr><tr><td>Taxable Amount</td><td><pre><code>TaxableAmt
</code></pre></td><td><strong><code>Number</code></strong></td><td>E.g.: <code>100</code></td></tr><tr><td>Tax</td><td><pre><code>Tax
</code></pre></td><td><strong><code>Number</code></strong></td><td>E.g.: <code>10</code></td></tr><tr><td>Currency</td><td><pre><code>CurrencyCode
</code></pre></td><td><strong><code>String</code></strong></td><td>E.g.: <code>USD</code></td></tr><tr><td>Rate</td><td><pre><code>CurrencyRate
</code></pre></td><td><strong><code>Number</code></strong></td><td>E.g.: <code>1.0</code></td></tr><tr><td>Local Total</td><td><pre><code>LocalNetTotal
</code></pre></td><td><strong><code>Number</code></strong></td><td>E.g.: <code>1100</code></td></tr><tr><td>Total</td><td><pre><code>NetTotal
</code></pre></td><td><strong><code>Number</code></strong></td><td>E.g.: <code>1100</code></td></tr><tr><td>Sequence</td><td><pre><code>Seq
</code></pre></td><td><strong><code>Number</code></strong></td><td>E.g.: <code>1</code></td></tr><tr><td>Item Code</td><td><pre><code>ItemCode
</code></pre></td><td><strong><code>String</code></strong></td><td>E.g.: <code>ITEM-001</code></td></tr><tr><td>Description</td><td><pre><code>Description
</code></pre></td><td><strong><code>String</code></strong></td><td>E.g.: <code>ITEM DESCRIPTION</code></td></tr><tr><td>Description 2</td><td><pre><code>Desc2
</code></pre></td><td><strong><code>String</code></strong></td><td>E.g.: <code>ADDITIONAL INFO</code></td></tr><tr><td>Delivery Date</td><td><pre><code>DeliveryDate
</code></pre></td><td><strong><code>String</code></strong></td><td>E.g.: <code>2024-12-20T00:00:00</code></td></tr><tr><td>Location</td><td><pre><code>Location
</code></pre></td><td><strong><code>String</code></strong></td><td>E.g.: <code>WAREHOUSE 1</code></td></tr><tr><td>UOM</td><td><pre><code>UOM
</code></pre></td><td><strong><code>String</code></strong></td><td>E.g.: <code>PCS</code></td></tr><tr><td>Quantity</td><td><pre><code>Qty
</code></pre></td><td><strong><code>Number</code></strong></td><td><p>Value must be <strong>number</strong>, and value <strong>cannot</strong> be <strong>negative.</strong></p><p>E.g.: <code>10</code></p></td></tr><tr><td>Unit Price</td><td><pre><code>UnitPrice
</code></pre></td><td><strong><code>Number</code></strong></td><td><p>Value must be <strong>number</strong>, and value <strong>cannot</strong> be <strong>negative.</strong></p><p>E.g.: <code>100</code></p></td></tr><tr><td>Discount</td><td><pre><code>Discount
</code></pre></td><td><strong><code>String</code></strong></td><td>E.g.: <code>10%</code></td></tr><tr><td>C/N Amt.</td><td><pre><code>CNAmt
</code></pre></td><td><strong><code>String</code></strong></td><td>E.g.: <code>50</code></td></tr><tr><td>Subtotal</td><td><pre><code>SubTotal
</code></pre></td><td><strong><code>Number</code></strong></td><td>E.g.: <code>900</code></td></tr><tr><td>Subtotal (ex)</td><td><pre><code>SubTotalExTax
</code></pre></td><td><strong><code>Number</code></strong></td><td>E.g.: <code>800</code></td></tr><tr><td>Detail Tax</td><td><pre><code>DtlTax
</code></pre></td><td><strong><code>Number</code></strong></td><td>E.g.: <code>80</code></td></tr><tr><td>Ref Document No</td><td><pre><code>FromDocNo
</code></pre></td><td><strong><code>String</code></strong></td><td>E.g.: <code>DOC-001</code></td></tr><tr><td>UDF Description 2</td><td><pre><code>UDF_Desc2
</code></pre></td><td><strong><code>String</code></strong></td><td>E.g.: <code>CUSTOM FIELD</code></td></tr></tbody></table>

## Purchase Order's Sample Code

{% hint style="warning" %}
Remember to change to the **correct field** before proceeding to run **ANY** script.
{% endhint %}

{% tabs %}
{% tab title="SQL Script" %}
{% hint style="info" %}
This is a sample SQL, may not be as same as your database.
{% endhint %}

```sql
SELECT TOP (10)
    Doc AS Document,
    DocKey AS DocumentKey,
    LastModified,
    CreditorCode,
    CreditorName,
    InvAddr1,
    InvAddr2,
    InvAddr3,
    InvAddr4,
    DocDate,
    BranchCode,
    DisplayTerm,
    PurchaseLocation,
    PurchaseAgent,
    ShipVia,
    ShipInfo,
    TotalExTax,
    InclusiveTax,
    TaxableAmt,
    Tax,
    CurrencyCode,
    CurrencyRate,
    LocalNetTotal,
    NetTotal,
    Seq,
    ItemCode,
    Description,
    Desc2,
    DeliveryDate,
    Location,
    UOM,
    Qty,
    UnitPrice,
    Discount,
    SubTotal,
    SubTotalExTax,
    DtlTax,
    FromSODocList,
    FurtherDescription,
    LastModified
FROM PurchaseOrders
WHERE LastModified > "{LAST_MODIFIED_DATE_TIME}";
```

{% endtab %}

{% tab title="jobs.json" %}
{% hint style="warning" %}
In order to sync, you must include **`LastModified`** in **`SELECT`**
{% endhint %}

```json
"SQLSync": [
  {
    "name": "AutoCount to Inistate",
    "enabled": false,
    "connectionString": "Data Source={SERVER};Initial Catalog={DATABASE};User Id={DB_USERNAME};Password={DB_PASSWORD};",
    "hook": "https://api.inistate.com/api/automationHook/hook/{MODULE-ID}-{LOGIC-NAME}",
    "sql": "SELECT AccNo, CompanyName, Address1, Address2, Address3, Address4, Phone1, DisplayTerm, EmailAddress, SalesAgent, LastModified \nFROM Debtor \nWHERE LastModified > @date",
    "lastSync": "{LAST-SYNC-DATE-TIME}",
    "start": null
  }
]
```

{% endtab %}

{% tab title="Logic Script" %}
{% hint style="info" %}
To find `{fieldName}`, you are required to have access to **Alpha** or use **Network** in Developer Tools `[F12]`.
{% endhint %}

{% code fullWidth="true" %}

```python
#debug('test', inputs)
def getFlatten(list, table):
    details = [dict(Line=y, Document=x) for x in list for y in x[table]]
    return details
    
moduleName = '{YOUR-MODULE-NAME}'
inistateKeyField = 'DocumentId'
keyField = 'Doc'
modifiedDateField = 'LastModified'
fields = [['DocumentId', 'Doc'],['LastModified', 'LastModified']]
inistateFields = []
tableField = 'Items'
tableColumns = ['Seq','ItemCode','Description','Desc2','DeliveryDate','Location','UOM','Qty','UnitPrice','Discount','SubTotal','SubTotalExTax','DtlTax','FromSODocList','FurtherDescription']

def createLine(x):
    item = JObject()
    main = JObject.FromObject(x[0])
    
    for field in main:
        if not tableColumns.Contains(field.Name):
            item[field.Name] = main[field.Name]
        
    item['items'] = JArray()
        
    for itemRow in x:
        rowJSON = JObject()
        for field in tableColumns:
            rowJSON[field] = itemRow[field]
        item['items'].Add(rowJSON)
        
    return item

def productAddToSync(product):
    if product is not None:
        form = Module('{YOUR-MODULE-NAME}').execute('Set To Sync', product)
        form['To Sync'] = True
        Module('{YOUR-MODULE-NAME}').submit(product, 'Set To Sync', form)
    
result = list(inputs["list"]).GroupBy(lambda x: x[keyField].ToString()).Select(lambda x: createLine(x)).ToList()

for item in result:
    entry = Module('{YOUR-MODULE-NAME}').find({ 'Dynamic.Extension.{fieldName}': item['Doc'] })
    # debug('test', item['Doc'])
    # debug('valid', entry['SyncDateTime'])
    # debug('valid time', item['LastModified'])
    form = Module('{YOUR-MODULE-NAME}').execute('sync', entry)
    form['{YOUR-CREDITOR}'] = item['CreditorCode']
    form['{YOUR-NAME}'] = item['CreditorName']
    form['{YOUR-ADDRESS1}'] = item['InvAddr1']
    form['{YOUR-ADDRESS2}'] = item['InvAddr2']
    form['{YOUR-ADDRESS3}'] = item['InvAddr3']
    form['{YOUR-ADDRESS4}'] = item['InvAddr4']
    form['{YOUR-P/O NO}'] = item['Doc']
    form['{YOUR-DOC-DATE}'] = item['DocDate']
    form['{YOUR-BRANCH}'] = item['BranchCode']
    form['{YOUR-CREDIT TERM}'] = item['DisplayTerm']
    form['{YOUR-PURCHASE LOCATION}'] = item['PurchaseLocation']
    form['{YOUR-PURCHASE AGENT}'] = item['PurchaseAgent']
    form['{YOUR-SHIP VIA}'] = item['ShipVia']
    form['{YOUR-SHIP INFO}'] = item['ShipInfo']
    
    form['{YOUR-SUBTOTAL (EX)}'] = item['TotalExTax']
    form['{YOUR-INCLUSIVE}'] = True if item['InclusiveTax'] != "F" else False
    form['{YOUR-TAXABLE AMOUNT}'] = item['TaxableAmt']
    form['{YOUR-TAX}'] = item['Tax']
    form['{YOUR-CURRENCY}'] = item['CurrencyCode']
    form['{YOUR-RATE}'] = item['CurrencyRate']
    form['{YOUR-LOCAL TOTAL}'] = item['LocalNetTotal']
    form['{YOUR-TOTAL}'] = item['NetTotal']
    
    # handle table
    lines = list(item['items']).ToList().OrderBy(lambda x: Convert.ToInt32(x['Seq'])).ToList()
    text = ''
    
    while len(form['Main']) > len(lines) :
        last = form['Main'].Last()
        productAddToSync(last['Item Code'])
        formLine = form.remove('Main',last)
        
    for line in lines:
        # create if none
        if len(form['Main']) <= lines.IndexOf(line):
            formLine = form.add('Main')
        else :
            formLine = form['Main'][lines.IndexOf(line)]
            
        # assign value to table row
        product = Module('{YOUR-MODULE-NAME}').find({ 'Dynamic.Extension.pIoowv': str(line['ItemCode'])  })
        if product is not None:
            if formLine['{YOUR-ITEM CODE}'].Id > 0 and formLine['{YOUR-ITEM CODE}'] != str(line['ItemCode']) and entry is not None :
                productAddToSync(formLine['{YOUR-ITEM CODE}'])
            formLine['{YOUR-ITEM CODE}'] = product
            
        formLine['{YOUR-DESCRIPTION}'] = line['Description']
        formLine['{YOUR-DESCRIPTION 2}'] = line['Desc2']
        formLine['{YOUR-DELIVERY DATE}'] = line['DeliveryDate']
        formLine['{YOUR-LOCATION}'] = line['Location']
        formLine['{YOUR-UOM}'] = line['UOM']
        formLine['{YOUR-QTY}'] = line['Qty']
        formLine['{YOUR-UNIT PRICE}'] = line['UnitPrice']
        formLine['{YOUR-DISCOUNT}'] = line['Discount']
        formLine['{YOUR-SUBTOTAL}'] = line['SubTotal']
        
        formLine['{YOUR-TOTAL (INC)}'] = Convert.ToInt32(line['SubTotalExTax'] if line['SubTotalExTax'] != None else 0) + Convert.ToInt32(line['DtlTax'] if line['DtlTax'] != None else 0) #no field in Autocount record total include tax, need add 2 value
        formLine['{YOUR-FROM S/O DOC. NO.}'] = line['FromSODocList']
        # formLine['Further Description'] = line['FurtherDescription'] #ignore first, take time to handle the image
        
    # debug('form', form)
    Module('{YOUR-MODULE-NAME}').submit(entry, form)
    
    # after = Module('Purchase Order').find({ 'Dynamic.Extension.zHLOEu': item['Doc'] })
    # if after is not None:
    #     for item in after['Main']:
    #         if item['Item Code'].Id > 0:
    #             form2 = Module('Product').execute('Update Stocks', item['Item Code'])
    #             result2 = Module('Product').submit(item['Item Code'], 'Update Stocks', form2)
debug('result', result)
```

{% endcode %}
{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://inistate.gitbook.io/home/advanced/integration/accounting-2/purchase-order.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
