Commit 5fa396de authored by Sandy's avatar Sandy

修改金额计算精度问题

parent b832e80a
This diff is collapsed.
//
// CalculateHelper.m
// XFFruit
//
// Created by Z on 16/7/14.
// Copyright © 2016年 Xummer. All rights reserved.
//
#import "CalculateHelper.h"
@implementation CalculateHelper
+ (NSDecimalNumber *)calculateNum1:(id)num1 num2:(id)num2 type:(CalculateType)type roundingType:(NSRoundingMode)roundingType cutLenth:(NSInteger)coutLenth {
NSDecimalNumberHandler *roundUp = [NSDecimalNumberHandler
decimalNumberHandlerWithRoundingMode:roundingType
scale:coutLenth
raiseOnExactness:NO
raiseOnOverflow:NO
raiseOnUnderflow:NO
raiseOnDivideByZero:YES];
NSDecimalNumber *decimalNum1 = [self changeType:num1];
NSDecimalNumber *decimalNum2 = [self changeType:num2];
NSDecimalNumber *decimalResult;
NSString *result;
switch (type) {
case CalculateTypeAdd: {
decimalResult = [decimalNum1 decimalNumberByAdding:decimalNum2 withBehavior:roundUp];
result = [decimalResult stringValue];
break;
}
case CalculateTypeSub: {
decimalResult = [decimalNum1 decimalNumberBySubtracting:decimalNum2 withBehavior:roundUp];
result = [decimalResult stringValue];
break;
}
case CalculateTypeMul: {
decimalResult = [decimalNum1 decimalNumberByMultiplyingBy:decimalNum2 withBehavior:roundUp];
result = [decimalResult stringValue];
break;
}
case CalculateTypeDiv: {
decimalResult = [decimalNum1 decimalNumberByDividingBy:decimalNum2 withBehavior:roundUp];
result = [decimalResult stringValue];
break;
}
}
return decimalResult;
}
+ (NSDecimalNumber *)changeType:(id)num1 {
NSDecimalNumber *decimalNum1;
if ([num1 isKindOfClass:[NSDecimalNumber class]]) {
decimalNum1 = num1;
}else if([num1 isKindOfClass:[NSString class]]){
decimalNum1 = [NSDecimalNumber decimalNumberWithString:num1];
}else if ([num1 isKindOfClass:[NSNumber class]]){
decimalNum1 = [NSDecimalNumber decimalNumberWithDecimal:[num1 decimalValue]];
}else if(num1 == nil){
decimalNum1 = [NSDecimalNumber decimalNumberWithString:@"0"];
}
return decimalNum1;
}
+ (NSString *)getMoneyStringFrom:(id)num Lenth:(NSInteger)cutLenth {
NSDecimalNumberHandler *roundUp = [NSDecimalNumberHandler
decimalNumberHandlerWithRoundingMode:NSRoundBankers
scale:cutLenth ? cutLenth : 2
raiseOnExactness:NO
raiseOnOverflow:NO
raiseOnUnderflow:NO
raiseOnDivideByZero:YES];
NSDecimalNumber *decimal = [self changeType:num];
NSDecimalNumber *result = [decimal decimalNumberByAdding:[NSDecimalNumber decimalNumberWithString:@"0"] withBehavior:roundUp];
return [result stringValue];
}
+ (NSString *)getMoneyStringFrom:(id)num{
NSString *originString = [self getMoneyStringFrom:num Lenth:2];
NSArray *array = [originString componentsSeparatedByString:@"."];
NSString *top = array[0];
NSString *result;
if (array.count == 1) {
result = [NSString stringWithFormat:@"%@.00",top];
}else if(array.count == 2){
NSString *bottom = array[1];
if (bottom.length == 2) {
result = originString;
}
NSString *chr;
for (NSInteger i = bottom.length; i < 2; i++) {
chr =[bottom substringWithRange:NSMakeRange(i, 1)];
if ([chr isEqualToString:@"0"]) {
result = [top stringByAppendingString:chr];
}
}
}
return result;
}
@end
......@@ -17,8 +17,11 @@ typedef NS_ENUM(NSInteger, CalculateType) {
/*
NSRoundPlain, // Round up on a tie //貌似取整
NSRoundDown, // Always down == truncate //只舍不入
NSRoundUp, // Always up // 只入不舍
NSRoundBankers // on a tie round so last digit is even 貌似四舍五入
*/
/**
......@@ -33,7 +36,41 @@ typedef NS_ENUM(NSInteger, CalculateType) {
* @return 结算结果
*/
+ (NSDecimalNumber *)calculateNum1:(id)num1 num2:(id)num2 type:(CalculateType)type roundingType:(NSRoundingMode)roundingType cutLenth:(NSInteger)coutLenth;
+ (NSString *)getMoneyStringFrom:(id)num Lenth:(NSInteger)cutLenth;
+ (NSDecimalNumber *)calculateNum1:(id)num1 num2:(id)num2 type:(CalculateType)type;
/** add */
+ (NSDecimalNumber *)add:(id)num1 num2:(id)num2;
/** sub */
+ (NSDecimalNumber *)sub:(id)num1 num2:(id)num2;
/** mul */
+ (NSDecimalNumber *)mul:(id)num1 num2:(id)num2;
/** div */
+ (NSDecimalNumber *)div:(id)num1 num2:(id)num2;
/** 一百倍 */
+ (NSDecimalNumber *)oneHundredTimes:(id)num;
/** 计算百分比 */
+ (NSString *)getPercent:(id)num1 num:(id)num2;
/** 获取金额 保留两位小数*/
+ (NSString *)getMoneyStringFrom:(id)num;
+ (NSDecimalNumber *)changeType:(id)num1;
/** 获取金额 */
+ (NSString *)getMoneyStringFrom:(id)num Lenth:(NSInteger)cutLenth isSeparate:(BOOL)isSeparate;
+ (NSString *)getMoneyStringFromString:(NSString *)originString;
//获得绝对值
+ (NSString *)getABSValue:(NSString *)string;
/** 每3位加逗号 */
+ (NSString *)separateMoney:(id)num;
/** 把非decimalNumber转化 */
+ (NSDecimalNumber *)decimalNumber:(id)number;
/**
* 判断数字是否在给定的范围内,num1和num2的顺序不影响判断
*
* @param num 需要判断的数字
* @param num1 范围区间
* @param num2 范围区间
*
* @return 是否在区间内
*/
+ (BOOL)number:(id)num isInNum1:(id)num1 num2:(id)num2;
@end
//
// CalculateHelper.m
// XFFruit
//
// Created by Z on 16/7/14.
// Copyright © 2016年 Xummer. All rights reserved.
//
#import "CalculateHelper.h"
@implementation CalculateHelper
+ (NSDecimalNumber *)calculateNum1:(id)num1 num2:(id)num2 type:(CalculateType)type roundingType:(NSRoundingMode)roundingType cutLenth:(NSInteger)coutLenth {
NSDecimalNumberHandler *roundUp = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:roundingType scale:coutLenth raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:YES];
NSDecimalNumber *decimalNum1 = [self changeType:num1];
NSDecimalNumber *decimalNum2 = [self changeType:num2];
if (decimalNum1 == nil || decimalNum2 == nil) {
return nil;
}
NSDecimalNumber *decimalResult;
NSString *result;
switch (type) {
case CalculateTypeAdd: {
decimalResult = [decimalNum1 decimalNumberByAdding:decimalNum2 withBehavior:roundUp];
result = [decimalResult stringValue];
break;
}
case CalculateTypeSub: {
decimalResult = [decimalNum1 decimalNumberBySubtracting:decimalNum2 withBehavior:roundUp];
result = [decimalResult stringValue];
break;
}
case CalculateTypeMul: {
decimalResult = [decimalNum1 decimalNumberByMultiplyingBy:decimalNum2 withBehavior:roundUp];
result = [decimalResult stringValue];
break;
}
case CalculateTypeDiv: {
if ([decimalNum2 isEqualToNumber:@0]) {
decimalResult = [NSDecimalNumber decimalNumberWithString:@"0"];
} else {
decimalResult = [decimalNum1 decimalNumberByDividingBy:decimalNum2 withBehavior:roundUp];
result = [decimalResult stringValue];
}
break;
}
}
return decimalResult;
}
+ (NSDecimalNumber *)calculateNum1:(id)num1 num2:(id)num2 type:(CalculateType)type {
NSDecimalNumber *decimalNum1 = [self changeType:num1];
NSDecimalNumber *decimalNum2 = [self changeType:num2];
if (decimalNum1 == nil || decimalNum2 == nil) {
return nil;
}
NSDecimalNumber *decimalResult;
NSString *result;
switch (type) {
case CalculateTypeAdd: {
decimalResult = [decimalNum1 decimalNumberByAdding:decimalNum2];
result = [decimalResult stringValue];
break;
}
case CalculateTypeSub: {
decimalResult = [decimalNum1 decimalNumberBySubtracting:decimalNum2];
result = [decimalResult stringValue];
break;
}
case CalculateTypeMul: {
decimalResult = [decimalNum1 decimalNumberByMultiplyingBy:decimalNum2];
result = [decimalResult stringValue];
break;
}
case CalculateTypeDiv: {
if ([decimalNum2 isEqualToNumber:@0]) {
decimalResult = [NSDecimalNumber decimalNumberWithString:@"0"];
} else {
decimalResult = [decimalNum1 decimalNumberByDividingBy:decimalNum2];
result = [decimalResult stringValue];
}
break;
}
}
return decimalResult;
}
//把传入的类型变成NSDecimalNumber
+ (NSDecimalNumber *)changeType:(id)num1 {
NSDecimalNumber *decimalNum1;
if ([num1 isKindOfClass:[NSDecimalNumber class]]) {
decimalNum1 = num1;
} else if ([num1 isKindOfClass:[NSString class]]) {
if ([num1 isEqualToString:@""]) {
decimalNum1 = [NSDecimalNumber decimalNumberWithString:@"0"];
} else {
decimalNum1 = [NSDecimalNumber decimalNumberWithString:num1];
}
} else if ([num1 isKindOfClass:[NSNumber class]]) {
decimalNum1 = [NSDecimalNumber decimalNumberWithDecimal:[num1 decimalValue]];
} else if (num1 == nil) {
decimalNum1 = [NSDecimalNumber decimalNumberWithString:@"0"];
} else {
decimalNum1 = [NSDecimalNumber decimalNumberWithString:@"0"];
}
return decimalNum1;
}
+ (NSDecimalNumber *)decimalNumber:(id)number {
return [self changeType:number];
}
+ (NSDecimalNumber *)oneHundredTimes:(id)num {
return [self calculateNum1:num num2:@100 type:CalculateTypeMul roundingType:NSRoundPlain cutLenth:10];
}
+ (NSString *)getPercent:(id)num1 num:(id)num2 {
[self calculateNum1:num1 num2:num1 type:CalculateTypeDiv roundingType:NSRoundPlain cutLenth:4];
NSDecimalNumber *result = [self oneHundredTimes:[self calculateNum1:num1 num2:num2 type:CalculateTypeDiv roundingType:NSRoundPlain cutLenth:4]];
return [NSString stringWithFormat:@"%@%%", [self getMoneyStringFromString:result.stringValue]];
}
+ (NSString *)getMoneyStringFrom:(id)num Lenth:(NSInteger)cutLenth isSeparate:(BOOL)isSeparate {
NSDecimalNumberHandler *roundUp = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain
scale:cutLenth
raiseOnExactness:NO
raiseOnOverflow:NO
raiseOnUnderflow:NO
raiseOnDivideByZero:YES];
NSDecimalNumber *decimal = [self changeType:num];
NSDecimalNumber *result = [decimal decimalNumberByAdding:[NSDecimalNumber decimalNumberWithString:@"0"] withBehavior:roundUp];
NSString *rs = nil;
if (isSeparate) {
rs = [self separateMoney:result];
} else {
rs = [result stringValue];
}
NSArray *array = [rs componentsSeparatedByString:@"."];
NSString *top = [array[0] stringByAppendingString:@"."];
NSString *finalResult = array[0];
if (array.count == 1) {
if (cutLenth > 0) {
finalResult = top;
for (NSInteger i = 0; i < cutLenth; i++) {
finalResult = [finalResult stringByAppendingString:@"0"];
}
}
} else {
finalResult = rs;
NSString *bottom = array[1];
for (NSInteger i = bottom.length; i < cutLenth; i++) {
finalResult = [finalResult stringByAppendingString:@"0"];
}
}
return finalResult;
}
+ (NSString *)getMoneyStringFrom:(id)num {
NSString *originString = [self getMoneyStringFrom:num Lenth:2 isSeparate:NO];
return [self getMoneyStringFromString:originString];
}
+ (NSString *)getMoneyStringFromString:(NSString *)originString {
NSArray *array = [originString componentsSeparatedByString:@"."];
NSString *top = [array[0] stringByAppendingString:@"."];
NSString *result;
if (array.count == 1) {
result = [NSString stringWithFormat:@"%@00", top];
} else if (array.count == 2) {
NSString *bottom = array[1];
if (bottom.length == 2) {
result = originString;
}
for (NSInteger i = bottom.length; i < 2; i++) {
result = [originString stringByAppendingString:@"0"];
}
}
return result;
}
+ (NSString *)getABSValue:(NSString *)string {
if ([string hasPrefix:@"-"] && ![string hasPrefix:@"--"]) {
NSString *absString = [string substringWithRange:NSMakeRange(1, string.length - 1)];
return absString;
} else {
return string;
}
}
+ (NSString *)separateMoney:(id)num1 {
NSDecimalNumber *num = [self changeType:num1];
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
numberFormatter.locale = [NSLocale currentLocale]; // this ensure the right separator behavior
numberFormatter.numberStyle = NSNumberFormatterDecimalStyle;
numberFormatter.usesGroupingSeparator = YES;
// example for writing the number object into a label
NSString *string = [numberFormatter stringFromNumber:num];
return string;
}
/** add */
+ (NSDecimalNumber *)add:(id)num1 num2:(id)num2 {
return [self calculateNum1:num1 num2:num2 type:CalculateTypeAdd];
}
/** sub */
+ (NSDecimalNumber *)sub:(id)num1 num2:(id)num2 {
return [self calculateNum1:num1 num2:num2 type:CalculateTypeSub];
}
/** mul */
+ (NSDecimalNumber *)mul:(id)num1 num2:(id)num2 {
return [self calculateNum1:num1 num2:num2 type:CalculateTypeMul];
}
/** div */
+ (NSDecimalNumber *)div:(id)num1 num2:(id)num2 {
return [self calculateNum1:num1 num2:num2 type:CalculateTypeDiv];
}
+ (BOOL)number:(id)num isInNum1:(id)num1 num2:(id)num2 {
NSDecimalNumber *decNum = [self decimalNumber:num];
NSDecimalNumber *minNumber;
NSDecimalNumber *maxNumber;
NSDecimalNumber *decNumber1 = [self decimalNumber:num1];
NSDecimalNumber *decNumber2 = [self decimalNumber:num2];
NSComparisonResult result = [decNumber1 compare:decNumber2];
if (result == NSOrderedAscending) {
minNumber = decNumber1;
maxNumber = decNumber2;
} else {
minNumber = decNumber2;
maxNumber = decNumber1;
}
if (([decNum compare:minNumber] == NSOrderedDescending && [decNum compare:maxNumber] == NSOrderedAscending) || [decNum compare:minNumber] == NSOrderedSame || [decNum compare:maxNumber] == NSOrderedSame) {
return YES;
} else {
return NO;
}
}
@end
......@@ -488,11 +488,11 @@ typedef enum : NSUInteger {
shopDetail.product_uuid = billProduct.product_uuid;
shopDetail.product_code = billProduct.product_code;
shopDetail.merchandise = billProduct.product_name;
shopDetail.packageSpecification = [CalculateHelper getMoneyStringFrom:billProduct.qpc Lenth:0];
shopDetail.packageSpecification = [CalculateHelper getMoneyStringFrom:billProduct.qpc Lenth:0 isSeparate:NO];
shopDetail.packageUnit = billProduct.unit;
shopDetail.packageQuantity = [CalculateHelper getMoneyStringFrom:billProduct.qty Lenth:0];
shopDetail.packageQuantity = [CalculateHelper getMoneyStringFrom:billProduct.qty Lenth:0 isSeparate:NO];
shopDetail.packageUnitPrice = billProduct.price;
shopDetail.foundationQuantity= [CalculateHelper getMoneyStringFrom:billProduct.baseQty Lenth:0];
shopDetail.foundationQuantity= [CalculateHelper getMoneyStringFrom:billProduct.baseQty Lenth:0 isSeparate:NO];
shopDetail.foundationUnitPrice= billProduct.basePrice;
shopDetail.totalMoney= billProduct.total;
shopDetail.remark = billProduct.remark;
......
......@@ -251,7 +251,7 @@ typedef enum : NSUInteger {
[model setValuesForKeysWithDictionary:dict];
if ([self.shopDetail.product_code isEqualToString:model.productCode]) {
if ([[CalculateHelper changeType:self.shopDetail.foundationQuantity] compare:decimalNumberWithDouble(model.qty)] == NSOrderedDescending) {
if ([[CalculateHelper decimalNumber:self.shopDetail.foundationQuantity] compare:decimalNumberWithDouble(model.qty)] == NSOrderedDescending) {
CLog(@"库存不足");
NSString *msg = [NSString stringWithFormat:@"采购单<%@>在总部系统的库存不足!", billNumber];
ShowMessage(msg);
......@@ -661,19 +661,19 @@ typedef enum : NSUInteger {
}
}else if(textField == foundationUnitPrice){
//基础单价
self.basePrice = [NSNumber numberWithFloat:foundationUnitPrice.text.floatValue];
self.basePrice = [CalculateHelper decimalNumber:foundationUnitPrice.text];
[self setPacktAndTotalPrice];
//如果基础数量和包装数量有的话计算出包装单价和和总价
}else if (textField == packageUnitPrice){
//包装单价
self.packPrice = [NSNumber numberWithFloat:packageUnitPrice.text.floatValue];
self.packPrice = [CalculateHelper decimalNumber:packageUnitPrice.text];
[self setUnitAndTotalPrice];
}else if(textField == totalMoney){
//总金额
self.totalPrice = [NSNumber numberWithFloat:totalMoney.text.floatValue];
self.totalPrice = [CalculateHelper decimalNumber:totalMoney.text];
[self setUnitAndPackPrice];
}else if (textField == _checkPriceTextField){
self.checkPrice = [CalculateHelper changeType:_checkPriceTextField.text];
self.checkPrice = [CalculateHelper decimalNumber:_checkPriceTextField.text];
self.checkTotal = [CalculateHelper calculateNum1:_checkPriceTextField.text num2:foundationQuantity.text type:CalculateTypeMul roundingType:NSRoundBankers cutLenth:2];
_checkTotalTextField.text = self.checkTotal.stringValue;
......
......@@ -302,37 +302,37 @@
if (textField == _shPackField) {
if (_shPackField.text.length > 0) {
//基础数量【实收】= 包装数量【实收】* 规格
// NSDecimalNumber *baseCount = [
float baseCount = [_shPackField.text floatValue] * [self.noticeProduct.qpc floatValue];
_shBaseQuantityField.text = [NSString stringWithFormat:@"%.2f",baseCount];
NSDecimalNumber *baseCount = [CalculateHelper mul:_shPackField.text num2:self.noticeProduct.qpc];
_shBaseQuantityField.text = [NSString stringWithFormat:@"%.2f",baseCount.doubleValue];
//总金额【实收】= 基础数量【实收】* 基础单价
float total = 0;
NSDecimalNumber *total = [CalculateHelper decimalNumber:@0];
if ([_shPackField.text floatValue] == [self.noticeProduct.qty floatValue]) {
total = [self.noticeProduct.total floatValue];
total = [CalculateHelper decimalNumber:self.noticeProduct.total];
}else{
total = baseCount * [self.noticeProduct.price floatValue];
total = [CalculateHelper mul:baseCount num2:self.noticeProduct.price];
}
_chooseTotalPriceLabel.text = [NSString stringWithFormat:@"%.2f元",total];
_chooseTotalPriceLabel.text = [NSString stringWithFormat:@"%.2f元",total.doubleValue];
self.noticeProduct.rctTotal = [NSNumber numberWithFloat:total];
self.noticeProduct.rctTotal = total;
}
}else if (textField == _shBaseQuantityField) {
if (_shBaseQuantityField.text.length > 0) {
// 包装数量【实收】= 基础数量【实收】/ 规格
float baseCount = 0;
// float baseCount = 0;
NSDecimalNumber *baseCount = [NSDecimalNumber decimalNumberWithString:@0];
if ([self.noticeProduct.qpc floatValue] > 0) {
baseCount = [_shBaseQuantityField.text floatValue]/ [self.noticeProduct.qpc floatValue];
baseCount = [CalculateHelper div:_shBaseQuantityField.text num2:self.noticeProduct.qpc];
}
_shPackField.text = [NSString stringWithFormat:@"%.2f",baseCount];
float total = 0;
_shPackField.text = [NSString stringWithFormat:@"%.2f",baseCount.doubleValue];
NSDecimalNumber *total = [CalculateHelper decimalNumber:@0];
// float total = 0;
if ([_shPackField.text floatValue] == [self.noticeProduct.qty floatValue]) {
total = [self.noticeProduct.total floatValue];
total = [CalculateHelper decimalNumber:self.noticeProduct.total];
}else{
total = baseCount * [self.noticeProduct.price floatValue];
total = [CalculateHelper mul:baseCount num2:self.noticeProduct.price];
}
_chooseTotalPriceLabel.text = [NSString stringWithFormat:@"%.2f元",total];
self.noticeProduct.rctTotal = [NSNumber numberWithFloat:total];
_chooseTotalPriceLabel.text = [NSString stringWithFormat:@"%.2f元",total.doubleValue];
self.noticeProduct.rctTotal = total;
}
}
}
......
......@@ -513,13 +513,13 @@ typedef enum : NSUInteger {
billProduct.productUuid = shopDetail.product_uuid;
billProduct.productCode = shopDetail.product_code;
billProduct.productName = shopDetail.merchandise;
billProduct.qpc = [NSNumber numberWithFloat:[shopDetail.packageSpecification floatValue]];
billProduct.qpc = [CalculateHelper decimalNumber:shopDetail.packageSpecification];
billProduct.unit = shopDetail.packageUnit;
billProduct.qty = [NSNumber numberWithFloat:[shopDetail.packageQuantity floatValue]];
billProduct.packprice = [NSNumber numberWithFloat:[shopDetail.packageUnitPrice floatValue]];
billProduct.price = [NSNumber numberWithFloat:[shopDetail.foundationUnitPrice floatValue]];
billProduct.baseQty = [NSNumber numberWithFloat:[shopDetail.foundationQuantity floatValue]];
billProduct.total = [NSNumber numberWithFloat:[shopDetail.totalMoney floatValue]];
billProduct.qty = [CalculateHelper decimalNumber:shopDetail.packageQuantity];
billProduct.packprice = [CalculateHelper decimalNumber:shopDetail.packageUnitPrice];
billProduct.price = [CalculateHelper decimalNumber:shopDetail.foundationUnitPrice];
billProduct.baseQty = [CalculateHelper decimalNumber:shopDetail.foundationQuantity];
billProduct.total = [CalculateHelper decimalNumber:shopDetail.totalMoney];
billProduct.note = shopDetail.remark;
billProduct.qpcStr = shopDetail.packageQpcStr ? shopDetail.packageQpcStr : @"无" ;
billProduct.baseUnit = shopDetail.packageQpcUnit;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment