Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import ru.evotor.framework.receipt.position.PartialRealization;
import ru.evotor.framework.receipt.position.PreferentialMedicine;
import ru.evotor.framework.receipt.position.SettlementMethod;
import ru.evotor.framework.receipt.position.VolumeSortAccountingRealization;

public final class PositionMapper {

Expand Down Expand Up @@ -87,6 +88,8 @@ public final class PositionMapper {

private static final String KEY_PARTIAL_REALIZATION = "partialRealization";

private static final String KEY_VOLUME_SORT_ACCOUNTING_REALIZATION = "volumeSortAccountingRealization";

@Nullable
public static Position from(@Nullable Bundle bundle) {
if (bundle == null) {
Expand Down Expand Up @@ -148,6 +151,9 @@ public static Position from(@Nullable Bundle bundle) {

PartialRealization partialRealization = PartialRealization.from(bundle.getBundle(KEY_PARTIAL_REALIZATION));

VolumeSortAccountingRealization volumeSortAccountingRealization =
VolumeSortAccountingRealization.from(bundle.getBundle(KEY_VOLUME_SORT_ACCOUNTING_REALIZATION));

if (quantity == null ||
price == null ||
priceWithDiscountPosition == null
Expand Down Expand Up @@ -188,6 +194,7 @@ public static Position from(@Nullable Bundle bundle) {
builder.setPreferentialMedicine(preferentialMedicine);
builder.setClassificationCode(classificationCode);
builder.setPartialRealization(partialRealization);
builder.setVolumeSortAccountingRealization(volumeSortAccountingRealization);
return builder.build();
}

Expand Down Expand Up @@ -268,6 +275,12 @@ public static Bundle toBundle(@Nullable Position position) {
final PartialRealization partialRealization = position.getPartialRealization();
bundle.putBundle(KEY_PARTIAL_REALIZATION, partialRealization != null ? partialRealization.toBundle() : null);

final VolumeSortAccountingRealization volumeSortAccountingRealization = position.getVolumeSortAccountingRealization();
bundle.putBundle(
KEY_VOLUME_SORT_ACCOUNTING_REALIZATION,
volumeSortAccountingRealization != null ? volumeSortAccountingRealization.toBundle() : null
);

return bundle;
}

Expand Down
10 changes: 10 additions & 0 deletions src/main/java/ru/evotor/framework/kkt/FiscalTags.kt
Original file line number Diff line number Diff line change
Expand Up @@ -192,4 +192,14 @@ object FiscalTags {
*/
const val MEASURE_CODE = 2108

/**
* дополнительный реквизит предмета расчета
*/
const val ADDITIONAL_REQUISITE_OF_SUBJECT_OF_CALCULATION = 1191

/**
* выбытие по ОСУ
*/
const val VOLUME_SORT_ACCOUNTING_REALIZATION = ADDITIONAL_REQUISITE_OF_SUBJECT_OF_CALCULATION

}
67 changes: 66 additions & 1 deletion src/main/java/ru/evotor/framework/receipt/Position.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import ru.evotor.framework.receipt.position.PartialRealization;
import ru.evotor.framework.receipt.position.PreferentialMedicine;
import ru.evotor.framework.receipt.position.SettlementMethod;
import ru.evotor.framework.receipt.position.VolumeSortAccountingRealization;

/**
* Позиция чека.
Expand All @@ -39,7 +40,7 @@ public class Position implements Parcelable {
/**
* Текущая версия объекта Position
*/
private static final int VERSION = 9;
private static final int VERSION = 10;
/**
* Магическое число для идентификации использования версионирования объекта.
*/
Expand Down Expand Up @@ -193,6 +194,18 @@ public class Position implements Parcelable {
@Nullable
private PartialRealization partialRealization;

/**
* Выбытие по объемно-сортовому учету(ОСУ) 1191
* <p>
* Доступно только для следующих типов товара:
* - молочная продукция {@link ProductType#DAIRY_MARKED}
* - вода {@link ProductType#WATER_MARKED}
* <p>
*/
@FiscalRequisite(tag = FiscalTags.VOLUME_SORT_ACCOUNTING_REALIZATION)
@Nullable
private VolumeSortAccountingRealization volumeSortAccountingRealization;

public Position(
String uuid,
@Nullable String productUuid,
Expand Down Expand Up @@ -261,6 +274,7 @@ public Position(Position position) {
this.classificationCode = position.getClassificationCode();
this.preferentialMedicine = position.getPreferentialMedicine();
this.partialRealization = position.getPartialRealization();
this.volumeSortAccountingRealization = position.getVolumeSortAccountingRealization();
}

/**
Expand Down Expand Up @@ -540,6 +554,15 @@ public PartialRealization getPartialRealization() {
return partialRealization;
}

/**
* @return Выбытие по объемно-сортовому учету(ОСУ) 1191
*/
@FiscalRequisite(tag = FiscalTags.VOLUME_SORT_ACCOUNTING_REALIZATION)
@Nullable
public VolumeSortAccountingRealization getVolumeSortAccountingRealization() {
return volumeSortAccountingRealization;
}

@Override
public boolean equals(Object o) {
return equals(o, false);
Expand Down Expand Up @@ -601,6 +624,8 @@ private boolean equals(Object o, boolean exceptQuantity) {
return false;
if (!Objects.equals(partialRealization, position.partialRealization))
return false;
if (!Objects.equals(volumeSortAccountingRealization, position.volumeSortAccountingRealization))
return false;

return Objects.equals(subPositions, position.subPositions);
}
Expand Down Expand Up @@ -632,6 +657,7 @@ public int hashCode() {
result = 31 * result + (classificationCode != null ? classificationCode.hashCode() : 0);
result = 31 * result + (preferentialMedicine != null ? preferentialMedicine.hashCode() : 0);
result = 31 * result + (partialRealization != null ? partialRealization.hashCode() : 0);
result = 31 * result + (volumeSortAccountingRealization != null ? volumeSortAccountingRealization.hashCode() : 0);
return result;
}

Expand Down Expand Up @@ -663,6 +689,7 @@ public String toString() {
", classificationCode=" + classificationCode +
", preferentialMedicine=" + preferentialMedicine +
", partial=" + partialRealization +
", volumeSortAccountingRealization=" + volumeSortAccountingRealization +
'}';
}

Expand Down Expand Up @@ -750,6 +777,8 @@ private void writeAdditionalFields(Parcel dest, int flags) {
// Partial realization
dest.writeBundle(this.partialRealization != null ? this.partialRealization.toBundle() : null);
dest.writeInt(this.measure.getCode());
// Volume Sort Accounting Realization
dest.writeBundle(this.volumeSortAccountingRealization != null ? this.volumeSortAccountingRealization.toBundle() : null);
}

protected Position(Parcel in) {
Expand Down Expand Up @@ -836,6 +865,9 @@ private void readAdditionalFields(Parcel in, String measureName, int measurePrec
if (version >= 9) {
measureCode = in.readInt();
}
if (version >= 10) {
readVolumeSortAccountingRealization(in);
}
this.measure = new Measure(
measureName,
measurePrecision,
Expand Down Expand Up @@ -887,6 +919,12 @@ private void readPartialRealization(Parcel in) {
this.partialRealization = PartialRealization.Companion.from(in.readBundle(PartialRealization.class.getClassLoader()));
}

private void readVolumeSortAccountingRealization(Parcel in) {
this.volumeSortAccountingRealization = VolumeSortAccountingRealization.Companion.from(
in.readBundle(VolumeSortAccountingRealization.class.getClassLoader())
);
}

public static final Creator<Position> CREATOR = new Creator<Position>() {
@Override
public Position createFromParcel(Parcel source) {
Expand Down Expand Up @@ -1416,6 +1454,17 @@ public Builder toPartialRealization(
return this;
}

public Builder toVolumeSortAccountingRealization(
@NonNull BigDecimal volumeSortQuantity,
@NonNull String gtin
) {
position.volumeSortAccountingRealization = new VolumeSortAccountingRealization(
gtin,
volumeSortQuantity
);
return this;
}

private void setAlcoParams(
Mark mark,
BigDecimal alcoholByVolume,
Expand Down Expand Up @@ -1589,6 +1638,22 @@ public Builder setPartialRealization(@Nullable PartialRealization partialRealiza
return this;
}

/**
* Реализация по ОСУ для позиции доступна только если тип товара является одним из:
* <p>
* вода {@link ProductType#WATER_MARKED}
* молочная продукция {@link ProductType#DAIRY_MARKED}
* не может использоваться совместно с setPartialRealization
*
* @param volumeSortAccountingRealization реализация по ОСУ
*/
public Builder setVolumeSortAccountingRealization(
@Nullable VolumeSortAccountingRealization volumeSortAccountingRealization
) {
position.volumeSortAccountingRealization = volumeSortAccountingRealization;
return this;
}

public Position build() {
return new Position(position);
}
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/ru/evotor/framework/receipt/PositionTable.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ object PositionTable {
const val COLUMN_IMPORTATION_DATA_COUNTRY_ORIGIN_CODE = "IMPORTATION_DATA_COUNTRY_ORIGIN_CODE"
const val COLUMN_IMPORTATION_DATA_CUSTOMS_DECLARATION_NUMBER = "IMPORTATION_DATA_CUSTOMS_DECLARATION_NUMBER"
const val COLUMN_PARTIAL_QUANTITY_IN_PACKAGE = "PARTIAL_REALIZATION_QUANTITY_IN_PACKAGE"
const val COLUMN_VOLUME_SORT_ACCOUNTING_QUANTITY = "VOLUME_SORT_ACCOUNTING_QUANTITY"
const val COLUMN_VOLUME_SORT_ACCOUNTING_GTIN = "VOLUME_SORT_ACCOUNTING_GTIN"

object ExtraKeyJSONKeys {
const val KEY_IDENTITY = "identity"
Expand Down
8 changes: 2 additions & 6 deletions src/main/java/ru/evotor/framework/receipt/ReceiptApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,10 @@ import ru.evotor.framework.receipt.mapper.FiscalReceiptMapper
import ru.evotor.framework.receipt.position.ImportationData
import ru.evotor.framework.receipt.position.Mark
import ru.evotor.framework.receipt.position.PreferentialMedicine
import ru.evotor.framework.receipt.position.mapper.AgentRequisitesMapper
import ru.evotor.framework.receipt.position.mapper.PositionPartialRealizationMapper
import ru.evotor.framework.receipt.position.mapper.PreferentialMedicineMapper
import ru.evotor.framework.receipt.position.mapper.SettlementMethodMapper
import ru.evotor.framework.receipt.position.mapper.*
import ru.evotor.framework.receipt.provider.FiscalReceiptContract
import java.math.BigDecimal
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap

@WorkerThread
object ReceiptApi {
Expand Down Expand Up @@ -450,6 +445,7 @@ object ReceiptApi {
.setImportationData(importationData)
.setExcise(excise)
.setPartialRealization(PositionPartialRealizationMapper.fromCursor(cursor))
.setVolumeSortAccountingRealization(VolumeSortAccountingRealizationMapper.fromCursor(cursor))
return builder.build()
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package ru.evotor.framework.receipt.position

import android.os.Bundle
import ru.evotor.IBundlable
import ru.evotor.framework.optBigDecimal
import java.math.BigDecimal


data class VolumeSortAccountingRealization (
/**
* Идентификатор продукта GTIN
*/
val gtin: String,
/**
* Количество товара по ОСУ
*/
val volumeSortQuantity: BigDecimal
) : IBundlable {

override fun toBundle() = Bundle().apply {
putString(KEY_VOLUME_SORT_QUANTITY, volumeSortQuantity.toPlainString())
putString(KEY_GTIN, gtin)
}

companion object {

private const val KEY_VOLUME_SORT_QUANTITY = "VolumeSortQuantity"
private const val KEY_GTIN = "GTIN"

@JvmStatic
fun from(bundle: Bundle?): VolumeSortAccountingRealization? = bundle?.let {
val volumeSortQuantity = it.optBigDecimal(KEY_VOLUME_SORT_QUANTITY) ?: return null
val gtin = it.getString(KEY_GTIN) ?: return null

VolumeSortAccountingRealization(volumeSortQuantity = volumeSortQuantity, gtin = gtin)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package ru.evotor.framework.receipt.position.mapper

import android.database.Cursor
import ru.evotor.framework.optQuantity
import ru.evotor.framework.optString
import ru.evotor.framework.receipt.PositionTable
import ru.evotor.framework.receipt.position.VolumeSortAccountingRealization

internal object VolumeSortAccountingRealizationMapper {

internal fun fromCursor(cursor: Cursor): VolumeSortAccountingRealization? {
val volumeSortQuantity = cursor.optQuantity(PositionTable.COLUMN_VOLUME_SORT_ACCOUNTING_QUANTITY)
?: return null
val gtin = cursor.optString(PositionTable.COLUMN_VOLUME_SORT_ACCOUNTING_GTIN)
?: return null
return VolumeSortAccountingRealization(
volumeSortQuantity = volumeSortQuantity,
gtin = gtin
)
}
}