diff --git a/src/main/java/ru/evotor/framework/core/action/datamapper/PositionMapper.java b/src/main/java/ru/evotor/framework/core/action/datamapper/PositionMapper.java index 2c69c7252..8a1b6e383 100644 --- a/src/main/java/ru/evotor/framework/core/action/datamapper/PositionMapper.java +++ b/src/main/java/ru/evotor/framework/core/action/datamapper/PositionMapper.java @@ -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 { @@ -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) { @@ -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 @@ -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(); } @@ -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; } diff --git a/src/main/java/ru/evotor/framework/kkt/FiscalTags.kt b/src/main/java/ru/evotor/framework/kkt/FiscalTags.kt index d4d481021..09e43589b 100644 --- a/src/main/java/ru/evotor/framework/kkt/FiscalTags.kt +++ b/src/main/java/ru/evotor/framework/kkt/FiscalTags.kt @@ -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 + } diff --git a/src/main/java/ru/evotor/framework/receipt/Position.java b/src/main/java/ru/evotor/framework/receipt/Position.java index 80f54c332..890107334 100644 --- a/src/main/java/ru/evotor/framework/receipt/Position.java +++ b/src/main/java/ru/evotor/framework/receipt/Position.java @@ -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; /** * Позиция чека. @@ -39,7 +40,7 @@ public class Position implements Parcelable { /** * Текущая версия объекта Position */ - private static final int VERSION = 9; + private static final int VERSION = 10; /** * Магическое число для идентификации использования версионирования объекта. */ @@ -193,6 +194,18 @@ public class Position implements Parcelable { @Nullable private PartialRealization partialRealization; + /** + * Выбытие по объемно-сортовому учету(ОСУ) 1191 + *
+ * Доступно только для следующих типов товара: + * - молочная продукция {@link ProductType#DAIRY_MARKED} + * - вода {@link ProductType#WATER_MARKED} + *
+ */
+ @FiscalRequisite(tag = FiscalTags.VOLUME_SORT_ACCOUNTING_REALIZATION)
+ @Nullable
+ private VolumeSortAccountingRealization volumeSortAccountingRealization;
+
public Position(
String uuid,
@Nullable String productUuid,
@@ -261,6 +274,7 @@ public Position(Position position) {
this.classificationCode = position.getClassificationCode();
this.preferentialMedicine = position.getPreferentialMedicine();
this.partialRealization = position.getPartialRealization();
+ this.volumeSortAccountingRealization = position.getVolumeSortAccountingRealization();
}
/**
@@ -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);
@@ -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);
}
@@ -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;
}
@@ -663,6 +689,7 @@ public String toString() {
", classificationCode=" + classificationCode +
", preferentialMedicine=" + preferentialMedicine +
", partial=" + partialRealization +
+ ", volumeSortAccountingRealization=" + volumeSortAccountingRealization +
'}';
}
@@ -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) {
@@ -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,
@@ -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
+ * вода {@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);
}
diff --git a/src/main/java/ru/evotor/framework/receipt/PositionTable.kt b/src/main/java/ru/evotor/framework/receipt/PositionTable.kt
index 1dc41f6a3..8e73fc1b9 100644
--- a/src/main/java/ru/evotor/framework/receipt/PositionTable.kt
+++ b/src/main/java/ru/evotor/framework/receipt/PositionTable.kt
@@ -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"
diff --git a/src/main/java/ru/evotor/framework/receipt/ReceiptApi.kt b/src/main/java/ru/evotor/framework/receipt/ReceiptApi.kt
index 10b8b1fd4..0855e80cb 100644
--- a/src/main/java/ru/evotor/framework/receipt/ReceiptApi.kt
+++ b/src/main/java/ru/evotor/framework/receipt/ReceiptApi.kt
@@ -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 {
@@ -450,6 +445,7 @@ object ReceiptApi {
.setImportationData(importationData)
.setExcise(excise)
.setPartialRealization(PositionPartialRealizationMapper.fromCursor(cursor))
+ .setVolumeSortAccountingRealization(VolumeSortAccountingRealizationMapper.fromCursor(cursor))
return builder.build()
}
diff --git a/src/main/java/ru/evotor/framework/receipt/position/VolumeSortAccountingRealization.kt b/src/main/java/ru/evotor/framework/receipt/position/VolumeSortAccountingRealization.kt
new file mode 100644
index 000000000..e1f883ad3
--- /dev/null
+++ b/src/main/java/ru/evotor/framework/receipt/position/VolumeSortAccountingRealization.kt
@@ -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)
+ }
+ }
+}
diff --git a/src/main/java/ru/evotor/framework/receipt/position/mapper/VolumeSortAccountingRealizationMapper.kt b/src/main/java/ru/evotor/framework/receipt/position/mapper/VolumeSortAccountingRealizationMapper.kt
new file mode 100644
index 000000000..13416633e
--- /dev/null
+++ b/src/main/java/ru/evotor/framework/receipt/position/mapper/VolumeSortAccountingRealizationMapper.kt
@@ -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
+ )
+ }
+}