Importação nunca usei, mas coloquei também.
Mistura DBF e MySQL, não sei se vai ser problema.... rs
METHOD ItemCalculaImpostos() CLASS Pedido
LOCAL mipIcmBas, mipIcmAli, mipIcmRed, mipIcmVal
LOCAL mipFcpAli, mipFcpVal
LOCAL mipIpiBas, mipIpiAli, mipIpiVal
LOCAL mipIssBas, mipIssAli, mipIssVal
LOCAL mipPisBas, mipPisAli, mipPisVal
LOCAL mipCofBas, mipCofAli, mipCofVal
LOCAL mipSubBas, mipSubIva, mipSubAli, mipSubRed, mipSubVal
LOCAL mipValNot, mipIIBas, mipIIVal
LOCAL mipIcsBas, mipIcsVal, mipIcsAli, mipIpiIcm
LOCAL mipValPro, mipValFre, mipValSeg, mipValOut, nCont, mipLeis, mTmpLei
LOCAL mipValDes, mipIIAli, mipDifAlii, mipDifAliu, mipDifAlif, mipDifVali, mipDifValf, mipDifBas, mipDifCal
LOCAL cnJPIBPT := ADOClass():New( AppcnMySqlLocal() )
IF Empty( jppedi->pdPedido )
RETURN NIL
ENDIF
Encontra( jppedi->pdCliFor, "jpcadas", "numlan" )
Encontra( jpcadas->cdUfEnt, "jpuf", "numlan" )
Encontra( jpitped->ipItem, "jpitem", "item" )
IF jpitped->ipTribut != "999999"
RecLock()
REPLACE jpitped->ipValPro WITH Round( jpitped->ipPreNot * jpitped->ipQtde, 2 ), ;
jpitped->ipInfAlt WITH LogInfo()
IF Encontra( jppedi->pdTransa + jpuf->ufTriUf + jpcadas->cdTriCad + jpitem->ieTriPro, "jpimpos", "regra" )
mipLeis := ""
FOR nCont = 1 To Len( Trim( jpimpos->imLeis ) ) Step 7
mTmpLei := Substr( jpimpos->imLeis,nCont, 6 )
IF Val( mTmpLei ) != 0
mipLeis := mipLeis + mTmpLei + ","
ENDIF
NEXT
REPLACE ;
jpitped->ipCfOp WITH jpimpos->imCfOp, ;
jpitped->ipTribut WITH jpimpos->imNumLan, ;
jpitped->ipIIAli WITH jpimpos->imIIAli, ;
jpitped->ipIssAli WITH jpimpos->imIssAli, ;
jpitped->ipIpiCst WITH jpimpos->imIpiCst, ;
jpitped->ipIpiAli WITH jpimpos->imIpiAli, ;
jpitped->ipIpiIcm WITH jpimpos->imIpiIcm, ;
jpitped->ipIpiEnq WITH jpimpos->imIpiEnq, ;
jpitped->ipIcmCst WITH jpimpos->imIcmCst, ;
jpitped->ipIcmAli WITH jpimpos->imIcmAli, ;
jpitped->ipIcmRed WITH jpimpos->imIcmRed, ;
jpitped->ipFcpAli WITH jpimpos->imFcpAli, ;
jpitped->ipSubAli WITH jpimpos->imSubAli, ;
jpitped->ipSubIva WITH jpimpos->imSubIva, ;
jpitped->ipSubRed WITH jpimpos->imSubRed, ;
jpitped->ipDifCal WITH jpimpos->imDifCal, ;
jpitped->ipDifAlii WITH jpimpos->imDifAlii, ;
jpitped->ipDifAliu WITH jpimpos->imDifAliu, ;
jpitped->ipDifAlif WITH jpimpos->imDifAlif, ;
jpitped->ipPisCst WITH jpimpos->imPisCst, ;
jpitped->ipPisAli WITH jpimpos->imPisAli, ;
jpitped->ipPisEnq WITH jpimpos->imPisEnq, ;
jpitped->ipCofCst WITH jpimpos->imCofCst, ;
jpitped->ipCofAli WITH jpimpos->imCofAli, ;
jpitped->ipCofEnq WITH jpimpos->imCofEnq, ;
jpitped->ipIcsAli WITH jpimpos->imIcsAli, ;
jpitped->ipLeis WITH mipLeis, ;
jpitped->ipInfAlt WITH LogInfo()
ELSEIF jpitped->ipTribut != "999999"
REPLACE ;
jpitped->ipCfOp WITH "X", ;
jpitped->ipTribut WITH "", ;
jpitped->ipIIAli WITH 0, ;
jpitped->ipIssAli WITH 0, ;
jpitped->ipIpiCst WITH "X", ;
jpitped->ipIpiAli WITH 0, ;
jpitped->ipIpiIcm WITH "S", ;
jpitped->ipIcmCst WITH "X", ;
jpitped->ipIcmAli WITH 0, ;
jpitped->ipIcmRed WITH 0, ;
jpitped->ipFcpAli WITH 0, ;
jpitped->ipSubAli WITH 0, ;
jpitped->ipSubIva WITH 0, ;
jpitped->ipSubRed WITH 0, ;
jpitped->ipDifCal WITH "N", ;
jpitped->ipDifAlii WITH 0, ;
jpitped->ipDifAliu WITH 0, ;
jpitped->ipDifAlif WITH 0, ;
jpitped->ipPisCst WITH "X", ;
jpitped->ipPisAli WITH 0, ;
jpitped->ipCofCst WITH "x", ;
jpitped->ipCofAli WITH 0, ;
jpitped->ipIcsAli WITH 0, ;
jpitped->ipImpAli WITH 0, ;
jpitped->ipLeis WITH "", ;
jpitped->ipInfAlt WITH LogInfo()
ENDIF
RecUnlock()
ENDIF
IF AppcnMySqlLocal() == NIL
IF Encontra( jpitem->ieNcm, "jpibpt", "numlan" )
RecLock()
IF Substr( jpitped->ipIcmCst, 1, 1 ) $ "0,3,4,5"
REPLACE jpitped->ipImpAli WITH jpibpt->ibNacAli
ELSE
REPLACE jpitped->ipImpAli WITH jpibpt->ibImpAli
ENDIF
RecUnlock()
ENDIF
ELSE
WITH OBJECT cnJPIBPT
:cSql := "SELECT * FROM JPIBPT WHERE IBCODIGO=" + StringSql( jpitem->ieNcm )
:Execute()
RecLock()
IF :Eof()
REPLACE jpitped->ipImpAli WITH 0
ELSE
IF Substr( jpitped->ipIcmCst, 1, 1 ) $ "0,3,4,5"
REPLACE jpitped->ipImpAli WITH :NumberSql( "IBNACALI" )
ELSE
REPLACE jpitped->ipImpAli WITH :NumberSql( "IBIMPALI" )
ENDIF
ENDIF
RecUnlock()
:CloseRecordset()
END WITH
ENDIF
mipValPro := jpitped->ipValPro
mipValFre := jpitped->ipValFre
mipValSeg := jpitped->ipValSeg
mipValOut := jpitped->ipValOut
mipValDes := jpitped->ipValDes
mipIIAli := jpitped->ipIIAli
mipIssAli := jpitped->ipIssAli
mipIpiAli := jpitped->ipIpiAli
mipIpiIcm := jpitped->ipIpiIcm
mipIcmBas := jpitped->ipIcmBas
mipIcmRed := jpitped->ipIcmRed
mipSubIva := jpitped->ipSubIva
mipIcmAli := jpitped->ipIcmAli
mipFcpAli := jpitped->ipFcpAli
mipSubBas := jpitped->ipSubBas
mipSubRed := jpitped->ipSubRed
mipSubAli := jpitped->ipSubAli
mipIcsAli := jpitped->ipIcsAli
mipPisAli := jpitped->ipPisAli
mipCofAli := jpitped->ipCofAli
mipDifCal := jpitped->ipDifCal
mipDifAlii := jpitped->ipDifAlii
mipDifALiu := jpitped->ipDifAliu
mipDifAlif := jpitped->ipDifAlif
IF mipIIAli > 0
mipIIBas := mipValPro
mipIIVal := Int(mipIIBas * mipIIAli ) / 100
ELSE
mipIIBas := 0
mipIIVal := 0
ENDIF
IF mipIssAli > 0
mipIssBas := mipValPro + mipIIVal
mipIssVal := Int( mipIssBas * mipIssAli ) / 100
ELSE
mipIssBas := 0
mipIssAli := 0
mipIssVal := 0
ENDIF
IF mipIpiAli > 0
mipIpiBas := mipValPro + mipIIVal
mipIpiVal := Int( mipIpiBas * mipIpiAli) / 100
ELSE
mipIpiBas := 0
mipIpiAli := 0
mipIpiVal := 0
ENDIF
IF mipIcmAli > 0 .AND. Substr( jpitped->ipIcmCst, 2, 3 ) $ "00 ,10 ,20 ,70 ,90 ,201,202,203,900"
mipIcmBas := mipValPro + mipValFre + mipValSeg + mipValOut + mipIIVal
IF mipIpiIcm != "N"
mipIcmBas += mipIpiVal
ENDIF
IF mipIcmRed > 0 .AND. Substr( jpitped->ipIcmCst, 2, 2 ) $ "20 ,70 ,90 ,201,202,203.900"
mipIcmBas := mipIcmBas - ( Int( mipIcmBas * mipIcmRed ) / 100 )
ELSE
mipIcmRed := 0
ENDIF
mipIcmVal := Int( mipIcmBas * mipIcmAli ) / 100
ELSE
mipIcmBas := 0
mipIcmAli := 0
mipIcmVal := 0
ENDIF
IF mipFcpAli > 0
mipFcpVal := Int( mipIcmBas * mipFcpAli ) / 100
ELSE
mipFcpVal := 0
ENDIF
IF mipSubAli > 0 .AND. Substr( jpitped->ipIcmCst, 2, 2 ) $ "10 ,30 ,70 ,90 ,900"
mipSubBas := mipValPro + mipValFre + mipValSeg + mipValOut + mipIIVal
IF mipIpiIcm != "N"
mipSubBas += mipIpiVal
ENDIF
mipSubBas := mipSubBas + ( Int( mipSubBas * mipSubIva ) / 100)
IF mipSubRed > 0 .AND. Substr( jpitped->ipIcmCst, 2, 3 ) $ "20 ,70 ,90 ,900"
mipSubBas := mipSubBas - ( Int( mipSubBas * mipSubRed ) / 100)
ELSE
mipSubRed := 0
ENDIF
mipSubVal := Int( mipSubBas * mipSubAli ) / 100
mipSubVal := mipSubVal - mipIcmVal
IF mipSubVal < 0
mipSubVal := 0
ENDIF
ELSE
mipSubBas := 0
mipSubIva := 0
mipSubAli := 0
mipSubRed := 0
mipSubVal := 0
ENDIF
IF mipDifCal == "S"
mipDifBas := mipValPro + mipValFre + mipValSeg + mipValOut + mipIIVal
IF mipIpiIcm != "N"
mipDifBas += mipIpiVal
ENDIF
mipDifVali := Max( Int( ( mipDifBas * mipDifAliu ) - ( mipDifBas * mipDifAlii ) ) / 100, 0 )
mipDifValf := Int( mipDifBas * mipDifAlif ) / 100
ELSE
mipDifBas := 0
mipDifVali := 0
mipDifValf := 0
ENDIF
// Aqui sem ST
mipValNot := mipValPro + mipIIVal + mipIpiVal + mipValFre + mipValSeg + mipValOut
IF mipPisAli > 0
mipPisBas := mipValNot
mipPisVal := Int( mipPisBas * mipPisAli ) / 100
ELSE
mipPisBas := 0
mipPisVal := 0
ENDIF
IF mipCofAli > 0
mipCofBas := mipValNot
mipCofVal := Int( mipCofBas * mipCofAli ) / 100
ELSE
mipCofBas := 0
mipCofVal := 0
ENDIF
IF mipIcsAli > 0
mipIcsBas := mipValNot
mipIcsVal := Int(mipIcsBas * mipIcsAli ) / 100
ELSE
mipIcsBas := 0
mipIcsVal := 0
ENDIF
// Soma pra nota ST e desconto
mipValNot := mipValNot - mipValDes + mipSubVal
IF Substr( jpitped->ipCfOp, 1, 1 ) = "3" .AND. Substr( jpitped->ipIcmCst, 1, 1 ) == "1" // Importacao direta
// Formula Pis/Cofins retirada de http://www4.receita.fazenda.gov.br/simulador/Simulacao-tag.jsp
// Demais retiradas de http://www.comexblog.com.br/importacao/calculando-uma-nf-de-entrada-na-importacao
mipPisBas := mipValPro * ( ( 1 + ( mipIcmAli / 100 * ( mipIIAli / 100 + ( mipIpiAli / 100 * ( 1 + mipIIAli / 100 ) ) ) ) ) / ( ( 1 - mipPisAli / 100 - mipCofAli / 100 ) * ( 1 - mipIcmAli / 100 ) ) )
mipPisVal := mipPisBas * mipPisAli / 100
mipCofBas := mipValPro * ( ( 1 + ( mipIcmAli / 100 * ( mipIIAli / 100 + ( mipIpiAli / 100 * ( 1 + mipIIAli / 100 ) ) ) ) ) / ( ( 1 - mipPisAli / 100 - mipCofAli / 100 ) * ( 1 - mipIcmAli / 100 ) ) )
mipCofVal := mipCofBas * mipCofAli / 100
mipIcmBas := mipValPro + mipValFre + mipValSeg + mipValOut + mipIIVal // + mipPisVal + mipCofVal // Pis/Cof calculado sobre ICMS
IF mipIpiIcm != "N"
mipIcmBas += mipIpiVal
ENDIF
mipIcmBas := Int( mipIcmBas / ( 100 - mipIcmAli ) * 10000 ) / 100
mipIcmVal := Int( mipIcmBas * mipIcmAli ) / 100
mipValNot := mipPisBas // equivalente a soma de tudo
ENDIF
IF len( Trim( jpitped->ipIcmCst ) ) > 3 // Simples Nacional
mipIcmAli := 0
mipIcmVal := 0
ENDIF
//IF jpitped->ipCfOp == "1.604 "
// mipValNot := 0
//ENDIF
RecLock()
REPLACE ;
jpitped->ipIIBas WITH mipIIBas, ;
jpitped->ipIIVal WITH mipIIVal, ;
jpitped->ipIssBas WITH mipIssBas, ;
jpitped->ipIssAli WITH mipIssAli, ;
jpitped->ipIssVal WITH mipIssVal, ;
jpitped->ipIpiBas WITH mipIpiBas, ;
jpitped->ipIpiVal WITH mipIpiVal, ;
jpitped->ipIcmBas WITH mipIcmBas, ;
jpitped->ipIcmAli WITH mipIcmAli, ;
jpitped->ipIcmRed WITH mipIcmRed, ;
jpitped->ipIcmVal WITH mipIcmVal, ;
jpitped->ipFcpAli WITH mipFcpAli, ;
jpitped->ipFcpVal WITH mipFcpVal, ;
jpitped->ipSubBas WITH mipSubBas, ;
jpitped->ipSubIva WITH mipSubIVA, ;
jpitped->ipSubAli WITH mipSubAli, ;
jpitped->ipSubRed WITH mipSubRed, ;
jpitped->ipSubVal WITH mipSubVal, ;
jpitped->ipPisBas WITH mipPisBas, ;
jpitped->ipPisAli WITH mipPisAli, ;
jpitped->ipPisVal WITH mipPisVal, ;
jpitped->ipCofBas WITH mipCofBas, ;
jpitped->ipCofAli WITH mipCofAli, ;
jpitped->ipCofVal WITH mipCofVal, ;
jpitped->ipValNot WITH mipValNot, ;
jpitped->ipIcsBas WITH mipIcsBas, ;
jpitped->ipIcsVal WITH mipIcsVal, ;
jpitped->ipDifCal WITH mipDifCal, ;
jpitped->ipDifBas WITH mipDifBas, ;
jpitped->ipDifAlii WITH mipDifAlii, ;
jpitped->ipDifAliu WITH mipDifAliu, ;
jpitped->ipDifAlif WITH mipDifALif, ;
jpitped->ipDIfVali WITH mipDifVAli, ;
jpitped->ipDifValf WITH mipDifValf, ;
jpitped->ipInfAlt WITH LogInfo()
Encontra( jppedi->pdTransa, "jptransa", "numlan" )
IF "CONSUMIDOR" $ jptransa->trReacao
REPLACE jpitped->ipImpVal WITH mipValNot * jpitped->ipImpAli / 100
ELSE
REPLACE jpitped->ipImpVal WITH 0
ENDIF
RecUnlock()
RETURN .T.
Num resumo:
Procuro a regra de tributação pra pegar as alíquotas, CFOP, redução, etc.
Procuro na tabela IPBT, que pode ser DBF ou MySQL, pra procurar os percentuais de tributação.
Pego os valores de itens de pedido, faço os cálculos, e gravo nos ítens de pedido.
Só que:
- Antes desses cálculos faço rateios de frete, descontos, etc.
- Depois desses cálculos tem os totais para pedido/NF
Chamando o conjunto de rotinas, a cada alteração do usuário já tem todos os cálculos prontos, na hora, durante a digitação do pedido.
Na emissão de nota, nenhum cálculo, exceto a parte financeira, conforme a forma de pagamento.
Não é perfeita, nem completa, mas tem atendido minhas necessidades.
Acho que os campos são auto-explicativos: IcmBas, IpiBas, PisBas, IcmVal, IcmAli, SubRed, SubIva, DifVal
As tres primeiras letras são do imposto: ICMs, IPI, PIS, COFins, SUBstituição Tributária, DIFal, etc.
As três últimas letras o que é: BASe, ALIquota, VALor, REDução, IVA
Correção: as duas primeiras letras podem ser referente ao arquivo IP=arquivo itens de pedido, IM=arquivo impostos
Depois disso as três do imposto, e as três do que é.
E se for memória, temporária equivalente ao arquivo, um "m" antes do nome.
mipIcmBas -> M=memória, IP=Itens de Pedido, ICM=Icms, BAS=base -> base de cálculo do ICMS ref. item de pedido, lido ou pra ser gravado lá.