Here's the code
define(['N/record', 'N/search', 'N/format', './gw_cm_inv_log_service'], (
record,
search,
format,
InvCmLogService
) => {
/**
* Module Description...
*
* @type {Object} CreditMemoService
*
* @copyright 2020 Gateweb
* @author Sean Lin <
seanlin816@gmail.com>
*
* @NApiVersion 2.1
* @NModuleScope Public
*/
class CreditMemoService {
constructor() {
this.invCmLogService = new InvCmLogService()
}
getCustomFormId() {}
genBatchCreditMemos(cmDataArr) {
var genCmResult = cmDataArr
.map((cmData) => {
var createCmResult = this.genCreditMemo(cmData)
if (createCmResult.success) {
// this.createInvCmLog(createCmResult.result)
this.invCmLogService.createInvCmLog(createCmResult.result)
}
return createCmResult
})
.filter((item) => item !== null)
log.debug({
title: 'genCreditMemo',
details: JSON.stringify(genCmResult),
})
return genCmResult
}
genCreditMemo(cmData) {
var createCmResult = {
success: false,
message: '',
requestData: cmData,
result: {
invoiceId: cmData.fromInvId,
cmId: 0,
cmType: cmData.type,
appliedAmt: cmData.totalApplyAmt,
cmTypeId: cmData.typeId,
useForm: {
cm:
cmData.useForm.cm,
inv: cmData.useForm.inv,
},
},
}
try {
var cmId = this.createCm(cmData)
createCmResult.success = true
createCmResult.message = ''
createCmResult.result.cmId = cmId
} catch (e) {
createCmResult.success = false
createCmResult.message = e.message
// alert(e.message)
log.debug({ title: 'genCreditMemo Error Occurs', details: e.message })
}
return createCmResult
}
/**
* Create Credit Memo
* @param invoiceId - Invoice ID use for transform record from
* @param cmData - credit memo object for set up new created credit memo
* @return {int} credit memo id after it's saved
*/
createCm(cmData) {
log.debug({ title: 'createCm cmData', details: cmData })
var cmRecord = this.generateCmRecord(cmData)
this.setBodyFieldValue(cmRecord, cmData)
log.debug({
title: 'after set body fields',
details: JSON.stringify(cmRecord),
})
this.clearDiscountItem(cmRecord)
log.debug({
title: 'after discount items',
details: JSON.stringify(cmRecord),
})
this.processItemLines(cmRecord, cmData)
log.debug({
title: 'after item lines',
details: JSON.stringify(cmRecord),
})
this.processApplyLines(cmRecord, cmData.fromInvId, cmData.totalApplyAmt)
log.debug({
title: 'after apply lines',
details: JSON.stringify(cmRecord),
})
log.debug({ title: 'before save', details: JSON.stringify(cmRecord) })
return cmRecord.save({
enableSourcing: true,
ignoreMandatoryFields: true,
})
}
/**
* Transform record from invoice to credit memo
* @param {int} invId - Invoice Id that transform from
* @return {Record} transformed credit memo record (unsaved)
*/
generateCmRecord(cmData) {
var cmRecord = record.transform({
fromType: record.Type.INVOICE,
fromId: cmData.fromInvId,
toType: record.Type.CREDIT_MEMO,
isDynamic: true,
defaultValues: {
customform:
cmData.useForm.cm,
},
})
return cmRecord
}
/**
* Clear discount
* @param {Record} cmRecord - transformed creit memo record from invoice
*/
clearDiscountItem(cmRecord) {
cmRecord.setValue({
fieldId: 'discountitem',
value: '',
})
cmRecord.setValue({
fieldId: 'discountrate',
value: 0,
})
}
/**
* set item lines for amount and gross amount, reset quantity to 0
* @param {Record} cmRecord
* @param {Object} cmData
*/
processItemLines(cmRecord, cmData) {
var sublistId = 'item'
let lineCount = cmRecord.getLineCount({ sublistId: sublistId })
for (var line = lineCount - 1; line >= 0; line--) {
cmRecord.selectLine({
sublistId: sublistId,
line: line,
})
var itemId = cmRecord.getCurrentSublistValue({
sublistId: sublistId,
// line: line,
fieldId: 'item',
})
var cmDataItems = cmData.items.filter(
(item) =>
parseInt(item.item) === parseInt(itemId) &&
parseInt(item.line) - 1 === line
)
if (cmDataItems.length > 0) {
var cmDataItem = cmDataItems[0]
// this.updateItemLine(cmRecord, cmDataItem, sublistId, line)
this.updateCurrentItemLine(cmRecord, cmDataItem, sublistId, line)
log.debug({
title: 'processItemLines',
details: 'before commit line',
})
cmRecord.commitLine({
sublistId: sublistId,
})
} else {
// this.updateItemQuantityToZero(cmRecord, sublistId, line)
log.debug({ title: 'removing line' })
this.removeLine(cmRecord, sublistId, line)
}
}
}
updateCurrentItemLine(cmRecord, cmDataItem, sublistId) {
// TODO: verify all fields are brought over
log.debug({
title: 'cm service updateCurrentItemLine',
details: cmDataItem,
})
var fieldsToUpdate = [
'quantity',
'rate',
'custcol_tcm_line_taxprice',
'amount',
'taxamt',
'grossamt',
]
cmDataItem.quantity = 0
fieldsToUpdate.forEach((fieldId) => {
var fieldToUpdate = fieldId === 'taxamt' ? 'tax1amt' : fieldId
var itemId = cmRecord.getCurrentSublistValue({
sublistId: sublistId,
// line: line,
fieldId: 'item',
})
log.debug({
title: 'cm service updateItemLine itemId',
details: itemId,
})
var currentValue = cmRecord.getCurrentSublistValue({
sublistId: sublistId,
// line: line,
fieldId: fieldToUpdate,
})
log.debug({
title: 'cm service updateItemLine fieldId: currentValue',
details: fieldToUpdate + ' : ' + currentValue,
})
log.debug({
title: 'cm service updateItemLine fieldId: value',
details: fieldToUpdate + ' : ' + cmDataItem[fieldToUpdate],
})
cmRecord.setCurrentSublistValue({
sublistId: sublistId,
fieldId: fieldToUpdate,
value: cmDataItem[fieldToUpdate],
ignoreRecalc: false,
})
})
// removeItemInventoryDetail(cmRecord, line, sublistId)
}
clearLocation(cmRecord) {
cmRecord.setValue({
fieldId: 'location',
value: '',
})
}
updateItemLine(cmRecord, cmDataItem, sublistId, line) {
// TODO: verify all fields are brought over
log.debug({ title: 'cm service updateItemLine', details: cmDataItem })
var fieldsToUpdate = [
'quantity',
'rate',
'custcol_tcm_line_taxprice',
'amount',
'taxamt',
'grossamt',
]
cmDataItem.quantity = 0
fieldsToUpdate.forEach((fieldId) => {
var fieldToUpdate = fieldId === 'taxamt' ? 'tax1amt' : fieldId
log.debug({
title: 'cm service updateItemLine fieldId: value',
details:
${fieldToUpdate} : ${cmDataItem[fieldToUpdate]}
,
})
cmRecord.setSublistValue({
sublistId: sublistId,
fieldId: fieldToUpdate,
line: line,
value: cmDataItem[fieldToUpdate],
})
})
}
removeLine(cmRecord, sublistId, line) {
cmRecord.removeLine({
sublistId: sublistId,
line: line,
ignoreRecalc: true,
})
}
/**
* Set apply amount on credit memo that applies to invoice that cm is created from
* @param cmRecord
* @param invoiceId
* @param applyAmt
*/
processApplyLines(cmRecord, invoiceId, applyAmt) {
var sublistId = 'apply'
var applyLineCount = cmRecord.getLineCount({ sublistId: sublistId })
for (var line = 0; line < applyLineCount; line++) {
cmRecord.selectLine({
sublistId: sublistId,
line: line,
})
let invId = cmRecord.getCurrentSublistValue({
sublistId: sublistId,
fieldId: 'internalid',
// line: line,
})
if (parseInt(invId) === parseInt(invoiceId)) {
cmRecord.setCurrentSublistValue({
sublistId: sublistId,
fieldId: 'apply',
// line: line,
value: false,
})
cmRecord.setCurrentSublistValue({
sublistId: sublistId,
fieldId: 'amount',
// line: line,
value: 10,
})
break
}
}
}
setBodyFieldValue(cmRecord, cmData) {
cmRecord.setValue({
fieldId: 'custbody_gw_contrac_cm_type',
value: cmData.typeId,
})
}
}
return CreditMemoService
})